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

# Manifests & Versioning

> Automatic agent version tracking with compatibility scoring — detect what changed and what broke.

DecimalAI automatically tracks changes to your agent's configuration across deployments. When a change is detected, a new **manifest version** is registered and a compatibility analysis shows how existing traces are affected.

## What Is a Manifest?

A manifest is a snapshot of your agent's contract — the tools, model, prompts, subagents, and output schema that define how your agent behaves:

```
Manifest v3
├── Tools: search, calculator, web_browser
├── Model: gpt-4o (temperature: 0.7)
├── Prompts: "You are a helpful research assistant..."
├── Subagents: fact-checker, summarizer
└── Skills: code-review, sql-optimizer
```

Every time your agent runs, the SDK extracts this contract, hashes it, and compares to the previous version. If something changed, a new version is registered automatically.

***

## How Auto-Detection Works

Detection is framework-specific. Each integration extracts the maximum available information:

| Framework                            | Init flag                               | Tools                | Model         | Prompts        | Schema Depth |
| ------------------------------------ | --------------------------------------- | -------------------- | ------------- | -------------- | ------------ |
| LangChain                            | `langchain=True`                        | ✅ Auto + full schema | ✅ Full config | ✅ System/user  | Full         |
| OpenAI Agents (`install(agent=...)`) | `openai_agents=True` + explicit install | ✅ Full JSON schema   | ✅ Name        | ✅ Instructions | Full         |
| OpenAI Agents (auto)                 | `openai_agents=True`                    | Names only           | ✅ Full config | ❌              | Names        |
| LlamaIndex                           | `llamaindex=True`                       | Names only (OTel)    | ✅ Full config | ❌              | Names        |
| CrewAI                               | `crewai=True`                           | Names only (OTel)    | ✅ Full config | ❌              | Names        |
| AutoGen / AG2                        | `autogen=True`                          | Names only (OTel)    | ✅ Full config | ❌              | Names        |
| Generic OTel                         | `otel=True`                             | Names only           | ✅ Full config | ❌              | Names        |
| Generic + `@tool` decorator          | (no flag)                               | ✅ From type hints    | ✅ Full        | ❌              | Full         |
| Explicit `register_manifest()`       | (no flag)                               | ✅ Whatever you pass  | ✅             | ✅              | Full         |

<Tip>
  This is the canonical capability matrix. The [Quickstart](/quickstart) shows code for each framework but doesn't repeat the matrix — come back here if you want to know how deep auto-detection goes for your framework before committing to it.
</Tip>

<Note>
  **Two calling forms — when to use which:**

  * **Flag form** (`decimalai.init(api_key=..., langchain=True)`) auto-installs the integration. **Use this by default** — it's what the [Quickstart](/quickstart) shows.
  * **Explicit `install(...)` form** is for when you need to pass advanced arguments — e.g., an `Agent` object for OpenAI Agents to capture full schemas, or `prompts={...}` to override dynamic prompts in LangChain. Call `decimalai.init(api_key=...)` first, then `install(...)`.

  Don't pass the framework flag *and* call `install()` separately — pick one form per integration.
</Note>

<Tabs>
  <Tab title="LangChain">
    ```python theme={null}
    import decimalai

    # Default — flag form auto-installs the integration
    decimalai.init(api_key="your-api-key", langchain=True)

    # Use LangChain as normal — everything is auto-detected
    ```

    Tools are extracted from callbacks, model config from `on_chat_model_start`, and prompts from system messages.

    <Warning>
      **Gotcha:** Dynamic prompts (RAG chunks, today's date) cause false drift. Drop into the explicit form to override:

      ```python theme={null}
      decimalai.init(api_key="your-api-key")
      from decimalai.langchain import install
      install(prompts={"system": "Your static template"})
      ```
    </Warning>
  </Tab>

  <Tab title="OpenAI Agents">
    ```python theme={null}
    # Default — flag form picks up Agent objects on first run
    import decimalai
    decimalai.init(api_key="your-api-key", openai_agents=True)

    # Run your agent as usual; the SDK introspects it at trace time.
    ```

    For **full JSON-schema capture**, drop into the explicit form and pass the `Agent` object:

    ```python theme={null}
    import decimalai
    from agents import Agent
    from decimalai.openai_agents import install

    decimalai.init(api_key="your-api-key")
    agent = Agent(name="research-agent", instructions="...", model="gpt-4o", tools=[...])
    install(agent=agent)  # Full schema introspection
    ```
  </Tab>

  <Tab title="OTel / CrewAI">
    ```python theme={null}
    # Default — flag form
    import decimalai
    decimalai.init(api_key="your-api-key", otel=True)
    # Or for CrewAI specifically: decimalai.init(api_key="...", crewai=True)
    ```

    OTel spans expose model name, temperature, and tool names, but not full tool schemas.
  </Tab>

  <Tab title="Generic">
    ```python theme={null}
    # Option 1: Explicit registration (highest fidelity)
    decimalai.register_manifest(
        agent_name="my-agent",
        tools=[
            {"name": "search", "schema": {"type": "object", "properties": {"query": {"type": "string"}}}},
        ],
        prompts={"system": "You are a helpful research assistant."},
        models={"default": {"provider": "openai", "model": "gpt-4o", "temperature": 0.7}},
    )

    # Option 2: Auto-deduce from trace calls (zero config)
    @decimalai.trace(agent_name="my-agent")
    def run_agent(query: str):
        decimalai.log_llm_call(model="gpt-4o", ...)
        decimalai.log_tool_call(name="search", ...)
    ```
  </Tab>
</Tabs>

***

## Manifest Hashing

Manifest hashing is deterministic and noise-resistant:

<Accordion title="Hashing implementation details">
  | Rule                      | What it does                                                                                                                                                   | Effect on drift                                                    |
  | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
  | Per-surface hashing       | Tools, prompts, models, subagents, skills, and output schema each get their own hash; the overall hash is the hash of all surface hashes sorted alphabetically | Isolates where drift came from                                     |
  | Temperature quantization  | Small changes (0.70 → 0.71) are quantized to the nearest 0.1                                                                                                   | No drift for tweaks; 0.7 → 0.8 *will* trigger a new manifest       |
  | Runtime settings excluded | `max_retries`, `timeout`, and operational settings are stripped before hashing                                                                                 | These never cause drift                                            |
  | Tool order invariant      | Tools are sorted by name before hashing                                                                                                                        | Reordering doesn't create false drift                              |
  | Hash dedup                | If the same hash already exists, no new version is created                                                                                                     | Deploying the same config to multiple pods won't create duplicates |
</Accordion>

***

## Compatibility Scoring

When a new manifest is detected, DecimalAI classifies every existing trace against the new config:

| Verdict    | Meaning                                            | Example                             |
| ---------- | -------------------------------------------------- | ----------------------------------- |
| **Keep**   | Trace is fully compatible                          | Model temperature changed slightly  |
| **Repair** | Trace can be adapted mechanically                  | Tool schema added an optional field |
| **Replay** | Trace should be re-run with the new agent          | System prompt changed significantly |
| **Drop**   | Trace is incompatible — exclude from training data | Tool was removed entirely           |

The classification considers 10 surfaces, each with its own severity:

| Surface           | Minor (keep)           | Moderate (flag)          | Major (drop)           |
| ----------------- | ---------------------- | ------------------------ | ---------------------- |
| `prompt_stack`    | Whitespace change      | Content changed          | Complete rewrite       |
| `model_runtime`   | Temperature tweak      | Model changed            | Provider changed       |
| `tool_registry`   | Schema field added     | Schema field changed     | Tool removed           |
| `skill_registry`  | Skill added            | Skill content changed    | Skill removed          |
| `workflow`        | Parameter change       | Handoff added            | Step removed           |
| `subagents`       | Sub-agent added        | Sub-agent reconfigured   | Sub-agent removed      |
| `output_contract` | Optional field added   | Field type changed       | Required field removed |
| `guardrails`      | Threshold relaxed      | Rule changed             | Rule removed           |
| `context_config`  | Window grew            | Retrieval source changed | Source removed         |
| `environment`     | Non-semantic var added | Value changed            | Var removed            |

***

## Repair: Fix Traces Mechanically

Traces classified as **repair** can be fixed with a deterministic data migration — no LLM calls, no re-running your agent. The platform rewrites tool call data inside the trace records so they conform to the new manifest.

### What Repair Does

| Rule Type           | What It Fixes                       | Example                                      |
| ------------------- | ----------------------------------- | -------------------------------------------- |
| `tool_rename`       | Rewrites tool name in trace records | `check_inventory(...)` → `lookup_stock(...)` |
| `param_rename`      | Renames parameter in tool call args | `product_id` → `item_id`                     |
| `param_remove`      | Strips deprecated parameter         | Removes `legacy_flag` from args              |
| `param_add_default` | Adds new optional parameter         | Adds `region: null`                          |

After repair, the trace's `manifest_id` is updated to point to the new manifest — it's now "compatible" with v2.

### Repair Flow

<Steps>
  <Step title="Preview">
    See what rules would be applied, with before/after examples:

    ```bash theme={null}
    curl -X POST https://api.decimal.ai/api/v1/repair/preview \
      -H "Authorization: Bearer $API_KEY" \
      -d '{"old_manifest_id": "...", "new_manifest_id": "...", "sample_size": 5}'
    ```

    Response shows each rule with confidence level and sample trace diffs.
  </Step>

  <Step title="Approve">
    Review the rules. You can apply all rules or select specific ones:

    * **Apply All** — repairs every eligible trace with all generated rules
    * **Selective** — pick which rules to apply (e.g., approve the tool rename but skip the param removal)
  </Step>

  <Step title="Apply">
    ```bash theme={null}
    # Apply all rules
    curl -X POST https://api.decimal.ai/api/v1/repair/apply \
      -H "Authorization: Bearer $API_KEY" \
      -d '{"old_manifest_id": "...", "new_manifest_id": "..."}'

    # Or apply selectively
    curl -X POST https://api.decimal.ai/api/v1/repair/apply-selective \
      -H "Authorization: Bearer $API_KEY" \
      -d '{"old_manifest_id": "...", "new_manifest_id": "...", "approved_rule_indices": [0, 2]}'
    ```

    Returns a batch ID with repaired/failed/skipped counts.
  </Step>
</Steps>

### Dashboard Quickstart

In the dashboard, the **Impact Report** banner appears automatically when your agent has 2+ manifest versions. From the banner you can:

1. Click **"Repair All"** to preview repair rules (before/after examples for each affected trace)
2. Review the rules, then click **"Apply Repairs"** to execute
3. Or click **"Repair & Build"** for a combined flow: repair all eligible traces, then build a clean SFT dataset from keep + repaired traces — one click, end to end

### REST API

```python theme={null}
import httpx

base = "https://api.decimal.ai/api/v1"
headers = {"Authorization": "Bearer dai_sk_..."}

# Preview repair rules — returns the proposed transforms with sample diffs
rules = httpx.post(
    f"{base}/repair/preview",
    headers=headers,
    json={"old_manifest_id": "...", "new_manifest_id": "...", "sample_size": 5},
).json()

# Apply all repairs
result = httpx.post(
    f"{base}/repair/apply",
    headers=headers,
    json={"old_manifest_id": "...", "new_manifest_id": "..."},
).json()

# Apply selectively (approve specific rule indices only)
result = httpx.post(
    f"{base}/repair/apply-selective",
    headers=headers,
    json={
        "old_manifest_id": "...",
        "new_manifest_id": "...",
        "approved_rule_indices": [0, 2],
    },
).json()
```

<Note>
  **Repair vs Replay:** Repair is instant (deterministic DB rewrite, zero LLM cost). Replay re-runs the full agent on original prompts (minutes/hours, full LLM cost). Use repair for schema changes; use [replay](/guides/replay) when the agent's behavior changed.
</Note>

***

## Compatibility Policies

How aggressively traces are classified when a manifest changes (strict / default / permissive presets, per-surface overrides, distillation mode, impact preview) is covered in its own guide:

<Card title="Compatibility Policies" icon="sliders" href="/guides/compatibility-policies">
  Preset reference, per-surface overrides, impact preview before applying, and the distillation override for fine-tuning workflows.
</Card>

***

## What Happens When a Manifest Changes

<Steps>
  <Step title="New version is registered">
    Auto-incremented (v1 → v2 → v3).
  </Step>

  <Step title="Compatibility report is generated">
    Each trace is classified as keep/repair/replay/drop.
  </Step>

  <Step title="Dashboard shows Impact Report">
    Visual breakdown with progress bars and action buttons.
  </Step>

  <Step title="Sidebar shows notification badge">
    Pulsing dot alerts you to drift.
  </Step>

  <Step title="Toast notification appears">
    Slide-in alert with "View Impact →" link.
  </Step>
</Steps>

<Tip>
  If you roll back to a previous configuration, DecimalAI detects the matching hash and **re-activates** the old manifest instead of creating a duplicate. Your version history stays clean.
</Tip>

***

## The Manifest Timeline

The agent dashboard shows a timeline of all manifest versions with:

* **Version label** (v1, v2, v3, or custom labels)
* **Date registered**
* **Diff view** — which surfaces changed between versions
* **Trace count** — how many traces were recorded under each version
* **Compatibility summary** — keep/repair/replay/drop counts

Click any two versions to see a side-by-side diff highlighting exactly what changed: tools added/removed, prompt text differences, model configuration changes.

***

## When Manifests Are Registered

| Framework                       | Timing                               |
| ------------------------------- | ------------------------------------ |
| LangChain                       | On first trace completion (lazy)     |
| OpenAI Agents (with `Agent`)    | Immediately at `install()` time      |
| OpenAI Agents (without `Agent`) | On first trace completion            |
| OTel                            | On first trace batch export          |
| Generic (explicit)              | When `register_manifest()` is called |
| Generic (auto-deduce)           | On first trace completion            |

***

## Best Practices

1. **Use static prompts.** Dynamic content (RAG chunks, dates) in system prompts causes false drift. Pass dynamic content as user messages instead.

2. **Use `@decimalai.tool` for full schema tracking.** The decorator generates JSON schemas from Python type hints — enabling schema-level drift detection, not just name-level.

3. **Start with the default policy.** The balanced preset works for most teams. Switch to strict when you need training data purity guarantees.

4. **Label important versions.** Use `version_label="v2.1-prod"` when deploying significant changes so you can find them in the timeline.

## Next Steps

<CardGroup cols={2}>
  <Card title="Regression Check" icon="shield-check" href="/guides/regression-check">
    Get manifest impact analysis as a PR comment on every change.
  </Card>

  <Card title="Manifests API" icon="code" href="/api-reference/manifests/overview">
    REST reference for register, list, get, diff.
  </Card>

  <Card title="Versioning & Compatibility" icon="book-open" href="/concepts/versioning">
    Conceptual model — manifest hash, component verdict, severity, repair.
  </Card>

  <Card title="Compatibility Policies" icon="sliders" href="/guides/compatibility-policies">
    Tune how the engine maps severity to verdicts.
  </Card>

  <Card title="Troubleshooting" icon="bug" href="/guides/troubleshooting">
    False drift, or the action says "no manifest"? Common fixes.
  </Card>
</CardGroup>
