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

# Umgebungsvariablen

> Vollständige Konfigurationsreferenz für FIM One.

Alle Konfigurationen werden über `.env` durchgeführt. Kopieren Sie `example.env` und füllen Sie Ihre Werte aus:

```bash theme={null}
cp example.env .env
```

## Konfigurationsebenen

Jede Integration hat eine Konfigurationsebene, die ihre Bedeutung angibt:

| Ebene            | Bedeutung                    | Verhalten wenn nicht konfiguriert                                                                     |
| ---------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| **Erforderlich** | Systemabhängigkeit           | System gibt einen Fehler aus — Chat und primäre Funktionen funktionieren nicht                        |
| **Empfohlen**    | Wichtiger Funktionsaktivator | Ordnungsgemäße Verschlechterung — die Funktion ist sichtbar nicht verfügbar, aber das System läuft    |
| **Optional**     | Verbesserungsfunktion        | Transparente Verschlechterung — System funktioniert einwandfrei, Funktion ist einfach nicht vorhanden |

> **Hinweis**: Von Administratoren konfigurierte Modelle (Admin → Seite „Modelle") können LLM-Umgebungsvariablen ersetzen. Die Integritätsprüfung berücksichtigt beide Quellen.

## Frontend (Nur lokale Entwicklung)

Das Frontend hat eine separate Env-Datei **nur für die lokale Entwicklung**: `frontend/.env.local`.

> **Diese Datei wird NICHT in Docker verwendet.** Innerhalb des Docker-Containers leitet Next.js `/api/*` intern an das Python-Backend weiter (Port 8000 ist intern im Container), daher ist keine Frontend-Env-Datei erforderlich.

Für die lokale Entwicklung funktionieren die Standardwerte sofort — Sie müssen `frontend/.env.local` **nicht** erstellen, es sei denn, Ihr Backend läuft auf einem nicht-standardmäßigen Port.

Falls Sie überschreiben müssen, erstellen Sie `frontend/.env.local` manuell:

```bash theme={null}
echo 'NEXT_PUBLIC_API_URL=http://localhost:9000' > frontend/.env.local
```

| Variable              | Standard                                | Beschreibung                                                                                                                                                                                                                                                       |
| --------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `NEXT_PUBLIC_API_URL` | `http://localhost:8000` *(automatisch)* | Backend-URL, die der **Browser** für direkte API-Aufrufe verwendet (OAuth-Umleitungen, Streaming). Wird automatisch von `window.location` erkannt, falls nicht gesetzt — überschreiben Sie nur, wenn Ihr Backend lokal auf einem nicht-standardmäßigen Port läuft. |

> **Hinweis zur Build-Zeit**: `NEXT_PUBLIC_*`-Variablen werden zur `pnpm build`-Zeit in das JS-Bundle eingebettet. Das Ändern zur Laufzeit (z. B. über die root `.env`) hat keine Auswirkung — deshalb befinden sie sich nur für die lokale Entwicklung in `frontend/.env.local`.

***

## LLM (erforderlich)

| Variable                          | Erforderlich | Standard                                           | Beschreibung                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------------------------- | ------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LLM_API_KEY`                     | **Ja**       | —                                                  | API-Schlüssel für den LLM-Anbieter                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `LLM_BASE_URL`                    | Nein         | `https://api.openai.com/v1`                        | Basis-URL einer beliebigen OpenAI-kompatiblen API                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `LLM_MODEL`                       | Nein         | `gpt-4o`                                           | Hauptmodell — verwendet für Planung, Analyse und ReAct-Agent                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `FAST_LLM_MODEL`                  | Nein         | *(fällt auf `LLM_MODEL` zurück)*                   | Schnelles Modell — verwendet für DAG-Schrittausführung (günstiger, schneller)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `LLM_TEMPERATURE`                 | Nein         | `0.7`                                              | Standard-Sampling-Temperatur                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `LLM_CONTEXT_SIZE`                | Nein         | `128000`                                           | Kontextfenstergröße für das Haupt-LLM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `LLM_MAX_OUTPUT_TOKENS`           | Nein         | `64000`                                            | Max. Ausgabe-Token pro Aufruf für das Haupt-LLM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `FAST_LLM_API_KEY`                | Nein         | *(fällt auf `LLM_API_KEY` zurück)*                 | API-Schlüssel für den Anbieter des schnellen Modells. Verwenden Sie dies, wenn das schnelle Modell von einem anderen Anbieter gehostet wird als das Hauptmodell                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `FAST_LLM_BASE_URL`               | Nein         | *(fällt auf `LLM_BASE_URL` zurück)*                | Basis-URL für den Anbieter des schnellen Modells                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `FAST_LLM_TEMPERATURE`            | Nein         | *(fällt auf `LLM_TEMPERATURE` zurück)*             | Sampling-Temperatur für das schnelle Modell                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `FAST_LLM_CONTEXT_SIZE`           | Nein         | *(fällt auf `LLM_CONTEXT_SIZE` zurück)*            | Kontextfenstergröße für das schnelle LLM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `FAST_LLM_MAX_OUTPUT_TOKENS`      | Nein         | *(fällt auf `LLM_MAX_OUTPUT_TOKENS` zurück)*       | Max. Ausgabe-Token pro Aufruf für das schnelle LLM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `LLM_REASONING_EFFORT`            | Nein         | *(deaktiviert)*                                    | Erweitertes Denk-Level für unterstützte Modelle (OpenAI o-Serie, Gemini 2.5+, Claude). Werte: `low`, `medium`, `high`. LiteLLM übersetzt dies automatisch in das native Format jedes Anbieters. Die Chain-of-Thought des Modells wird im UI-Schritt „thinking" angezeigt.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `LLM_REASONING_BUDGET_TOKENS`     | Nein         | *(automatisch aus Effort)*                         | Explizites Token-Budget für Anthropic-Denken (Minimum 1024). Für OpenAI/Gemini wird das Effort-Level direkt verwendet. Nur wirksam, wenn `LLM_REASONING_EFFORT` gesetzt ist.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `FIM_GPT5_RESPONSES_MODE`         | Nein         | `native`                                           | Welches Protokoll GPT-5.x-Modelle verwenden. `native` spricht die OpenAI Responses API direkt an und gibt das verschlüsselte Denken jeder Runde wieder, sodass das Modell seine Chain-of-Thought über Tool-Aufrufe hinweg behält. `bridge` verwendet LiteLLMs Chat-Completions-Übersetzung, die funktioniert, aber das Denken jede Runde neu ableitet. `off` erzwingt einfache Chat-Completions, bei denen das Denken deaktiviert wird, wenn Tools vorhanden sind. Lassen Sie es ungesetzt, es sei denn, Sie debuggen; Endpunkte ohne eine `/v1/responses`-Route fallen auf ihre eigene zurück. Gilt nur für GPT-5.x.                                                                                                                                                                                                                                                                                                                                                                                   |
| `LLM_JSON_MODE_ENABLED`           | Nein         | `true`                                             | Globaler Schalter für `response_format=json_object`. Setzen Sie auf `false`, wenn Ihr Anbieter LiteLLMs Assistant-Prefill-Injektion ablehnt (z. B. AWS Bedrock-Relay → `ValidationException` bei der 2. und nachfolgenden Agent-Iteration). Wenn deaktiviert, überspringen strukturierte Aufrufe den JSON-Modus und fallen auf Regex-Extraktion in Klartext zurück — kein Qualitätsverlust. Gilt für alle Modelle (ENV-konfiguriert und Admin-konfiguriert).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `LLM_TOOL_CHOICE_ENABLED`         | Nein         | `true`                                             | Globaler Schalter für erzwungenes `tool_choice` bei strukturierter Ausgabeextraktion (Level 1 — Native Function Calling). Setzen Sie auf `false`, wenn Ihr Modell Fehler bei erzwungener Tool-Auswahl zurückgibt (z. B. Denk-Modus-Modelle, die `tool_choice='specified'` ablehnen). Wenn deaktiviert, überspringen strukturierte Aufrufe natives FC und beginnen mit JSON Mode. Pro-Modell-Überschreibung verfügbar in Einstellungen → Modelle → Erweitert.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `REASONING_LLM_MODEL`             | Nein         | *(fällt auf `LLM_MODEL` zurück)*                   | Modellname für die Reasoning-Ebene. Verwendet für Aufgaben, die tiefe Analyse erfordern (z. B. DAG-Planung, Plan-Analyse)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `REASONING_LLM_API_KEY`           | Nein         | *(fällt auf `LLM_API_KEY` zurück)*                 | API-Schlüssel für den Reasoning-Modell-Anbieter                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `REASONING_LLM_BASE_URL`          | Nein         | *(fällt auf `LLM_BASE_URL` zurück)*                | Basis-URL für den Reasoning-Modell-Anbieter                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `REASONING_LLM_TEMPERATURE`       | Nein         | *(fällt auf `LLM_TEMPERATURE` zurück)*             | Sampling-Temperatur für das Reasoning-Modell                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `REASONING_LLM_CONTEXT_SIZE`      | Nein         | *(fällt auf `LLM_CONTEXT_SIZE` zurück)*            | Kontextfenstergröße für das Reasoning-Modell                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `REASONING_LLM_MAX_OUTPUT_TOKENS` | Nein         | *(fällt auf `LLM_MAX_OUTPUT_TOKENS` zurück)*       | Max. Ausgabe-Token pro Aufruf für das Reasoning-Modell                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `REASONING_LLM_EFFORT`            | Nein         | *(fällt auf `LLM_REASONING_EFFORT` zurück)*        | Reasoning-Effort-Level für die Reasoning-Modell-Ebene. Werte: `low`, `medium`, `high`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `REASONING_LLM_BUDGET`            | Nein         | *(fällt auf `LLM_REASONING_BUDGET_TOKENS` zurück)* | Token-Budget für Reasoning (hauptsächlich Anthropic). Überschreibt das automatisch berechnete Budget für die Reasoning-Ebene                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `LLM_SUPPORTS_VISION`             | Nein         | `true` *(optimistisch)*                            | Steuert, ob ENV-Modus-Dokument-OCR (über MarkItDown + `markitdown-ocr`) versucht wird. Gilt nur, wenn **keine aktive Modellgruppe in Admin → Modelle konfiguriert ist** (reiner ENV-Modus). Wenn der Standard `true` wirksam ist, nehmen `convert_to_markdown` und RAG-Erfassung an, dass `LLM_MODEL` Vision unterstützt, und rufen es für Bild-OCR auf — dies ist das richtige Verhalten für alle gängigen Optionen (`gpt-4o`, `claude-3-5-sonnet`, `gemini-1.5-pro/flash`). Setzen Sie dies auf `false`, wenn Ihr ENV-konfiguriertes `LLM_MODEL` Vision **nicht** unterstützt (z. B. `deepseek-v3`, `qwen-chat`, `llama-3.1`, `gpt-3.5-turbo`, `o1-mini`), um den fehlgeschlagenen Vision-Aufruf zu überspringen und direkt zur reinen Textextraktion zu gehen. Wenn eine aktive Modellgruppe im Admin → Modelle-Panel vorhanden ist, wird dieses Flag ignoriert und die `supports_vision`-Flags der Gruppe übernehmen — die von Admin kuratierte Wahl ist immer die Quelle der Wahrheit im DB-Modus. |

> **Auflösungsreihenfolge**: Benutzereinstellung → Admin-Modelle (DB) → ENV-Fallback. Wenn ein Admin-Modell mit der Rolle „General" in Admin → Modelle konfiguriert ist, dienen diese ENV-Variablen nur als Fallback. Die Integritätsprüfung berücksichtigt beide Quellen.

### MarkItDown OCR-Auflösung

Das `convert_to_markdown` Built-in-Tool und die RAG-Ingestion-Pipeline verwenden beide Microsofts [MarkItDown](https://github.com/microsoft/markitdown) + das offizielle [`markitdown-ocr`](https://github.com/microsoft/markitdown/tree/main/packages/markitdown-ocr) Plugin, um Text aus Dokumenten zu extrahieren — einschließlich OCR auf eingebetteten Bildern und gescannten PDF-Seiten, wenn ein Vision-fähiges LLM verfügbar ist.

**Vision-LLM-Auflösungsreihenfolge** (erste Übereinstimmung gewinnt):

| # | Quelle                                                             | Prioritätsrationale                                                                                                                                   |
| - | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | **Primäres LLM des Agenten**, wenn `supports_vision=True`          | Konsistenz: gleicher API-Schlüssel, gleicher Abrechnungsbucket, gleicher Rate-Limit-Pool wie das Gespräch.                                            |
| 2 | Aktive **ModelGroup → Fast Model**, wenn `supports_vision=True`    | Fast Models (`gpt-4o-mini`, `claude-haiku`, `gemini-1.5-flash`) sind das ideale OCR-Arbeitstier — günstig, niedrige Latenz, normalerweise multimodal. |
| 3 | Aktive **ModelGroup → General Model**, wenn `supports_vision=True` | Qualitäts-Fallback, wenn das primäre Modell nicht in der Gruppe ist.                                                                                  |
| 4 | **ENV primäres LLM** (`LLM_MODEL`)                                 | Optimistischer Fallback für reinen ENV-Modus. Wird nur verwendet, wenn keine aktive ModelGroup existiert. Gesteuert durch `LLM_SUPPORTS_VISION`.      |

**Reasoning-Modelle werden niemals für OCR bevorzugt.** Reasoning-Tiers (`o1`, `o3-mini`, `DeepSeek-R1`) haben historisch keine Vision-Unterstützung und sind ohnehin das falsche Werkzeug für OCR — OCR ist eine Wahrnehmungsaufgabe, keine Überlegungsaufgabe. Wenn ein Workspace nur ein Reasoning-Modell mit `supports_vision=True` hat, wird es trotzdem über den Primary-LLM-Pfad aufgegriffen, aber der Resolver stuft es nicht aktiv über Fast/General ein.

**Null-Regressions-Fallback**: Wenn auf keiner Ebene ein Vision-fähiges Modell gefunden wird, wird OCR stillschweigend deaktiviert und MarkItDown läuft im reinen Text-Modus. OCR für eingebettete Bilder in Word/PowerPoint/Excel wird nicht verfügbar (wie vor dieser Funktion), aber alle andere Textextraktion (Überschriften, Tabellen, Absatztext) funktioniert unverändert weiter. **Es gibt niemals einen Fall, in dem das Hinzufügen dieser Funktion die Extraktion schlechter machte als das vorherige Verhalten.**

**Nicht-OpenAI-Provider (Anthropic, Google Gemini, etc.)** werden transparent unterstützt: das aufgelöste LLM wird in einem `LiteLLMOpenAIShim` verpackt, das `chat.completions.create(...)`-Aufrufe durch `litellm.completion()` leitet, was die Provider-spezifische Nachrichtenformat-Übersetzung handhabt (z. B. Anthropics `source.type="base64"` Image-Block). Ein Shim deckt jeden Provider ab, den LiteLLM unterstützt — das Hinzufügen eines neuen Providers kostet null Code-Änderungen in FIM One.

### Extended Thinking (Reasoning)

Wenn `LLM_REASONING_EFFORT` gesetzt ist, aktiviert FIM One die Extended-Thinking-Funktion des Modells, sodass die interne Gedankenkette im UI-Schritt "thinking" angezeigt wird. FIM One verwendet [LiteLLM](https://github.com/BerriAI/litellm), um den Reasoning-Effort-Parameter automatisch in das native Format jedes Anbieters zu übersetzen.

#### Unterstützte Anbieter

Welche Anbieter Thinking akzeptieren, wie jeder einzelne aktiviert wird, welche `effort`-Werte er annimmt und wo der Reasoning-Text endet, wird einmalig mit Code-Ankern in [Tabelle C der Provider Capability Matrix](/architecture/llm-provider-guide#provider-capability-matrix) dokumentiert. Diese Tabelle ist die autoritative Liste; diese Seite dokumentiert nur die Variablen.

FIM One löst den Anbieter aus `LLM_BASE_URL` auf (plus ein explizites Anbieterfeld, wenn eines konfiguriert ist) und ordnet die Anfrage dem korrekten API-Format zu. Unbekannte URLs werden als OpenAI-kompatibel behandelt.

#### Wichtige Einschränkungen

<Warning>
  **Third-Party-Proxies / benutzerdefinierte Endpunkte sind nicht garantiert.**
  Wenn Ihr `LLM_BASE_URL` auf einen Third-Party-API-Proxy verweist (z. B. OpenRouter, one-api, benutzerdefiniertes Gateway), wird LiteLLM versuchen, basierend auf der URL korrekt weiterzuleiten. Wenn Ihr Proxy jedoch ein nicht standardisiertes Format erwartet, funktioniert das Reasoning möglicherweise nicht wie erwartet. Konsultieren Sie die Dokumentation des Proxys für das erwartete Parameterformat.
</Warning>

#### Temperatureinschränkungen mit Reasoning

Einige Anbieter schränken `temperature` ein, wenn Reasoning aktiv ist. **Alle diese Einschränkungen werden automatisch durchgesetzt; lassen Sie `LLM_TEMPERATURE` bei dem Wert, der zu Ihrer Workload passt.**

* **Anthropic**: erfordert `temperature=1` während Extended Thinking aktiviert ist. Der Request Builder setzt den Wert auf Anthropic-Routen fest, sodass Ihre konfigurierte Temperatur für diese Aufrufe überschrieben wird, anstatt abgelehnt zu werden.
* **Anthropic, strikte Modelle** (Opus 4.7 und 4.8, Fable 5, Mythos 5): lehnen `temperature`, `top_p` und `top_k` grundsätzlich ab, unabhängig von Thinking. FIM One entfernt `temperature` aus dem Request für diese Modelle.
* **OpenAI GPT-5.x**: unterstützt nur `temperature=1`. Das `drop_params`-Filtering von LiteLLM entfernt nicht unterstützte Werte.

Das manuelle Setzen von `LLM_TEMPERATURE=1` zur Erfüllung von Anthropic-Anforderungen ist unnötig und kostet Sie die Möglichkeit, eine niedrigere Temperatur bei jedem Nicht-Thinking-Aufruf zu verwenden.

#### Wie `LLM_REASONING_BUDGET_TOKENS` funktioniert

Diese Variable ist **nur auf dem Legacy-Anthropic-Thinking-Pfad sinnvoll** (Claude 4.5 und älter, geroutet als `anthropic/`). Dort überschreibt sie das automatisch berechnete Budget und wird als `budget_tokens` innerhalb des `thinking`-Parameters gesendet. Adaptive-Thinking-Modelle (Opus 4.6 und neuer, Sonnet 4.6, Fable 5, Mythos 5) verwenden stattdessen eine Anstrengungsstufe und ignorieren diese Variable vollständig. Wenn sie nicht gesetzt ist, wird das Budget aus `LLM_MAX_OUTPUT_TOKENS` × Anstrengungsverhältnis abgeleitet:

| `LLM_REASONING_EFFORT` | Budget-Verhältnis | Beispiel (max\_tokens = 64000) |
| ---------------------- | ----------------- | ------------------------------ |
| `low`                  | 20%               | 12.800 Token                   |
| `medium`               | 50%               | 32.000 Token                   |
| `high`                 | 80%               | 51.200 Token                   |

Das Mindestbudget beträgt 1.024 Token (Anthropics hartes Minimum).

Für OpenAI und Gemini verwaltet der Provider die Token-Zuweisung intern basierend auf der `reasoning_effort`-Stufe — `LLM_REASONING_BUDGET_TOKENS` hat keine Auswirkung.

## Agent-Ausführung

### ReAct Agent

| Variable                            | Required | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ----------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REACT_MAX_ITERATIONS`              | No       | `20`    | Max tool-call iterations per ReAct request. Higher = more thorough but slower and costlier                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `REACT_MAX_TURN_TOKENS`             | No       | `0`     | Emergency circuit-breaker: max cumulative tokens (prompt + completion across all iterations) per single ReAct turn. Default `0` = unlimited. **This is NOT for daily token control** — use per-user `token_quota` for that. This is a last-resort safety valve for extreme scenarios like an agent stuck in an infinite tool-call loop. Hitting this limit aborts the task mid-execution, wasting all tokens consumed so far and returning an incomplete result. Keep at `0` unless you have a specific runaway-agent problem to contain |
| `REACT_TOOL_SELECTION_THRESHOLD`    | No       | `12`    | When the total number of registered tools exceeds this threshold, a lightweight LLM call selects the most relevant subset before each request                                                                                                                                                                                                                                                                                                                                                                                            |
| `REACT_TOOL_SELECTION_MAX`          | No       | `6`     | Max tools to keep after smart selection (only effective when tool count exceeds `REACT_TOOL_SELECTION_THRESHOLD`)                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `REACT_SELF_REFLECTION_INTERVAL`    | No       | `6`     | Inject a self-reflection prompt every N tool calls to help the agent course-correct and avoid loops                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `REACT_TOOL_OBS_TRUNCATION`         | No       | `8000`  | Max characters per tool observation when synthesizing the final answer. Higher values preserve more structured data (JSON, tables) at the cost of more tokens                                                                                                                                                                                                                                                                                                                                                                            |
| `REACT_TOOL_RESULT_BUDGET`          | No       | `40000` | Aggregate token budget for all tool results in a single session. When total tool-result tokens exceed this cap, new results are truncated with a notice. Prevents context bloat from large API responses (e.g., 5 connector calls returning 8K each). Set to `0` to disable the cap                                                                                                                                                                                                                                                      |
| `REACT_COMPLETION_CHECK_SKIP_CHARS` | No       | `800`   | Skip the post-answer completion-check LLM call when the agent's final answer exceeds this many characters. Long detailed answers don't need a "did I miss anything?" verification round-trip. Set lower to skip more aggressively; set to a very large value to always run the check                                                                                                                                                                                                                                                     |
| `REACT_CYCLE_DETECTION_THRESHOLD`   | No       | `2`     | When the same tool is called with identical arguments this many times in a row, a deterministic warning is injected telling the agent to try a different approach. Unlike self-reflection (which relies on the LLM noticing the loop), this is a hash-based check that cannot be bypassed. Also applies to DAG steps                                                                                                                                                                                                                     |
| `REACT_COMPLETION_CHECK_MIN_TOOLS`  | No       | `3`     | Minimum number of tool calls before the completion checklist fires. Simple tasks (1-2 tool calls) skip verification to avoid unnecessary latency. Set to `1` for always-on verification. Also applies to DAG steps                                                                                                                                                                                                                                                                                                                       |
| `REACT_TURN_PROFILE_ENABLED`        | No       | `true`  | Emit per-turn phase-level timing logs (`memory_load`, `compact`, `tool_schema_build`, `llm_first_token`, `llm_total`, `tool_exec`). One structured log line per turn. Set to `false` to disable profiling entirely (zero overhead)                                                                                                                                                                                                                                                                                                       |
| `REACT_PLAN_TOOL_ENABLED`           | No       | `true`  | Register the `update_plan` todo tool so the agent writes down and maintains a plan checklist during multi-step tasks. Automatically skipped for DAG step agents and agents with no tools                                                                                                                                                                                                                                                                                                                                                 |
| `REACT_PLAN_REMINDER_INTERVAL`      | No       | `3`     | Tool rounds without an `update_plan` call before a stale-plan reminder (embedding the full checklist) is re-injected into the conversation, so the plan survives context compaction                                                                                                                                                                                                                                                                                                                                                      |
| `REACT_PLAN_REPEAT_THRESHOLD`       | No       | `4`     | Consecutive rounds calling the same tool (with different arguments) before a reminder tells the agent to change approach instead of repeating fruitless calls. Exact-duplicate calls are handled separately by cycle detection                                                                                                                                                                                                                                                                                                           |
| `REACT_PLAN_NUDGE_AFTER`            | No       | `5`     | Tool rounds with no plan recorded before a one-shot nudge suggests writing the plan down. Only applies when the plan tool is enabled                                                                                                                                                                                                                                                                                                                                                                                                     |
| `REACT_FINISH_SIGNAL`               | No       | `true`  | FINAL-first answering on the chat path: the agent ends its tool loop on a `finish` signal and then writes the answer as a genuinely token-streamed turn. Set to `false` to restore inline loop answers with buffered replay                                                                                                                                                                                                                                                                                                              |
| `REACT_MAX_CONTINUATIONS`           | No       | `3`     | Maximum continuation rounds when the model's answer is cut off by the provider's output-token limit (`finish_reason=length`). Truncated segments are stitched into one seamless answer, both in the agent loop and in streamed synthesis                                                                                                                                                                                                                                                                                                 |
| `REACT_BACKGROUND_TOOLS_ENABLED`    | No       | `true`  | Offer a `run_in_background` option on slow tools (sandboxed python/shell/node execution). The agent gets a task id immediately and continues working; the result arrives as a `<task_notification>` message when the tool finishes                                                                                                                                                                                                                                                                                                       |
| `REACT_BG_WAIT_TIMEOUT`             | No       | `300`   | Maximum seconds to wait for still-running background tools when the agent wants to finalize its answer. Tasks not finished within the window are cancelled with an explicit timeout notification                                                                                                                                                                                                                                                                                                                                         |
| `DAG_CHECKPOINT_EVIDENCE_CHARS`     | No       | `4000`  | Per-step evidence cap in the DAG crash-resume checkpoint file (`data/dag_checkpoints/`). Step summaries are stored in full                                                                                                                                                                                                                                                                                                                                                                                                               |
| `DAG_CHECKPOINT_MAX_AGE_HOURS`      | No       | `24`    | DAG checkpoints older than this are ignored on load, so stale crash leftovers never resume into a fresh run                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `LLM_RATE_LIMIT_PER_USER`           | No       | `true`  | Use per-user keyed rate-limit buckets instead of a single process-global bucket. Prevents one noisy user from starving all others on the same worker. The underlying rate is hardcoded at 60 requests/min and 100K tokens/min per bucket — this setting only controls whether the bucket is shared (global) or partitioned (per-user). Set to `false` to revert to the legacy global bucket (not recommended)                                                                                                                            |

### DAG Planner

| Variable                         | Required | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MAX_CONCURRENCY`                | No       | `5`     | Max parallel steps in DAG executor                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `DAG_STEP_MAX_ITERATIONS`        | No       | `15`    | Max tool-call iterations within each DAG step                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `DAG_STEP_TIMEOUT`               | No       | `600`   | Step execution timeout in seconds. Steps exceeding this are marked as failed and their dependents are cascade-skipped                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `DAG_MAX_REPLAN_ROUNDS`          | No       | `3`     | Max autonomous re-plan attempts when goal is not achieved. User interrupts (inject) are unlimited and do not count against this budget                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `DAG_REPLAN_STOP_CONFIDENCE`     | No       | `0.8`   | Applies only when the agent judges the goal **unreachable** (impossible request, missing capability, dead resource): stop retrying at or above this certainty. A missing or half-finished deliverable is always re-planned regardless of confidence — only `DAG_MAX_REPLAN_ROUNDS` bounds those retries                                                                                                                                                                                                                                                                       |
| `DAG_VERIFY_TRUNCATION`          | No       | `2000`  | Max characters of step output sent to the step verifier LLM for quality judgment                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `DAG_ANALYZER_TRUNCATION`        | No       | `10000` | Max characters per step result when formatting for the post-execution analyzer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `DAG_STEP_EVIDENCE_CHARS`        | No       | `16000` | Max characters of raw tool output (web fetches, search results, file reads) retained per step as authoritative "source evidence". This is fed to the analyzer and final synthesis alongside the step's own summary, so the answer's factual claims (totals, enumerations, severities) can be verified against the source instead of trusting a summary that may have silently dropped or mislabelled items. Set to `0` to disable evidence capture                                                                                                                            |
| `DAG_REPLAN_RECENT_TRUNCATION`   | No       | `500`   | Max characters per step result from the most recent round when building re-plan context                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `DAG_REPLAN_OLDER_TRUNCATION`    | No       | `200`   | Max characters per step result from older rounds when building re-plan context. Older rounds are more aggressively truncated to save context                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `DAG_TOOL_CACHE`                 | No       | `true`  | Cache identical tool calls within a single DAG execution. Only tools explicitly marked as `cacheable` (read-only tools like search, knowledge retrieval) are cached. Set to `false` to disable caching entirely                                                                                                                                                                                                                                                                                                                                                               |
| `DAG_STEP_VERIFICATION`          | No       | `false` | Generic LLM-based quality check after each DAG step. On failure, the step retries once with feedback. **Default off** — adds latency on every step and is rarely needed; most step outputs are acceptable without re-checking. Use only when you observe frequent low-quality step results                                                                                                                                                                                                                                                                                    |
| `DAG_CITATION_VERIFICATION`      | No       | `true`  | Citation-accuracy check for specialist-domain steps. **Prerequisite**: the query must first be classified as a specialist domain by the LLM domain classifier (see `ESCALATION_DOMAINS`). When the domain is detected AND this flag is `true`, each completed step is scanned for legal/medical/financial citations and verified for accuracy — catching hallucinated article numbers, fabricated case references, and incorrect regulatory citations. If domain classification returns `null` (general query), citation verification does not run regardless of this setting |
| `DAG_CITATION_VERIFY_TRUNCATION` | No       | `6000`  | Max characters of step result sent to the citation verification prompt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

### Domain-Klassifizierung

Steuert die unabhängige LLM-basierte Domain-Erkennungsschicht, die **vor** der ReAct- und DAG-Ausführung ausgeführt wird. Wenn eine Abfrage als spezialisierte Domain klassifiziert wird, aktiviert das System Domain-bewusste Funktionen: Modellsteigerung auf Reasoning-Modell, Domain-spezifische SOP-Anweisungen und Zitierverifikation (nur DAG).

| Variable             | Erforderlich | Standard                                        | Beschreibung                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------- | ------------ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ESCALATION_DOMAINS` | Nein         | `legal,medical,financial,tax,compliance,patent` | Kommagetrennte Liste spezialisierter Domains. Ein schnelles LLM klassifiziert jede Abfrage gegen diese Liste. Bei Übereinstimmung führt das System folgende Schritte durch: (1) Upgrade auf das Reasoning-Modell für höhere Genauigkeit, (2) Injektion von Domain-spezifischen SOP-Anweisungen (z. B. Zitate vor dem Schreiben per Suche verifizieren), (3) Aktivierung der Zitierverifikation für DAG-Schritte. Fügen Sie nach Bedarf benutzerdefinierte Domains hinzu (z. B. `legal,education,construction`) |

### Context Guard

Steuert die automatische Verwaltung des Kontextfensters, die verhindert, dass Gespräche das Limit des Modells überschreiten.

| Variable                       | Erforderlich | Standard | Beschreibung                                                                                                                                     |
| ------------------------------ | ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CONTEXT_GUARD_DEFAULT_BUDGET` | Nein         | `32000`  | Standard-Token-Budget für die Verwaltung des Kontextfensters. Wenn das Gespräch diesen Wert überschreitet, werden ältere Nachrichten komprimiert |
| `CONTEXT_GUARD_MAX_MSG_CHARS`  | Nein         | `50000`  | Hartes Zeichenlimit für jede einzelne Nachricht. Nachrichten, die diesen Wert überschreiten, werden als Sicherheitsmaßnahme gekürzt              |
| `CONTEXT_GUARD_KEEP_RECENT`    | Nein         | `4`      | Anzahl der neuesten Nachrichten, die bei der Komprimierung des Gesprächsverlaufs beibehalten werden                                              |

### Content Guardrails

Kommagetrennte Namen von Guardrails, die den *Inhalt* von Ein- oder Ausgabe überprüfen. Unabhängig vom Tool-Berechtigungsgate (`core/hooks/*`) und der Sicherheitsschicht (`core/security/*`). Siehe [Content Guardrails](/configuration/guardrails) für das vollständige Bild.

| Variable                         | Erforderlich | Standard    | Beschreibung                                                                                                                                                                                                                                                           |
| -------------------------------- | ------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FIM_GUARDRAILS_INPUT`           | Nein         | `jailbreak` | Aktive Input-Guardrails. Der Standard-`jailbreak`-Regex-Detektor bricht den Turn ab, bevor LLM-Token ausgegeben werden, wenn bekannte Prompt-Override-Phrasen erkannt werden. Auf leer setzen zum Deaktivieren. Unbekannte Namen werden protokolliert und übersprungen |
| `FIM_GUARDRAILS_OUTPUT`          | Nein         | (leer)      | Aktive Output-Guardrails. Derzeit enthalten: `max_length` (begrenzt die Zeichenanzahl der Antwort). Wird ausgeführt, nachdem der Agent seine endgültige Antwort produziert hat                                                                                         |
| `FIM_GUARDRAIL_MAX_OUTPUT_CHARS` | Nein         | `50000`     | Zeichenlimit, das vom `max_length`-Output-Guardrail verwendet wird. Nur wirksam, wenn `max_length` in `FIM_GUARDRAILS_OUTPUT` aufgelistet ist                                                                                                                          |

### Agent-Arbeitsbereich

| Variable                      | Erforderlich | Standard | Beschreibung                                                                                                                                                                           |
| ----------------------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WORKSPACE_OFFLOAD_THRESHOLD` | Nein         | `8000`   | Wenn eine Werkzeugausgabe diese Anzahl von Zeichen überschreitet, wird sie in einer Arbeitsbereichsdatei gespeichert und eine gekürzte Vorschau wird in den Gesprächskontext eingefügt |
| `WORKSPACE_PREVIEW_CHARS`     | Nein         | `2000`   | Anzahl der Vorschauzeichen, die in gekürzten Arbeitsbereichsreferenzen enthalten sein sollen                                                                                           |
| `WORKSPACE_CLEANUP_MAX_HOURS` | Nein         | `72`     | Arbeitsbereichsdateien, die älter als diese Anzahl von Stunden sind, sind für die automatische Bereinigung berechtigt                                                                  |

### System

| Variable                    | Required | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| --------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ~~`SYSTEM_PROMPT_RESERVE`~~ | —        | —       | **Entfernt.** Subtrahierte zuvor einen festen 4K-Reserve vom Kontext-Budget für Systemprompts. Dies führte zu Doppelzählungen, da ContextGuard die Systemprompt bereits bei der Schätzung der Token der Nachrichtenliste berücksichtigt. Die Budget-Formel lautet jetzt `(context_size - max_output_tokens) × 0.92` (die Marge absorbiert Token-Schätzungsfehler), und die tatsächliche Größe der Systemprompt wird dynamisch berücksichtigt |

## Web Tools (Optional)

| Variable              | Required | Default                           | Description                                                                                                                                                                                             |
| --------------------- | -------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `JINA_API_KEY`        | No       | —                                 | Jina API key. Powers the **default** search backend, and acts as a shared fallback for **fetch, embedding, and reranker** when no service-specific key is set. Get yours at [jina.ai](https://jina.ai/) |
| `TAVILY_API_KEY`      | No       | —                                 | Tavily Search API key. Required when `WEB_SEARCH_PROVIDER=tavily`; also used by auto-detect if the provider is unset                                                                                    |
| `BRAVE_API_KEY`       | No       | —                                 | Brave Search API key. Required when `WEB_SEARCH_PROVIDER=brave`; also used by auto-detect if the provider is unset                                                                                      |
| `EXA_API_KEY`         | No       | —                                 | Exa Search API key. Required when `WEB_SEARCH_PROVIDER=exa`; also used by auto-detect if the provider is unset. See [Exa](/integrations/exa). Get yours at [exa.ai](https://exa.ai/)                    |
| `WEB_SEARCH_PROVIDER` | No       | `jina`                            | Search provider selector: `jina` (default) / `tavily` / `brave` / `exa`. Prefer setting this explicitly when using a non-default provider                                                               |
| `WEB_FETCH_PROVIDER`  | No       | `jina` (if key set, else `httpx`) | Fetch provider: `jina` (uses Jina Reader API) / `httpx` (direct HTTP request, no API key needed)                                                                                                        |

> **Schnelleinstieg-Tipp**: Das Setzen von nur `JINA_API_KEY` aktiviert den Standard-Web-Search-Stack sowie Web-Fetch, Embedding und Reranking — ein Schlüssel, vier Services. Wechseln Sie die Suche zu Tavily, Brave oder Exa mit `WEB_SEARCH_PROVIDER` und dem entsprechenden API-Schlüssel.

***

## RAG & Wissensdatenbank (Empfohlen)

### Embedding

Embedding konvertiert Text in Vektoren für die Wissensdatenbank-Suche. FIM One verwendet den Standard-**OpenAI-kompatiblen `/v1/embeddings`-Endpunkt**, daher funktioniert er mit jedem Anbieter, der diese Schnittstelle bereitstellt — nicht nur Jina.

| Variable              | Erforderlich | Standard                            | Beschreibung                             |
| --------------------- | ------------ | ----------------------------------- | ---------------------------------------- |
| `EMBEDDING_API_KEY`   | Nein         | *(fällt auf `JINA_API_KEY` zurück)* | API-Schlüssel für den Embedding-Anbieter |
| `EMBEDDING_BASE_URL`  | Nein         | `https://api.jina.ai/v1`            | Basis-URL für den Embedding-Anbieter     |
| `EMBEDDING_MODEL`     | Nein         | `jina-embeddings-v3`                | Modellbezeichner                         |
| `EMBEDDING_DIMENSION` | Nein         | `1024`                              | Vektordimension                          |

**Anbieterbeispiele** — setzen Sie einfach die drei Variablen, um zu wechseln:

| Anbieter              | `EMBEDDING_BASE_URL`          | `EMBEDDING_MODEL`        | `EMBEDDING_DIMENSION` |
| --------------------- | ----------------------------- | ------------------------ | --------------------- |
| **Jina** *(Standard)* | `https://api.jina.ai/v1`      | `jina-embeddings-v3`     | `1024`                |
| **OpenAI**            | `https://api.openai.com/v1`   | `text-embedding-3-small` | `1536`                |
| **Voyage**            | `https://api.voyageai.com/v1` | `voyage-3`               | `1024`                |
| **Ollama** *(lokal)*  | `http://localhost:11434/v1`   | `nomic-embed-text`       | `768`                 |

<Warning>
  **Das Ändern des Embedding-Modells oder der Dimension macht alle vorhandenen Wissensdatenbank-Vektoren ungültig.** Alte Vektoren wurden in einem anderen Embedding-Raum berechnet — die Abrufgenauigkeit wird sich unmerklich verschlechtern. Sie müssen **alle Wissensdatenbank-Indizes neu erstellen**, nachdem Sie gewechselt haben.
</Warning>

### Abruf

| Variable         | Erforderlich | Standard    | Beschreibung                                                                                          |
| ---------------- | ------------ | ----------- | ----------------------------------------------------------------------------------------------------- |
| `RETRIEVAL_MODE` | Nein         | `grounding` | `grounding` (vollständige Pipeline mit Zitaten und Konfidenzscoring) oder `simple` (grundlegende RAG) |

### Reranker

Reranker bewertet abgerufene Dokumente neu, um die Relevanz zu verbessern. Drei Anbieter werden unterstützt — wählen Sie über `RERANKER_PROVIDER` oder lassen Sie das System automatisch aus verfügbaren API-Schlüsseln erkennen.

| Variable                | Erforderlich | Standard                             | Beschreibung                                                                                                             |
| ----------------------- | ------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `RERANKER_PROVIDER`     | Nein         | *(automatische Erkennung)*           | `jina` / `cohere` / `openai`. Falls nicht gesetzt: verwendet Cohere, wenn `COHERE_API_KEY` gesetzt ist, andernfalls Jina |
| `RERANKER_MODEL`        | Nein         | `jina-reranker-v2-base-multilingual` | Modellkennung (gilt für Jina- und OpenAI-Anbieter)                                                                       |
| `COHERE_API_KEY`        | Nein         | —                                    | Cohere API-Schlüssel (wählt automatisch Cohere-Reranker aus, wenn gesetzt und `RERANKER_PROVIDER` nicht gesetzt ist)     |
| `COHERE_RERANKER_MODEL` | Nein         | `rerank-multilingual-v3.0`           | Cohere-spezifisches Reranker-Modell                                                                                      |

> **Jina** verwendet `JINA_API_KEY` (aus Web Tools oben). **OpenAI** verwendet `LLM_API_KEY` / `LLM_BASE_URL` erneut — kein zusätzlicher Schlüssel erforderlich. **Cohere** benötigt seinen eigenen `COHERE_API_KEY`.

> Reranker ist **optional** — die Wissensdatenbanksuche funktioniert ohne ihn mit Fusion-Scoring. Embedding wird **empfohlen** für Wissensdatenbankfunktionen.

### Vektorspeicher

| Variable           | Erforderlich | Standard              | Beschreibung                                                                       |
| ------------------ | ------------ | --------------------- | ---------------------------------------------------------------------------------- |
| `VECTOR_STORE_DIR` | Nein         | `./data/vector_store` | Verzeichnis für LanceDB-Vektorspeicherdaten (dateibasiert, keine externen Dienste) |

***

## Code-Ausführung

| Variable               | Erforderlich | Standard            | Beschreibung                                                                                                                                                                                |
| ---------------------- | ------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CODE_EXEC_BACKEND`    | Nein         | `local`             | `local` (direkte Host-Ausführung) oder `docker` (isolierte Container)                                                                                                                       |
| `DOCKER_PYTHON_IMAGE`  | Nein         | `python:3.11-slim`  | Docker-Image für Python-Ausführung                                                                                                                                                          |
| `DOCKER_NODE_IMAGE`    | Nein         | `node:20-slim`      | Docker-Image für Node.js-Ausführung                                                                                                                                                         |
| `DOCKER_SHELL_IMAGE`   | Nein         | `python:3.11-slim`  | Docker-Image für Shell-Ausführung                                                                                                                                                           |
| `DOCKER_MEMORY`        | Nein         | *(Docker-Standard)* | RAM-Limit pro Container (z. B. `256m`, `512m`, `1g`)                                                                                                                                        |
| `DOCKER_CPUS`          | Nein         | *(Docker-Standard)* | CPU-Kontingent pro Container (z. B. `0.5`, `1.0`)                                                                                                                                           |
| `SANDBOX_TIMEOUT`      | Nein         | `120`               | Standard-Ausführungs-Timeout in Sekunden                                                                                                                                                    |
| `DOCKER_HOST_DATA_DIR` | Nein         | *(nicht gesetzt)*   | Host-seitiger absoluter Pfad des `./data` Volume-Mounts. Erforderlich für DooD-Bereitstellungen (Docker-outside-of-Docker); `docker-compose.yml` setzt dies automatisch über `${PWD}/data`. |

> **Sicherheit**: Der `local`-Modus führt von KI generierte Code direkt auf dem Host aus. Für internetgestützte oder Multi-User-Bereitstellungen sollten Sie immer `CODE_EXEC_BACKEND=docker` setzen.

## Werkzeug-Artefakte

Größenlimits für Dateien, die durch Werkzeugausführung erstellt werden (Code-Ausführung, Template-Rendering, Bildgenerierung).

| Variable              | Erforderlich | Standard           | Beschreibung                                            |
| --------------------- | ------------ | ------------------ | ------------------------------------------------------- |
| `MAX_ARTIFACT_SIZE`   | Nein         | `10485760` (10 MB) | Maximale Größe einer einzelnen Artefaktdatei in Bytes   |
| `MAX_ARTIFACTS_TOTAL` | Nein         | `52428800` (50 MB) | Maximale Gesamtgröße der Artefakte pro Sitzung in Bytes |

***

## Dokumentverarbeitung (Optional)

Steuert, wie hochgeladene PDF-/DOCX-Dateien für die LLM-Verarbeitung verarbeitet werden. Vision-fähige Modelle (GPT-4o, Claude 3/4, Gemini) können PDF-Seiten als gerenderte Bilder für höhere Genauigkeit empfangen.

| Variable                    | Erforderlich | Standard | Beschreibung                                                                                              |
| --------------------------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------- |
| `DOCUMENT_PROCESSING_MODE`  | Nein         | `auto`   | `auto` (Vision, falls Modell unterstützt), `vision` (Seiten immer rendern), `text` (nur Text extrahieren) |
| `DOCUMENT_VISION_DPI`       | Nein         | `150`    | DPI für PDF-Seitenrendering. Höher = bessere Qualität, mehr Token                                         |
| `DOCUMENT_VISION_MAX_PAGES` | Nein         | `20`     | Maximale Anzahl von Seiten, die pro PDF als Bilder gerendert werden                                       |

> **Hinweis**: Die Vision-Unterstützung pro Modell wird über den `supports_vision`-Schalter in Admin → Models konfiguriert. Wenn nicht explizit festgelegt, erkennt das System die Vision-Fähigkeit automatisch anhand des Modellnamens.

## Bildgenerierung (Optional)

| Variable             | Erforderlich | Standard                         | Beschreibung                                                                                    |
| -------------------- | ------------ | -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `IMAGE_GEN_PROVIDER` | Nein         | `google`                         | `google` (Gemini native API) oder `openai` (OpenAI-kompatible `/v1/images/generations`)         |
| `IMAGE_GEN_API_KEY`  | Nein         | —                                | Google AI Studio Schlüssel (`google`) oder Proxy/OpenAI API Schlüssel (`openai`)                |
| `IMAGE_GEN_MODEL`    | Nein         | `gemini-3.1-flash-image-preview` | Bildgenerierungsmodell (z. B. `dall-e-3`, `gemini-nano-banana-2`)                               |
| `IMAGE_GEN_BASE_URL` | Nein         | *(pro Anbieter)*                 | Google: `https://generativelanguage.googleapis.com/v1beta`; OpenAI: `https://api.openai.com/v1` |

***

## Email (SMTP) (Empfohlen)

Registriert das `email_send` Built-in-Tool automatisch, wenn `SMTP_HOST`, `SMTP_USER` und `SMTP_PASS` alle gesetzt sind.

| Variable                 | Erforderlich | Standard                  | Beschreibung                                                                                                                                                                                                           |
| ------------------------ | ------------ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SMTP_HOST`              | Bed.         | —                         | SMTP-Serverhostname                                                                                                                                                                                                    |
| `SMTP_PORT`              | Nein         | `465`                     | SMTP-Port                                                                                                                                                                                                              |
| `SMTP_SSL`               | Nein         | `ssl`                     | TLS-Modus: `ssl` (Port 465) / `tls` (STARTTLS, Port 587) / `none` oder `""` (unverschlüsselt, Anmeldedaten im Klartext). Jeder andere Wert wird abgelehnt, anstatt stillschweigend auf unverschlüsselt zurückzufallen. |
| `SMTP_USER`              | Bed.         | —                         | SMTP-Anmeldebenutzername                                                                                                                                                                                               |
| `SMTP_PASS`              | Bed.         | —                         | SMTP-Anmeldepasswort                                                                                                                                                                                                   |
| `SMTP_FROM`              | Nein         | *(verwendet `SMTP_USER`)* | Absenderadresse im From-Header                                                                                                                                                                                         |
| `SMTP_FROM_NAME`         | Nein         | —                         | Anzeigename im From-Header                                                                                                                                                                                             |
| `SMTP_REPLY_TO`          | Nein         | —                         | Reply-To-Adresse; Antworten gehen hier statt an `SMTP_FROM`                                                                                                                                                            |
| `SMTP_ALLOWED_DOMAINS`   | Nein         | —                         | Kommagetrennte Domain-Allowlist (z. B. `example.com,corp.io`); blockiert Empfänger außerhalb der aufgelisteten Domains                                                                                                 |
| `SMTP_ALLOWED_ADDRESSES` | Nein         | —                         | Kommagetrennte Allowlist für genaue Adressen; kombiniert mit `SMTP_ALLOWED_DOMAINS`; beide nicht gesetzt lassen, um jeden Empfänger zuzulassen (nicht empfohlen für gemeinsame Postfächer)                             |

***

## Konnektoren

| Variable                       | Erforderlich | Standard          | Beschreibung                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------ | ------------ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTOR_RESPONSE_MAX_CHARS` | Nein         | `50000`           | Maximale Anzahl von Zeichen für Antworten von Nicht-Array-JSON-/Klartext-Konnektoren                                                                                                                                                                                                                                                               |
| `CONNECTOR_RESPONSE_MAX_ITEMS` | Nein         | `10`              | Maximale Array-Elemente, die beibehalten werden, wenn die Konnektor-Antwort ein JSON-Array ist                                                                                                                                                                                                                                                     |
| `CREDENTIAL_ENCRYPTION_KEY`    | Nein         | *(nicht gesetzt)* | Fernet-Verschlüsselungsschlüssel für Konnektor-Anmeldedaten-Blobs. Wenn gesetzt, werden Auth-Token in `connector_credentials` im Ruhezustand verschlüsselt. Wenn nicht gesetzt, werden Anmeldedaten als einfaches JSON gespeichert (abwärtskompatibel). Das Ändern dieses Schlüssels macht alle vorhandenen verschlüsselten Anmeldedaten ungültig. |
| `CONNECTOR_TOOL_MODE`          | Nein         | `progressive`     | Wie Konnektor-Tools für Agenten verfügbar gemacht werden. `progressive`: einzelnes `ConnectorMetaTool` mit `discover`/`execute`-Unterbefehlen (\~30 Token/Konnektor). `classic`: ein Tool pro Aktion (Legacy, \~250 Token/Aktion).                                                                                                                 |
| `DATABASE_TOOL_MODE`           | Nein         | `progressive`     | Wie Datenbank-Konnektor-Tools für Agenten verfügbar gemacht werden. `progressive`: einzelnes `DatabaseMetaTool` mit `list_tables`/`discover`/`query`-Unterbefehlen. `legacy`: ein Tool pro Aktion pro Datenbank-Konnektor (3 Tools jeweils).                                                                                                       |
| `MCP_TOOL_MODE`                | Nein         | `progressive`     | Wie MCP-Server-Tools für Agenten verfügbar gemacht werden. `progressive`: einzelnes `MCPServerMetaTool` mit `discover`/`call`-Unterbefehlen. `legacy`: ein Tool pro MCP-Server-Aktion (ursprüngliche einzelne Tools).                                                                                                                              |

***

## Platform

| Variable                         | Required | Default                                 | Description                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------- | -------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DATABASE_URL`                   | No       | `sqlite+aiosqlite:///./data/fim_one.db` | Datenbankverbindungszeichenfolge. **SQLite** (keine Konfiguration erforderlich): `sqlite+aiosqlite:///./data/fim_one.db`. **PostgreSQL** (Produktion): `postgresql+asyncpg://user:pass@localhost:5432/fim_one`. Docker Compose konfiguriert PostgreSQL automatisch.                                                                                                                                    |
| `JWT_SECRET_KEY`                 | No       | `CHANGE_ME`                             | Geheimer Schlüssel zum Signieren von JWT-Token. Der Platzhalterwert `CHANGE_ME` (oder ein anderer älterer Standardwert) löst beim ersten Start die automatische Generierung eines sicheren 256-Bit-Zufallsschlüssels aus, der in `.env` zurückgeschrieben wird. Legen Sie ihn in der Produktion explizit fest, um Token über Neustarts und Replikas hinweg gültig zu halten.                           |
| `FIM_BCRYPT_COST`                | No       | `12`                                    | bcrypt-Arbeitsfaktor für Passwort-Hashing, begrenzt auf 4-31. Der Standard 12 benötigt etwa 200ms pro Hash auf modernen CPUs; reduzieren Sie ihn auf schwacher Hardware, erhöhen Sie ihn für sicherheitsverstärkte Bereitstellungen.                                                                                                                                                                   |
| `CORS_ORIGINS`                   | No       | —                                       | Kommagetrennte Liste zusätzlicher zulässiger CORS-Ursprünge über die Standard-Localhost-Einträge hinaus. Erforderlich, wenn das Frontend auf einer Nicht-Localhost-Domain ausgeführt wird (z. B. `https://app.example.com`).                                                                                                                                                                           |
| `UPLOADS_DIR`                    | No       | `./uploads`                             | Verzeichnis für hochgeladene Dateien                                                                                                                                                                                                                                                                                                                                                                   |
| `EXPORT_FONT_DIR`                | No       | *(automatisch erkannt)*                 | Verzeichnis mit `NotoSansSC-Regular.ttf` / `NotoSansSC-Bold.ttf` für PDF-Export. Rufen Sie mit `python scripts/fetch_export_fonts.py` ab; Docker-Images bündeln es bereits. Ohne eine einbettbare TrueType-CJK-Schriftart fällt der PDF-Export auf eine nicht eingebettete CID-Schriftart mit verschlechtertem Abstand und ohne Fettdruck zurück.                                                      |
| `MAX_UPLOAD_SIZE_MB`             | No       | `50`                                    | Maximale Dateigröße für Upload in Megabyte (Backend-Erzwingung)                                                                                                                                                                                                                                                                                                                                        |
| `NEXT_PUBLIC_MAX_UPLOAD_SIZE_MB` | No       | `50`                                    | Maximale Dateigröße für Upload in der Frontend-UI. **Build-Zeit-Variable** — muss mit `MAX_UPLOAD_SIZE_MB` übereinstimmen.                                                                                                                                                                                                                                                                             |
| `MCP_SERVERS`                    | No       | —                                       | JSON-Array von MCP-Serverkonfigurationen (erfordert `uv sync --extra mcp`)                                                                                                                                                                                                                                                                                                                             |
| `ALLOW_STDIO_MCP`                | No       | `false`                                 | Stdio-MCP-Server zulassen. Setzen Sie auf `true` nur für vertrauenswürdige lokale Bereitstellungen                                                                                                                                                                                                                                                                                                     |
| `ALLOWED_STDIO_COMMANDS`         | No       | `npx,uvx,node,python,python3,deno,bun`  | Kommagetrennte Liste zulässiger Basisbefehle für Stdio-MCP-Server. Wirksam nur, wenn `ALLOW_STDIO_MCP=true`                                                                                                                                                                                                                                                                                            |
| `LOG_LEVEL`                      | No       | `INFO`                                  | Protokollierungsstufe: `DEBUG` / `INFO` / `WARNING` / `ERROR` / `CRITICAL`                                                                                                                                                                                                                                                                                                                             |
| `REDIS_URL`                      | No       | —                                       | Redis-Verbindungs-URL für Worker-übergreifendes Interrupt-Relay. **Erforderlich, wenn `WORKERS>1`** — ohne diese können Mid-Stream-Interrupt-/Inject-Anfragen einen anderen Worker treffen und stillschweigend fehlschlagen. Wird von Docker Compose automatisch konfiguriert.                                                                                                                         |
| `WORKERS`                        | No       | `1`                                     | Uvicorn-Worker-Prozesse. `1` ist sicher und benötigt keine externen Dienste. Für Multi-Worker-Produktion verwenden Sie PostgreSQL (SQLite ist Single-Writer). SQLite funktioniert für lokale Entwicklung unter leichter Last. Authentifizierung, OAuth und Dateivorgänge sind vollständig Multi-Worker-sicher (JWT-basiert). Docker Compose konfiguriert automatisch sowohl PostgreSQL als auch Redis. |

<Warning>
  **Multi-Worker-Checkliste** (`WORKERS>1`):

  * **Stoppen (Streaming abbrechen)** — funktioniert immer, keine zusätzliche Konfiguration erforderlich (Signal wird über die gleiche TCP-Verbindung übertragen).
  * **Inject (Mid-Stream-Folgeanfrage)** — **erfordert `REDIS_URL`**. Ohne Redis kann die Inject-Anfrage auf einem anderen Worker landen, der keine Kenntnis der laufenden Ausführung hat, was zu stillschweigendem Fehlschlag führt.
  * **Produktion**: verwenden Sie PostgreSQL (`DATABASE_URL`). SQLites Single-Writer-Lock kann unter gleichzeitigen Schreibvorgängen zu Konflikten führen.
  * **Lokale Entwicklung**: SQLite + Multi-Worker ist für leichte Nutzung in Ordnung; fügen Sie einfach `REDIS_URL` hinzu, wenn Sie die Inject-Funktion verwenden.
</Warning>

## Workflow Run Retention

Background cleanup task that automatically purges old workflow runs. Per-workflow overrides (configured in the workflow settings UI) take priority over these global defaults.

| Variable                              | Required | Default | Description                                                     |
| ------------------------------------- | -------- | ------- | --------------------------------------------------------------- |
| `WORKFLOW_RUN_MAX_AGE_DAYS`           | No       | `30`    | Delete workflow runs older than this many days                  |
| `WORKFLOW_RUN_MAX_PER_WORKFLOW`       | No       | `100`   | Keep at most this many runs per workflow (oldest deleted first) |
| `WORKFLOW_RUN_CLEANUP_INTERVAL_HOURS` | No       | `24`    | How often the background cleanup task runs, in hours            |

### Channel Confirmation Request Expiry

Background sweeper that marks stale pending approval requests (produced by channel hooks like `FeishuGateHook` or the Approval Playground) as expired. Ensures a click days later on a forgotten card doesn't flip agent state that has already been torn down.

| Variable                                      | Required | Default | Description                                                                |
| --------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------- |
| `CHANNEL_CONFIRMATION_TTL_MINUTES`            | No       | `1440`  | Pending confirmations older than this are auto-expired (default: 24 hours) |
| `CHANNEL_CONFIRMATION_SWEEP_INTERVAL_SECONDS` | No       | `600`   | How often the expiry sweeper runs (default: every 10 minutes)              |

## OAuth (Optional)

Wenn sowohl `CLIENT_ID` als auch `CLIENT_SECRET` für einen Anbieter gesetzt sind, zeigt die Anmeldeseite automatisch die entsprechende OAuth-Schaltfläche an.

| Variable                | Erforderlich | Standard                                      | Beschreibung                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------- | ------------ | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GITHUB_CLIENT_ID`      | Nein         | —                                             | GitHub OAuth App Client ID. Erstellen Sie diese unter [github.com/settings/developers](https://github.com/settings/developers) → OAuth Apps                                                                                                                                                                                                                          |
| `GITHUB_CLIENT_SECRET`  | Nein         | —                                             | GitHub OAuth App Client Secret                                                                                                                                                                                                                                                                                                                                       |
| `GOOGLE_CLIENT_ID`      | Nein         | —                                             | Google OAuth Client ID. Erstellen Sie diese unter [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)                                                                                                                                                                                                                     |
| `GOOGLE_CLIENT_SECRET`  | Nein         | —                                             | Google OAuth Client Secret                                                                                                                                                                                                                                                                                                                                           |
| `DISCORD_CLIENT_ID`     | Nein         | —                                             | Discord OAuth2 Client ID. Erstellen Sie diese unter [discord.com/developers](https://discord.com/developers/applications)                                                                                                                                                                                                                                            |
| `DISCORD_CLIENT_SECRET` | Nein         | —                                             | Discord OAuth2 Client Secret                                                                                                                                                                                                                                                                                                                                         |
| `FEISHU_APP_ID`         | Nein         | —                                             | Feishu (Lark) App ID. Erstellen Sie diese unter [open.feishu.cn](https://open.feishu.cn/app). Erfordert die Berechtigung `contact:user.email:readonly`                                                                                                                                                                                                               |
| `FEISHU_APP_SECRET`     | Nein         | —                                             | Feishu (Lark) App Secret                                                                                                                                                                                                                                                                                                                                             |
| `FRONTEND_URL`          | **Prod**     | `http://localhost:3000`                       | Wo der Browser nach Abschluss von OAuth landet. Muss in der Produktion gesetzt werden (z. B. `https://yourdomain.com`)                                                                                                                                                                                                                                               |
| `API_BASE_URL`          | **Prod**     | `http://localhost:8000`                       | Extern erreichbare Backend-URL, wird zum Erstellen von OAuth-Callback-URLs verwendet. Muss in der Produktion gesetzt werden                                                                                                                                                                                                                                          |
| `NEXT_PUBLIC_API_URL`   | **Prod**     | *(automatisch erkannt als `<hostname>:8000`)* | Browser-seitige API-Basis-URL für OAuth-Umleitungen. **Dies ist eine Frontend-Build-Zeit-Variable** — setzen Sie diese in `frontend/.env.local` für lokale Entwicklung oder übergeben Sie sie als Docker-Build-Argument für benutzerdefinierte Produktionsbereitstellungen. Die automatische Erkennung funktioniert für Standard-Reverse-Proxy-Setups (Port 80/443). |

> **Prod** = lokal optional (Standardwerte funktionieren), aber **erforderlich für jede Bereitstellung mit Internetzugriff**.

### OAuth-Callback-URLs zum Registrieren bei jedem Anbieter

Das Backend konstruiert Callback-URLs als: `{API_BASE_URL}/api/auth/oauth/{provider}/callback`

| Anbieter | Zu registrierende Callback-URL                           |
| -------- | -------------------------------------------------------- |
| GitHub   | `https://yourdomain.com/api/auth/oauth/github/callback`  |
| Google   | `https://yourdomain.com/api/auth/oauth/google/callback`  |
| Discord  | `https://yourdomain.com/api/auth/oauth/discord/callback` |

***

## Cloudflare Tunnel (Optional)

Leiten Sie den gesamten Datenverkehr über Cloudflares Netzwerk um, anstatt Ports direkt freizulegen. Eliminiert die Notwendigkeit für Nginx, SSL-Zertifikate und offene Firewall-Regeln. Siehe den Abschnitt [Production Deployment](/quickstart#cloudflare-tunnel) für Setupanweisungen.

<Warning>
  **Benutzer in Festlandchina**: Cloudflare Free/Pro/Business-Pläne haben keine PoPs in Festlandchina. Der Datenverkehr wird zu Overseas-Edges weitergeleitet, was häufig zu 502-Fehlern führt. Verwenden Sie dies nicht, wenn Ihre primären Benutzer in Festlandchina sind, es sei denn, Sie haben Cloudflare Enterprise mit China Network.
</Warning>

| Variable                  | Erforderlich                       | Standard | Beschreibung                                                                                                                                                                      |
| ------------------------- | ---------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLOUDFLARE_TUNNEL_TOKEN` | **Ja** (bei Verwendung von Tunnel) | —        | Token von Cloudflare Zero Trust → Networks → Tunnels → Ihr Tunnel → Configure. Beginnt mit `eyJ...`. Erforderlich durch den `cloudflared` Sidecar in `docker-compose.tunnel.yml`. |

***

## Analytics (Optional)

Alle Analytics-Anbieter sind optional. Legen Sie eine beliebige Kombination fest — alle aktiven Anbieter werden gleichzeitig geladen. Lassen Sie alle leer, um Analytics vollständig zu deaktivieren (empfohlen für lokale Entwicklung).

| Variable                           | Erforderlich | Standard                            | Beschreibung                                                                                                                                              |
| ---------------------------------- | ------------ | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_GA_MEASUREMENT_ID`    | Nein         | —                                   | Google Analytics 4 Measurement ID (z. B. `G-XXXXXXXXXX`). Erhalten Sie Ihre ID unter [analytics.google.com](https://analytics.google.com)                 |
| `NEXT_PUBLIC_UMAMI_SCRIPT_URL`     | Nein         | —                                   | Umami Analytics Script URL (z. B. `https://your-umami.com/script.js`). Selbst gehostet, datenschutzfreundliche Alternative — [umami.is](https://umami.is) |
| `NEXT_PUBLIC_UMAMI_WEBSITE_ID`     | Nein         | —                                   | Umami Website ID. Erforderlich, wenn `NEXT_PUBLIC_UMAMI_SCRIPT_URL` gesetzt ist                                                                           |
| `NEXT_PUBLIC_PLAUSIBLE_DOMAIN`     | Nein         | —                                   | Plausible Analytics Domain (z. B. `yourdomain.com`). Leichtgewichtig, datenschutzfreundlich — [plausible.io](https://plausible.io)                        |
| `NEXT_PUBLIC_PLAUSIBLE_SCRIPT_URL` | Nein         | `https://plausible.io/js/script.js` | Benutzerdefinierte Plausible Script URL für selbst gehostete Instanzen                                                                                    |

> Alle `NEXT_PUBLIC_*` Analytics-Variablen sind **Build-Zeit** — Änderungen erfordern einen Frontend-Rebuild, um wirksam zu werden.

## Stripe Billing (Optional)

Stripe powers Pro subscriptions. Leave all three variables blank to disable billing — the rest of FIM One works unchanged. **Both** `STRIPE_SECRET_KEY` **and** `STRIPE_WEBHOOK_SECRET` must be set together; partial config raises an error at first use.

| Variable                    | Required | Default                                      | Description                                                                                                                                                                                                                      |
| --------------------------- | -------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STRIPE_SECRET_KEY`         | No       | —                                            | Stripe API secret key. Must start with `sk_test_` / `sk_live_` (full access) or `rk_test_` / `rk_live_` (restricted key). Get yours from the Stripe Dashboard → Developers → API keys. Never commit a `sk_live_*` key to source. |
| `STRIPE_WEBHOOK_SECRET`     | No       | —                                            | Stripe webhook signing secret (`whsec_*`). Created when you register the webhook endpoint in Stripe Dashboard → Developers → Webhooks → Add endpoint. Required to verify inbound webhook payloads.                               |
| `STRIPE_BILLING_RETURN_URL` | No       | `http://localhost:3000/settings?tab=billing` | URL Stripe redirects users to after Checkout / Customer Portal sessions. Set this to your production billing settings page (e.g. `https://your-domain.com/settings?tab=billing`).                                                |
