server:
  port: 2438

rag:
  ai-bridge:
    enabled: ${RAG_AI_BRIDGE_ENABLED:false}
    timeout: ${RAG_AI_BRIDGE_TIMEOUT:300s}
    # Python 子进程管理（由 Java 启动并注入 LLM 环境变量，LLM 配置统一从 spring.ai.openai.* 读取）
    host: ${RAG_AI_BRIDGE_HOST:127.0.0.1}
    port: ${RAG_AI_BRIDGE_PORT:18733}
    python-path: ${RAG_AI_BRIDGE_PYTHON_PATH:python}
    script-path: ${RAG_AI_BRIDGE_SCRIPT_PATH:rag-ai-bridge/server.py}
    startup-timeout: ${RAG_AI_BRIDGE_STARTUP_TIMEOUT:60}
    health-check-interval: ${RAG_AI_BRIDGE_HEALTH_CHECK_INTERVAL:60}

skill:
  # Skill 文件存放目录，请修改为你的实际路径
  # 该目录下的每个子目录被视为一个 Skill，子目录内应包含 SKILL.md
  base-path: ${SKILL_BASE_PATH:./uploads/skills}

# JSON 文件存储目录（配置类数据：ai_model / tags / categories / workflows）
app:
  json-store-dir: ${JSON_STORE_DIR:./data/json}

  # ========== 错误模式嗅探（智能体节点失败兜底识别） ==========
  # 启动时若数据文件为空，自动写入以下内置模式；用户自定义后不会被覆盖。
  # 通过"重置为默认"可清空自定义 + 重新启用全部内置模式。
  # pattern 字段：子串匹配、大小写不敏感；建议保持粒度适中，过短易误报。
  error-pattern:
    builtin:
      - name: LLM SDK 重试耗尽
        pattern: API call failed after
        description: OpenAI SDK 重试耗尽仍未成功，通常是限流或下游故障
      - name: HTTP 4xx 客户端错误
        pattern: HTTP 4
        description: LLM 服务返回 4xx（含 429 限流、401 鉴权、400 参数等）
      - name: HTTP 5xx 服务端错误
        pattern: HTTP 5
        description: LLM 服务返回 5xx，服务端临时故障
      - name: Rate Limit（英文）
        pattern: rate limit
        description: OpenAI 兼容服务的标准限流错误
      - name: OpenAI 配额耗尽
        pattern: insufficient_quota
        description: OpenAI 标准配额耗尽错误码
      - name: 额度 / 配额
        pattern: quota
        description: 额度耗尽类错误（中英文 quota 关键词）
      - name: OpenAI 鉴权失败
        pattern: invalid_api_key
        description: OpenAI 标准鉴权失败错误码
      - name: 认证失败（英文）
        pattern: invalid api key
        description: API Key 无效或被吊销
      - name: 认证失败（中文）
        pattern: 无效的 api
        description: 中文鉴权失败描述（兼容智谱等中文错误消息）
      - name: 上下文超限（英文）
        pattern: context_length_exceeded
        description: 输入超过模型上下文窗口
      - name: 上下文超限（中文）
        pattern: 上下文长度
        description: 中文上下文超限描述
      - name: 模型不存在
        pattern: model_not_found
        description: 指定的模型标识不存在或无权访问
      - name: OpenAI 服务端错误
        pattern: server_error
        description: OpenAI 标准 5xx 错误码
      - name: Anthropic 过载
        pattern: overloaded_error
        description: Anthropic 服务过载错误码
      - name: 智谱限流（具体）
        pattern: 该模型当前访问量过大
        description: 智谱 AI glm 系列特定限流描述
      - name: 通用中文限流
        pattern: 请稍后重试
        description: 通用中文限流提示（含 QPS/并发限制等场景）
      - name: 通用中文系统繁忙
        pattern: 系统繁忙
        description: 服务端繁忙类错误（多见于国内 LLM 服务）
      - name: 通用中文请求失败
        pattern: 请求失败
        description: 通用请求失败描述（兜底捕获）
      - name: 网络连接拒绝
        pattern: connection refused
        description: 下游服务不可达（连接被拒绝）
      - name: 网络超时
        pattern: connection timeout
        description: 下游服务响应超时
      - name: ECONNREFUSED
        pattern: ECONNREFUSED
        description: Node.js / Python HTTP 客户端的连接拒绝错误码
      - name: ETIMEDOUT
        pattern: ETIMEDOUT
        description: HTTP 客户端的连接超时错误码
      - name: Socket 挂起
        pattern: socket hang up
        description: HTTP 连接被对端中途切断
      - name: JSON 解析失败
        pattern: unexpected token
        description: LLM 返回非合法 JSON（结构化输出场景）
      - name: 工具调用失败（英文）
        pattern: tool call failed
        description: Agent 工具调用抛出异常

  # ========== 知识库子系统 ==========
  kb:
    # 总开关：false 时所有 kb 接口返回 503（运维应急降级用）
    enabled: ${KB_ENABLED:true}
    upload-dir: ${KB_UPLOAD_DIR:./uploads/kb}
    max-file-size: 52428800  # 50MB
    chunk-size: 1000
    chunk-overlap: 200
    allowed-mime-types:
      - application/pdf
      - application/vnd.openxmlformats-officedocument.wordprocessingml.document
      - application/msword
      - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
      - application/vnd.ms-excel
      - application/vnd.openxmlformats-officedocument.presentationml.presentation
      - application/vnd.ms-powerpoint
      - text/plain
      - text/markdown
      - text/html

  # Milvus 向量库（文档向量化）
  milvus:
    enabled: ${MILVUS_ENABLED:true}
    # Java SDK 使用 gRPC 连接 Milvus Lite，不要加 http:// 前缀
    # 本地 Milvus Lite 默认 gRPC 地址：127.0.0.1:19530
    # HTTP REST 端口是 9091，不要混用
    host: ${MILVUS_HOST:127.0.0.1}
    port: ${MILVUS_PORT:19530}
    collection: ${MILVUS_COLLECTION:kb_documents}
    vector-dimension: 1024

  # 本地 Embedding Bridge（稠密+稀疏向量、三级分块、Leaf-only 存储）
  # 使用前需安装依赖: pip install -r backend/embedding-bridge/requirements.txt
  # 首次运行会自动下载 HuggingFace 模型（约 2GB）
  embedding-bridge:
    enabled: ${EMBEDDING_BRIDGE_ENABLED:true}
    host: ${EMBEDDING_BRIDGE_HOST:127.0.0.1}
    port: ${EMBEDDING_BRIDGE_PORT:18732}
    python-path: ${EMBEDDING_BRIDGE_PYTHON_PATH:python}
    script-path: ${EMBEDDING_BRIDGE_SCRIPT_PATH:embedding-bridge/server.py}
    startup-timeout: 120
    health-check-interval: 5
    http-timeout: 600000
    # 访问令牌（为空时自动生成临时 token）
    auth-token: ${EMBEDDING_BRIDGE_AUTH_TOKEN:}
    # 本地 HuggingFace 嵌入模型
    embedding-model: ${EMBEDDING_MODEL:BAAI/bge-m3}
    embedding-device: ${EMBEDDING_DEVICE:cpu}
    dense-embedding-dim: ${DENSE_EMBEDDING_DIM:1024}
    # 三级分块叶子节点参数（L1/L2 按比例放大）
    chunk-size: ${EMBEDDING_CHUNK_SIZE:800}
    chunk-overlap: ${EMBEDDING_CHUNK_OVERLAP:100}

  # ========== SQL Console（结构化数据源管理） ==========
  sql-console:
    query-timeout-seconds: 30
    max-rows: 10000
    forbidden-system-schemas:
      - information_schema
      - mysql
      - sys
      - performance_schema
      - pg_catalog

  # ========== 知识图谱（Neo4j） ==========
  neo4j:
    # 默认值仅供表单预填，实际连接信息存 GraphSource 表（密码 Jasypt 加密）
    # ⚠️ 请改为你的 Neo4j 实例地址与凭据
    default-uri: ${NEO4J_URI:bolt://localhost:7687}
    default-user: ${NEO4J_USER:neo4j}
    default-password: ${NEO4J_PASSWORD:YOUR_NEO4J_PASSWORD_HERE}
    # 查询安全
    query-timeout-seconds: 30
    max-nodes: 1000
    max-edges: 2000

# 工作流运行目录（永久保留，包含每次运行的文件）
workflow:
  run-dir: ${WORKFLOW_RUN_DIR:./data/workflow-runs}
  # LLM 类节点（llm / smartAction / agent / hermesAgent / hermesSmartAction）输出提取的全局默认重试策略
  # 节点 data 中可声明同名字段覆盖此处默认值（详见 RetryPolicy.fromNodeData）
  # 双层重试模型：
  #   runtime-max-retries - 运行异常（限流/超时）时重新完整推理
  #   format-max-retries  - 格式错误（中文键名/字段缺失/类型不匹配）时仅重组 JSON，不重跑业务
  llm:
    retry:
      runtime-max-retries: 2
      format-max-retries: 2
      retry-on-parse-error: true
      retry-on-missing-required: true
      retry-on-type-mismatch: true
      retry-on-key-name-mismatch: true

spring:
  datasource:
    # H2 仅保留运行日志（workflow_run / workflow_run_node）
    url: jdbc:h2:file:./data/agent-runs
    driver-class-name: org.h2.Driver
    username: sa
    password:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false
  h2:
    console:
      enabled: false
  servlet:
    multipart:
      # 单次上传文件大小上限（工作流运行时上传场景）
      max-file-size: 50MB
      max-request-size: 50MB
  # 排除 Spring AI Milvus 自动配置，由本项目 MilvusConfig 按 app.milvus.enabled 控制
  autoconfigure:
    exclude:
      - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration
  ai:
    openai:
      # LLM 服务地址，默认指向智谱 AI（兼容 OpenAI 协议）
      # 可改为其他兼容服务（如 DeepSeek、Moonshot 等）
      base-url: https://open.bigmodel.cn/api/coding/paas/v4
      # ⚠️ 请填入你的智谱 AI API Key
      # 获取地址：https://open.bigmodel.cn/
      # 该 Key 同时用于：1) Spring AI 直接调用 LLM 节点 2) Hermes Bridge 子进程（hermes.bridge.llm-api-key 为空时回退到此）
      api-key: ${OPENAI_API_KEY:YOUR_ZHIPU_API_KEY_HERE}
      chat:
        completions-path: /chat/completions
        options:
          # 模型名称需与 base-url 对应服务一致
          model: glm-5.2
          temperature: 0.3
      # 智谱 embedding-2（已弃用，文档向量化现由本地 Embedding Bridge 完成）
      # 保留本配置仅为兼容 Spring AI EmbeddingModel bean 创建
      embedding:
        options:
          model: embedding-2


# 外部 API（/api/v1/**）配置
# 第三方系统通过 X-API-Key 鉴权后调用工作流，详见 docs/external-workflow-api-spec.md
external:
  api:
    enabled: ${EXTERNAL_API_ENABLED:true}
    keys:
      - key: ${EXTERNAL_API_KEY_1:}
        workflow-ids: []   # 留空表示不限制；填 [12, 15] 表示仅允许调用这两个工作流

# Hermes Agent 执行引擎配置
# 启用后 agent / smartAction 节点将委托 Hermes Bridge（Python AIAgent）执行，
# 获得 40+ 工具（终端、浏览器、搜索等）与 Skill 系统的实际执行能力。
# 使用前需安装: pip install -r hermes-bridge/requirements.txt
# 关闭后 agent / smartAction 节点将退化为 LLM 节点（仅文本对话，无工具能力）
hermes:
  enabled: ${HERMES_ENABLED:true}
  bridge:
    port: ${HERMES_BRIDGE_PORT:18731}
    # Python 可执行文件路径（Windows 可能需要改为 python）
    python-path: ${HERMES_PYTHON_PATH:python}
    # Bridge 脚本路径（相对于项目根目录）
    script-path: ${HERMES_SCRIPT_PATH:hermes-bridge/hermes_bridge.py}
    # Bridge 启动超时（秒）
    startup-timeout: 30
    # 健康检查间隔（秒），0 表示不检查
    health-check-interval: 60
    # 节点未显式配置时使用的最大工具调用轮次（默认 100）
    # 复杂 Skill（多步工具调用）需要较大值，过小会导致「工具调用次数已达上限」错误
    default-max-iterations: 100
    # Bridge 子进程使用的 LLM API Key（与前端 LLM 节点隔离）
    # 为空时回退到 spring.ai.openai.api-key
    llm-api-key: ${HERMES_BRIDGE_LLM_API_KEY:}
    # Bridge HTTP 端点访问令牌（X-Bridge-Token 头校验）
    # 为空时启动会生成临时 token（推荐显式设置 32+ 字符随机字符串）
    auth-token: ${HERMES_BRIDGE_AUTH_TOKEN:}
    # 固定 HERMES_HOME 目录（其下 skills 由 Java 侧自动镜像同步，skill_view/skills_list 从此加载）
    # 相对路径基于后端工作目录；Bridge 子进程启动时通过 --hermes-home 传入，进程内不变
    home: ${HERMES_HOME:./data/hermes-home}

# Jasypt 加密（数据源凭据加密入库）
# ⚠️ 生产环境务必通过环境变量 JASYPT_KEY 设置强随机密钥，不要使用默认值
jasypt:
  encryptor:
    password: ${JASYPT_KEY:dev-only-key-replace-me-in-prod}
