server:
  host: 0.0.0.0
  port: 18001
  workers: 1
  rate_limit: 60
llm:
  providers:
    bailian-coding:
      type: openai
      base_url: https://coding.dashscope.aliyuncs.com/v1
      api_key: "${DASHSCOPE_API_KEY}"
      models:
        qwen3.7-plus: {alias: default}
        qwen3-coder-plus: {alias: coding}
        qwen3-max-2026-01-23: {alias: powerful}
        qwen-turbo: {alias: fast}
    deepseek:
      type: openai
      base_url: https://api.deepseek.com/v1
      api_key: "${DEEPSEEK_API_KEY}"
      models:
        deepseek-chat: {alias: chat}
        deepseek-reasoner: {alias: reasoning}
  model_aliases:
    default: bailian-coding/qwen3.7-plus
    fast: bailian-coding/qwen-turbo
    powerful: bailian-coding/qwen3-max-2026-01-23
    coding: bailian-coding/qwen3-coder-plus
    chat: deepseek/deepseek-chat
    reasoning: deepseek/deepseek-reasoner
  # G4/U1: Auxiliary model for cost-sensitive tasks (summarization).
  # When set, ContextCompressor tries this alias first, falling back to
  # the main model on failure or empty content. Commented to preserve
  # default behavior — uncomment to enable.
  # auxiliary_model: fast
# G9/U4: Rollback configuration. Drives RollbackExecutor subprocess timeout
# for PlanPhase.validation_command / PlanPhase.rollback_command. Per-phase
# opt-in (KTD6) — when PlanPhase.rollback_command is unset, no rollback runs.
# Canonical rollback pattern: `git checkout <specific_files>` (file-scoped,
# not `git checkout .` which would wipe unrelated changes).
rollback:
  default_timeout: 30.0
# G7/U3: Three-tier fallback chain at chat REST send_message.
# main → Recovery (ReflexionEngine retry) → Emergency (rule-based classifier).
# Wired only at chat REST path (KTD5); CLI / ReWOO / Reflexion internal
# ReAct calls bypass the chain (no recursive loop).
fallback_chain:
  enabled: true
  recovery:
    enabled: true
    max_retries: 1          # ReflexionEngine max_reflections override
  emergency:
    enabled: true
# G6/U2: PLAN_EXEC phase policy — SOLO four-stage state machine.
# When `enabled: true`, chat WebSocket PLAN_EXEC requests build a PhasePolicy
# (Planning → Building → Verification → Delivery) and enforce per-step tool
# whitelists (R24). Transitions are LLM-driven via AdvancePhaseTool; set
# `auto_advance_after_steps` to auto-advance as a safety net (KTD6).
# Commented to preserve default behavior — uncomment to enable.
# plan_exec:
#   enabled: true
#   auto_advance_after_steps: 5    # optional, default = manual (LLM calls advance_phase)
#   start_phase: planning          # optional, default = planning
#   whitelist_override:            # optional, merges with default (override wins)
#     planning: [search, read_file, shell]
#     building: [write_file, shell, read_file]
# G10/U5: Use Redis for bus / session / task_store when REDIS_URL is set.
# Falls back to in-memory when REDIS_URL is unset (development fallback).
# The local dev environment runs pms-redis on 127.0.0.1:6379 (see .env.dev).
# Tests run in-memory for isolation; production / staging should use Redis.
session:
  backend: ${AGENTKIT_SESSION_BACKEND:-memory}
bus:
  backend: ${AGENTKIT_BUS_BACKEND:-memory}
  redis_url: ${REDIS_URL:-redis://127.0.0.1:6379/0}
task_store:
  backend: ${AGENTKIT_TASK_STORE_BACKEND:-memory}
skills: {auto_discover: true, paths: ["./configs/skills"]}
experts: {paths: ["./configs/experts"]}
board: {max_rounds: 5, default_template: private_board, parallel_speech: true, history_compression_threshold: 20}
logging: {level: INFO, format: text}
router: {classifier: heuristic, auction_enabled: false}
# OTel 可观测性 — 默认注释（OTel 为可选依赖，未安装时 telemetry/metrics.py 返回 NoOp）。
# 启用：pip install opentelemetry-sdk opentelemetry-exporter-otlp，取消注释并指向 collector。
# 未配置时所有指标（请求量/延迟/token 消耗）静默丢弃，形成监控盲区。
# telemetry:
#   otlp_endpoint: http://localhost:4317  # OTLP gRPC 端点
#   service_name: fischer-agentkit
