# ============================================
# CyberStrikeAI 配置文件
# ============================================
# 本配置文件支持通过 Web 界面进行可视化配置
# 点击右上角"设置"按钮即可修改配置
# ============================================

# ============================================
# 系统设置
# ============================================

# 前端显示的版本号（可选，不填则显示默认版本）
version: "v1.7.1"
# 服务器配置
server:
  host: 0.0.0.0 # 监听地址，0.0.0.0 表示监听所有网络接口
  port: 8080 # 服务端口；未启用 TLS 时为 http://localhost:8080
  # --- 可选：HTTPS + HTTP/2（缓解浏览器对同源 HTTP/1.1 的并发连接数限制，多路 Deep 流式更稳）---
  # 启用 TLS 的条件（满足其一即可）：tls_enabled: true，或 tls_auto_self_sign: true，或同时配置了 tls_cert_path + tls_key_path。
  # 启用后请用 https://127.0.0.1:<本端口>/ 访问；若仍用 http:// 访问同端口，将自动 308 跳转到 HTTPS（可用 tls_http_redirect: false 关闭）。
  tls_enabled: true
  # 启用 HTTPS 时，明文 HTTP 是否自动跳转到 HTTPS（默认 true；同端口嗅探 TLS/HTTP 后分流）
  # tls_http_redirect: true
  # 方式 A（推荐生产）：PEM 证书与私钥路径
  # tls_cert_path: /path/to/fullchain.pem
  # tls_key_path: /path/to/privkey.pem
  # 方式 B（仅本地/测试）：无证书文件时内存自签（浏览器会提示不受信任；SAN 含 localhost / 127.0.0.1）
  tls_auto_self_sign: true
# 认证配置
auth:
  session_duration_hours: 12 # 登录有效期（小时），超时后需重新登录
# 日志配置
log:
  level: info # 日志级别: debug(调试), info(信息), warn(警告), error(错误)
  output: stdout # 日志输出位置: stdout(标准输出), stderr(标准错误), 或文件路径
# 平台操作审计（系统设置 -> 日志审计；不记录对话正文与每次工具调用）
audit:
  enabled: true
  retention_days: 15 # 0 表示不自动清理
  max_detail_bytes: 8192
  auth_failure_cooldown_seconds: 60 # 同一 IP 登录/改密失败审计最短间隔（秒）；未配置时默认 60；-1 关闭节流
# MCP 状态监控执行记录保留（tool_executions 表）
monitor:
  retention_days: 90 # 省略时默认 90；0 表示不自动清理
# ============================================
# 对话相关配置
# ============================================

# AI 模型配置（支持 OpenAI 兼容 API）
# 必填项：api_key, base_url, model 必须填写才能正常运行
# 支持的 API 服务商：
#   - OpenAI: https://api.openai.com/v1
#   - DeepSeek: https://api.deepseek.com/v1
#   - 其他兼容 OpenAI 协议的 API
# 常用模型: gpt-4, gpt-3.5-turbo, deepseek-chat, claude-3-opus 等
# provider: 可选值 openai(默认) | claude(自动桥接到 Anthropic Claude Messages API)
openai:
  provider: openai # API 提供商: openai(默认,兼容OpenAI协议) | claude(自动桥接到Anthropic Claude Messages API)
  base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 # API 基础 URL（必填）
  api_key: sk-xxxxxxx # API 密钥（必填）
  model: qwen3-max # 模型名称（必填）
  max_total_tokens: 120000 # LLM 相关上下文的最大 Token 数限制（内存压缩和攻击链构建会共用此配置）
  # Eino 路径模型推理：DeepSeek/OpenAI 为 thinking / reasoning_effort；Claude 4.6+ 为 adaptive + output_config.effort（仅显式配置 effort 时下发）；3.7 为 enabled+budget_tokens:10000（文档示例），effort 不映射，自定义预算用 extra_request_fields
  reasoning:
    mode: on # auto | on | off；off 时不附加任何推理扩展字段
    effort: high # low | medium | high | max | xhigh（最高档：OpenAI 常用 xhigh，部分网关用 max，原样下发）；空表示不指定
    allow_client_reasoning: true # false 时忽略对话请求体 reasoning，仅以下方为准
    profile: openai_compat # auto | deepseek_compat | openai_compat | output_config_effort
    # extra_request_fields: {} # 可选：管理员自定义根级 JSON 片段（高级）
# 视觉分析（analyze_image MCP 工具；图片仅在单次 VL 调用中出现，Agent 上下文只保留文字摘要）
vision:
  enabled: false # true 且 model 非空时注册 analyze_image
  model: qwen-vl # VL 模型名（enabled 时必填）
  api_key: "" # 留空则复用 openai.api_key
  base_url: "" # 留空则复用 openai.base_url
  provider: # 留空则复用 openai.provider（openai | claude）
  max_image_bytes: 5242880 # 原始文件上限（字节），默认 5MB
  max_dimension: 2048 # 长边缩放像素
  jpeg_quality: 82
  max_payload_bytes: 524288 # 编码后送 VL API 上限，默认 512KB
  skip_preprocess_below_bytes: 2097152 # 低于 2MB 且长边<=max_dimension 且<=max_payload 时原图直传；0=始终压缩
  detail: auto # low | high | auto（Eino ImageURLDetail）
  timeout_seconds: 60
# ============================================
# 信息收集（FOFA）配置（可选）
# ============================================
# 用于「信息收集」页面调用 FOFA API（后端代理，避免前端暴露 key）
# 也可通过环境变量配置：FOFA_EMAIL / FOFA_API_KEY（优先级更高）
fofa:
  base_url: https://fofa.info/api/v1/search/all # 可选，留空则使用默认
  email: "" # FOFA 账号邮箱（可选，建议在系统设置中填写）
  api_key: "" # FOFA API Key（可选，建议在系统设置中填写）
# Agent 配置
# 达到最大迭代次数时，AI 会自动总结测试结果
agent:
  max_iterations: 12000 # 全局最大迭代次数（单代理 / Deep / Supervisor / Plan-Execute 主执行器 / 子代理均沿用；agents/*.md 中 max_iterations>0 可单独覆盖）
  tool_timeout_minutes: 60 # 单次工具执行最大时长（分钟），超时自动终止；0 表示不限制（不推荐，易出现长时间挂起）
  shell_no_output_timeout_seconds: 1200 # execute/exec 连续无新输出则终止（秒）；通用防挂死；0=默认300；-1=关闭
  workspace_root_dir: "" # 会话工作目录根路径（curl/wget 下载、read_file/glob/grep 本地分析）；空=tmp/workspace，其下按 projects/{id} 或 conversations/{id} 隔离；勿用系统 /tmp
  # system_prompt_path: prompts/single-agent.md # 可选：单代理系统提示文件（相对本配置文件所在目录）；非空且可读时替换内置提示

  system_prompt_path: ""
# 人机协同（HITL）全局白名单：此处列出的工具始终免审批，与对话页「白名单工具（免审批，逗号分隔）」合并为并集；侧栏「应用」可合并写入本列表并立即生效。
# 非白名单工具在审批方=审计 Agent 时，按会话 HITL 模式选用提示词：
#   approval → audit_agent_prompt
#   review_edit → audit_agent_prompt_review_edit（可改参后放行）
hitl:
  # 全局默认审批方：human=人工审批，audit_agent=审计 Agent；未选会话时切换会写入本项，重启后仍生效
  default_reviewer: human
  # 审计 Agent 专用模型；字段留空则复用上方 openai 配置。建议 model 填小模型，用于降低审批成本。
  audit_model:
    provider: "" # openai / claude；留空跟随 openai.provider
    base_url: "" # 留空跟随 openai.base_url
    api_key: "" # 留空跟随 openai.api_key
    model: "" # 留空跟随 openai.model，例如可填 gpt-4o-mini / qwen-turbo / deepseek-chat
  # 已决策审计日志保留天数（与 MCP 监控一致；省略默认 90；0 表示不自动清理）
  retention_days: 90
  # 按你环境里的真实工具名增删（与侧栏一致、小写不敏感）；不需要全局免审批可改为 []
  tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
  # audit_agent_prompt: |  # 审批模式；留空使用内置默认，可在「人机协同」页编辑
  # audit_agent_prompt_review_edit: |  # 审查编辑模式；留空使用内置默认

  audit_agent_prompt: |-
    你是 CyberStrikeAI 人机协同审计 Agent。审查 Agent 即将执行的工具调用是否会对系统造成实质性损害。

    你会收到 JSON，包含 hitlMode、toolName、arguments/argumentsObj、userMessage、thinking、reasoningChain、planning 等字段。

    裁决基调（默认放行）：
    - 常规、低风险的渗透测试操作 → approve（如信息收集、端口/服务扫描、目录枚举、只读查询、无害探测命令）
    - 与用户授权、当前任务目标一致，且未见明确高危迹象 → approve
    - 仅在「可能对系统造成实质影响」时 → reject

    必须 reject 的高危情形（示例，非穷举）：
    - 删库、清表、批量删除数据、格式化磁盘、不可逆破坏
    - 修改/重置密码、创建或篡改管理员账号、持久化后门、开机自启
    - 向生产环境写入恶意载荷、勒索加密、停止关键服务、修改系统核心配置
    - 明显越权：与任务/授权目标无关的破坏性操作

    不应单独作为 reject 理由的情形：
    - 常规 nmap/curl/grep/读文件/枚举类命令本身
    - 参数略显宽泛但无明确破坏意图
    - 仅因「信息不足」——若无上述高危迹象，应 approve 并可在 comment 中提示注意点

    仅输出一行 JSON，不要 markdown 代码块：
    {"decision":"approve"|"reject","comment":"简要理由"}
  audit_agent_prompt_review_edit: |-
    你是 CyberStrikeAI 人机协同审计 Agent。审查 Agent 即将执行的工具调用是否会对系统造成实质性损害。

    你会收到 JSON，包含 hitlMode、toolName、arguments/argumentsObj、userMessage、thinking、reasoningChain、planning 等字段。

    裁决基调（默认放行）：
    - 常规、低风险的渗透测试操作 → approve（如信息收集、端口/服务扫描、目录枚举、只读查询、无害探测命令）
    - 与用户授权、当前任务目标一致，且未见明确高危迹象 → approve
    - 仅在「可能对系统造成实质影响」时 → reject；参数可安全收窄时优先 approve + editedArguments

    必须 reject 的高危情形（示例，非穷举）：
    - 删库、清表、批量删除数据、格式化磁盘、不可逆破坏
    - 修改/重置密码、创建或篡改管理员账号、持久化后门、开机自启
    - 向生产环境写入恶意载荷、勒索加密、停止关键服务、修改系统核心配置
    - 明显越权：与任务/授权目标无关的破坏性操作

    不应单独作为 reject 理由的情形：
    - 常规 nmap/curl/grep/读文件/枚举类命令本身
    - 参数略显宽泛但无明确破坏意图（应收窄参数后 approve）
    - 仅因「信息不足」——若无上述高危迹象，应 approve 并可在 comment 中提示注意点

    仅输出一行 JSON，不要 markdown 代码块：
    {"decision":"approve"|"reject","comment":"简要理由","editedArguments":{...}}

    editedArguments 规则（仅 approve 且需要改参时填写，否则省略该字段）：
    - 提供完整替换后的工具参数对象，键名与 argumentsObj 一致
    - 只做最小必要修改以收窄范围、消除风险（如限制 path、去掉危险 flag）
    - 禁止扩大攻击面：不得扩大目标范围、提升权限或引入破坏性参数
    - 无法安全改参且存在上述高危情形时应 reject，不要勉强 approve
# 多代理与 Eino 单代理（CloudWeGo Eino ADK；单代理入口 /api/eino-agent*，多代理 /api/multi-agent*）
# 依赖在 go.mod 中拉取；若下载失败可设置: go env -w GOPROXY=https://goproxy.cn,direct
# Deep / Plan-Execute / Supervisor 由对话页与 WebShell 所选模式在请求体 orchestration 中指定；机器人按 robot_default_agent_mode
multi_agent:
  enabled: true
  robot_default_agent_mode: eino_single # 企微/钉钉/飞书机器人默认：eino_single | deep | plan_execute | supervisor
  batch_use_multi_agent: false # true 时「批量任务」队列中每个子任务也走 Eino 多代理（成本更高）
  # plan_execute 专用：execute↔replan 外层循环上限，0 表示 Eino 默认 10。主/子代理 ReAct 轮次见 agent.max_iterations。
  plan_execute_loop_max_iterations: 0
  sub_agent_user_context_max_runes: 0 # 子代理 task 描述中注入用户原文；0=不截断（默认），>0=总字符上限，负数=禁用
  without_general_sub_agent: false # false 时保留 Deep 内置 general-purpose 子代理
  without_write_todos: false
  orchestrator_instruction: "" # Deep 主代理：agents/orchestrator.md（或 kind: orchestrator 的单个 .md）正文优先；正文为空时用此处；皆空则 Eino 默认
  orchestrator_instruction_plan_execute: "" # plan_execute 主代理：agents/orchestrator-plan-execute.md 正文优先；正文为空时用此处；皆空则用内置 plan_execute 提示（不使用 Deep 的 orchestrator_instruction）
  orchestrator_instruction_supervisor: "" # supervisor 主代理：agents/orchestrator-supervisor.md 正文优先；正文为空时用此处；皆空则用内置 supervisor 提示（transfer/exit 说明仍由运行追加；不使用 Deep 的 orchestrator_instruction）
  # Eino 官方 Skills：渐进式披露 + 可选本机文件/Shell（eino-ext local backend）。Skills 目录见 skills_dir。
  eino_skills:
    disable: false # true：不注册 skill 渐进式披露中间件，也不挂本机 FS/Shell 工具；false：按下方开关加载
    filesystem_tools: true # true：注册 read_file/glob/grep/write/edit/execute（授权环境慎用）；false：仅 skill，不暴露本机读写与 Shell
    skill_tool_name: skill # 模型侧可调用的「加载技能」工具名，一般保持 skill；与技能包文档中的调用名一致即可
  # Eino ADK 中间件与 Deep/Supervisor/plan_execute Executor 调参（结构体见 internal/config/config.go → MultiAgentEinoMiddlewareConfig）
  # plan_execute：下列 patch/reduction/tool_search/plantask 等同样作用于 Executor（经 ExecPreMiddlewares）；Planner/Replanner 不挂 MCP 前置中间件。
  eino_middleware:
    patch_tool_calls: true # true：修补历史中无 tool_result 的悬空 tool_call（流式中断/重试后更稳）；false：关闭；字段省略时默认等同 true
    tool_search_enable: true # true：工具数 ≥ min 时启用 tool_search，仅前 N 个工具常驻，其余按正则按需解锁，省 token、减误选；false：全量工具进上下文
    tool_search_min_tools: 20 # 达到该数量才启用 tool_search（避免工具很少时多此一举）；与 always_visible 配合使用
    tool_search_always_visible: 12 # 始终直接暴露给模型的工具个数（顺序与角色工具列表一致）；其余工具进入动态池，需 tool_search 解锁
    tool_search_always_visible_tools: [read_file, glob, grep, analyze_image, write_file, edit_file, execute, task, transfer_to_agent, exit, write_todos, skill, tool_search, TaskCreate, TaskGet, TaskUpdate, TaskList, record_vulnerability, list_vulnerabilities, get_vulnerability, list_knowledge_risk_types, search_knowledge_base, webshell_exec, webshell_file_list, webshell_file_read, webshell_file_write, manage_webshell_list, manage_webshell_add, manage_webshell_update, manage_webshell_delete, manage_webshell_test, batch_task_list, batch_task_get, batch_task_start, batch_task_rerun, batch_task_pause, batch_task_update_metadata, batch_task_update_schedule, batch_task_schedule_enabled, batch_task_update_task, batch_task_remove_task, batch_task_delete, batch_task_create, batch_task_add_task, http-framework-test, exec] # 后端内置常驻工具白名单（优先于 always_visible 数量策略）
    plantask_enable: true # P0：主代理挂载 TaskCreate/Get/Update/List 结构化任务板；需 eino_skills 可用且 skills_dir 存在
    plantask_rel_dir: .eino/plantask # 任务文件相对 skills_dir，按会话分子目录：skills/.eino/plantask/<conversationId>/
    reduction_enable: true # true：大工具输出截断/落盘以控上下文；后端会独立创建，不依赖 eino_skills 是否启用
    reduction_max_length_for_trunc: 50000 # 单条工具结果超过该字符数（bytes）时截断并落盘（由 reduction 中间件处理）
    reduction_max_tokens_for_clear: 60000 # 历史工具结果清理阈值（tokens），应低于 max_total_tokens * summarization_trigger_ratio
    reduction_root_dir: "" # 非空：截断/清理内容落盘根路径；空：使用系统临时目录下按会话隔离的默认路径
    reduction_clear_exclude: [] # 不参与「清理阶段」的工具名额外列表（会与 task/transfer/exit 等内置排除项合并）；需要时用 YAML 列表填写
    reduction_sub_agents: true # true：子代理也挂 reduction；false：仅编排主代理使用 reduction
    summarization_trigger_ratio: 0.8 # summarization 触发比例（max_total_tokens * ratio），建议 0.75~0.85
    summarization_output_reserve_tokens: 8192 # 摘要模型输出预留 token；摘要输入预算 = 触发阈值 - 该值
    summarization_emit_internal_events: true # true：发出 summarization 内部事件（便于诊断）
    summarization_user_intent_ledger_max_runes: 96000 # 压缩后注入模型上下文的「原始用户输入与约束账本」总字符上限；DB 原始消息不裁剪
    summarization_user_intent_ledger_entry_max_runes: 16000 # 账本中单条用户消息的字符上限；超出仅裁剪模型可见账本，不影响 DB 原文
    latest_user_message_max_runes: 48000 # 本轮最新 user 进入模型上下文的字符上限；超出时全文落盘，仅注入 head/tail 预览
    latest_user_message_head_runes: 24000 # 超长本轮 user 的头部预览字符数
    latest_user_message_tail_runes: 24000 # 超长本轮 user 的尾部预览字符数
    plan_execute_user_input_budget_ratio: 0.35 # plan_execute 中 userInput 预算比例（planner/replanner/executor 共用）
    plan_execute_executed_steps_budget_ratio: 0.2 # plan_execute 中 executed_steps 预算比例
    plan_execute_max_step_result_runes: 4000 # plan_execute 每步结果最大字符数（超出截断）
    plan_execute_keep_last_steps: 8 # plan_execute 仅保留最近 N 步正文，早期步骤折叠为标题
    checkpoint_dir: data/eino-checkpoints # P0：进程崩溃/OOM 后同会话自动 ADK Resume；正常结束会删 .ckpt；与「中断并继续」(last_react_*) 是两套机制
    run_retry_max_attempts: 0 # 429/5xx/网络抖动时可退避重试次数（run loop + summarization 共用 isEinoTransientRunError）；0=默认 10
    run_retry_max_backoff_sec: 0 # 单次退避上限秒数；0=默认 30
    empty_response_continue_max_attempts: 0 # Run 成功但未捕获助手正文（含流式中断）时 Handler 退避续跑次数；0=默认 5
    deep_output_key: final_answer # P0：Eino session 写入最终助手结论（框架内部；Deep/Supervisor 主/eino_single）
    deep_model_retry_max_retries: 0 # 已废弃，请用 run_retry_max_attempts；保留字段仅为兼容旧配置
    task_tool_description_prefix: "" # 非空：仅 Deep 的 task 工具使用自定义描述前缀，运行时会拼接子代理名称；空则走 Eino 默认生成逻辑
  # Eino callbacks + OpenTelemetry：框架级 span（与 Zap 对齐）；默认不向终端用户 UI 推 eino_trace_*（见 sse_trace_to_client）
  eino_callbacks:
    enabled: true
    # log_only=仅 Zap+OTel（推荐默认）| sse/full=才启用流式回调副本关闭等（full 含 stream hooks）
    mode: log_only
    sse_trace_to_client: false # true：且 mode 为 sse/full 时，向前端时间线推送 eino_trace_*（排障/内网演示用）
    max_input_summary_runes: 400
    max_output_summary_runes: 400
    zap_verbose: false # true：Debug 附带 input/output 摘要
    otel:
      enabled: true
      service_name: cyberstrike-ai
      exporter: stdout # none | stdout（开发/本机）| otlphttp（生产接 Collector）
      otlp_endpoint: localhost:4318 # otlphttp 时使用，host:port，路径固定 /v1/traces
      sample_ratio: 1.0 # 0~1，ParentBased+TraceIDRatio
# 数据库配置
database:
  path: data/conversations.db # SQLite 数据库文件路径，用于存储对话历史和消息
  knowledge_db_path: data/knowledge.db # 知识库数据库文件路径（可选，为空则使用会话数据库），用于存储知识库项和向量嵌入，可独立复制和复用
# ============================================
# 任务管理相关配置
# ============================================
# （配置项已包含在对话相关配置中）

# ============================================
# 漏洞管理相关配置
# ============================================

# 安全工具配置
# 系统会从该目录加载所有 .yaml 格式的工具配置文件
# 推荐方式：在 tools/ 目录下为每个工具创建独立的配置文件
security:
  tools_dir: tools # 工具配置文件目录（相对于配置文件所在目录）
  # 工具描述模式：加载 tools 下工具时，暴露给 AI/API 使用的描述来源
  #   short - 优先使用 short_description（简短描述，省 token），为空时用 description
  #   full  - 使用 description（详细描述）
  tool_description_mode: full
# ============================================
# MCP 相关配置
# ============================================

# MCP 协议配置
# MCP (Model Context Protocol) 用于工具注册和调用
mcp:
  enabled: false # 是否启用 MCP 服务器（http模式）
  host: 127.0.0.1 # MCP 服务器监听地址；需要远程访问时再显式修改并配置网络层访问控制
  port: 8081 # MCP 服务器端口
  auth_header: "X-MCP-Token" # 可选的全局服务凭证 Header；普通调用请使用用户 Authorization: Bearer Token
  auth_header_value: "" # 全局服务凭证值，仅 allow_global_access=true 时生效
  allow_global_access: false # 高风险兼容模式：静态密钥映射为全局服务身份；默认请使用用户 Bearer Token
# 外部 MCP 配置
external_mcp:
  servers: {}
# 内置 C2：本机仅做对话/知识库时可设为 false，不启动监听器、不注册 C2 MCP 工具；省略本段时默认启用
c2:
  enabled: true
# ============================================
# 知识库相关配置
# ============================================
knowledge:
  enabled: false # 是否启用知识检索功能
  base_path: knowledge_base # 知识库目录路径（相对于配置文件所在目录）
  embedding:
    provider: openai # 嵌入模型提供商（目前仅支持openai）
    model: text-embedding-v4 # 嵌入模型名称
    base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 # 留空则使用OpenAI配置的base_url
    api_key: sk-xxxxxxx # 留空则使用OpenAI配置的api_key
  retrieval:
    top_k: 5 # 检索返回的Top-K结果数量
    similarity_threshold: 0.4 # 余弦相似度阈值（0-1），低于此值的结果将被过滤
    # Eino MultiQuery：LLM 改写查询后多路向量检索再融合（始终启用）
    multi_query:
      max_queries: 4 # 改写变体上限（含语义覆盖）；建议 3~4
    # 精排（始终启用）：dashscope 用 gte-rerank；其他 OpenAI 兼容端点走 /v1/rerank
    rerank:
      provider: "" # 空=按 base_url 推断：dashscope | cohere
      model: "" # 空=dashscope→gte-rerank，cohere→rerank-multilingual-v3.0
      base_url: "" # 留空则用 embedding / openai 的 base_url
      api_key: "" # 留空则用 embedding / openai 的 api_key
    post_retrieve:
      prefetch_top_k: 20 # 每条 MultiQuery 变体的向量候选数；0=内置 max(top_k*4,20)
      max_context_chars: 0 # 0 不限制；否则返回的正文总 Unicode 字符上限（整段 chunk）
      max_context_tokens: 0 # 0 不限制；tiktoken 总 token 上限
    sub_index_filter: ""
  # ============================================
  # 索引配置（用于解决 API 限制问题）
  # ============================================
  indexing:
    # 分块配置
    chunk_size: 512 # 每个块的最大 token 数（默认 512），长文本会被分割成多个块
    chunk_overlap: 50 # 块之间的重叠 token 数（默认 50），保持上下文连贯性
    max_chunks_per_item: 0 # 单个知识项的最大块数量（0 表示不限制），防止单个文件消耗过多 API 配额
    # 速率限制配置（解决 429 错误）
    max_rpm: 0 # 每分钟最大请求数（默认 0 表示不限制），如 OpenAI 默认 200 RPM
    rate_limit_delay_ms: 300 # 请求间隔毫秒数（默认 300），用于避免 API 速率限制，设为 0 不限制
    # 建议值：200 次/分钟≈300ms, 100 次/分钟≈600ms

    # 重试配置
    max_retries: 3 # 最大重试次数（默认 3），遇到速率限制或服务器错误时自动重试
    retry_delay_ms: 1000 # 重试间隔毫秒数（默认 1000），每次重试会递增延迟
    # 分块策略（Eino）：markdown_then_recursive = 先按 Markdown 标题切再递归；recursive = 仅递归切分。留空时程序内默认 markdown_then_recursive
    chunk_strategy: markdown_then_recursive
    # 嵌入 HTTP 请求超时（秒）。0 表示使用内置默认（一般为 120），与向量化 API 客户端一致
    request_timeout_seconds: 120
    # true：索引时优先用知识项 file_path 指向的磁盘文件内容（Eino FileLoader）；false：用数据库里存的正文。读盘失败会回退 DB
    prefer_source_file: false
    # 单次嵌入 API 请求的文本条数上限（索引写入按此分批）。须 ≤ 服务商限制（如部分兼容接口最多 10）；过大易 400
    batch_size: 10
    # Eino indexer.WithSubIndexes：逻辑分区标签列表，会写入向量表 sub_indexes，检索可用 sub_index_filter 过滤；无需求可 []
    sub_indexes: []
# ============================================
# 机器人配置（企业微信、钉钉、飞书）
# ============================================
# 用于在手机端通过企业微信/钉钉/飞书与 CyberStrikeAI 对话，无需部署在服务器上也可使用
# 在系统设置 -> 机器人设置 中可配置
robots:
  wechat: # 微信 iLink（个人微信 ClawBot，扫码绑定）
    enabled: false
    # 鉴权默认 user_binding；专用机器人可改 service_account，并必须限制真实发送者
    auth:
      mode: user_binding # user_binding | service_account
      # service_user_id: "admin 或专用服务账号的 RBAC user ID"
      # allowed_external_users: ["t:tenant|u:sender"]
    bot_token: ""
    ilink_bot_id: ""
    ilink_user_id: ""
    base_url: https://ilinkai.weixin.qq.com
    bot_type: "3"
    bot_agent: CyberStrikeAI/1.0
  wecom: # 企业微信
    enabled: false
    auth:
      mode: user_binding
    token: ""
    encoding_aes_key: ""
    corp_id: ""
    secret: ""
    agent_id: 0
  dingtalk: # 钉钉
    enabled: false
    auth:
      mode: user_binding
    client_id: ""
    client_secret: ""
    allow_conversation_id_fallback: false
  lark: # 飞书
    enabled: false
    auth:
      mode: user_binding
    app_id: ""
    app_secret: ""
    verify_token: ""
    allow_chat_id_fallback: false
  telegram: # Telegram
    enabled: false
    auth:
      mode: user_binding
    bot_token: ""
    bot_username: ""
    allow_group_messages: false
  slack: # Slack
    enabled: false
    auth:
      mode: user_binding
    bot_token: ""
    app_token: ""
  discord: # Discord
    enabled: false
    auth:
      mode: user_binding
    bot_token: ""
    allow_guild_messages: false
  qq: # QQ 机器人
    enabled: false
    auth:
      mode: user_binding
    app_id: ""
    client_secret: ""
    sandbox: true
# ============================================
# Skills 相关配置
# ============================================

# 技能包目录：每个子目录仅标准 SKILL.md（Agent Skills：front matter 仅 name、description）+ 可选附属文件；无 SKILL.yaml
# 示例：skills/cyberstrike-eino-demo/
skills_dir: skills # Skills配置文件目录（相对于配置文件所在目录）
# ============================================
# 多代理子 Agent（Markdown，唯一维护处）
# ============================================
# 每个 .md：YAML front matter（name / id / description / tools / bind_role / 可选 max_iterations>0 覆盖全局 / 可选 kind: orchestrator）+ 正文为系统提示词
# 主代理：固定文件名 orchestrator.md，或任意文件名 + front matter kind: orchestrator（全目录仅允许一个）；主代理不参与 task 子代理列表
# 高级用法：仍可在 multi_agent 块内写 sub_agents，会与本文目录合并且同 id 时 YAML 可被 .md 覆盖
agents_dir: agents
# ============================================
# 角色相关配置
# ============================================

# 系统会从该目录加载所有 .yaml 格式的角色配置文件
# 每个角色应创建独立的配置文件，例如：roles/CTF.yaml, roles/默认.yaml 等
roles_dir: roles # 角色配置文件目录（相对于配置文件所在目录）
# ============================================
# 项目管理与事实黑板
# ============================================
project:
  enabled: true
  # default_project_id: "" # 可选：机器人/批量任务创建对话时的默认项目 ID
  fact_index_max_runes: 65000
  # 事实关系速览段预算（从索引总预算中预留）
  fact_index_path_max_runes: 10000
  fact_summary_max_runes: 24000
  default_inject_deprecated: false
