feat: add AI endpoint manager plugin with configuration and routing capabilities
Some checks failed
CI / Determine matrix (push) Has been cancelled
CI / Sanitizer (ASan+UBSan) / ubuntu-24.04 (push) Has been cancelled
CI / Coverage (gcovr) / ubuntu-24.04 (push) Has been cancelled
CI / ${{ matrix.os }} / ${{ matrix.build_type }} (push) Has been cancelled

- Introduced `ai_endpoint_mgr` plugin to manage multiple AI provider endpoints.
- Added configuration reference documentation for `config.toml`.
- Implemented endpoint loading, active endpoint switching, and model mutation.
- Included error handling for missing endpoints and configuration failures.
- Developed unit tests covering various scenarios including error paths and concurrency.
This commit is contained in:
2026-06-03 21:07:25 +08:00
parent 28ae90a6cc
commit 4745ce1f1c
18 changed files with 1570 additions and 34 deletions

90
config.example.toml Normal file
View File

@@ -0,0 +1,90 @@
# ============================================================================
# dstalk config.example.toml — 配置模板 / Configuration template
# ============================================================================
# 复制为 config.toml 并修改即可使用。
# Copy to config.toml and edit before use.
#
# 两种配置方式(互斥,选择一种即可):
# Two configuration modes (mutually exclusive, pick one):
#
# 1) 单 Provider 模式(简单,一个 AI 后端)
# Single-provider mode (simple, one AI backend)
# 使用 keys: ai.provider / api.base_url / api.api_key / api.model
#
# 2) 多 Endpoint 模式(高级,同时配置多个 AI 后端并通过 /endpoint 切换)
# Multi-endpoint mode (advanced, multiple AI backends switchable via /endpoint)
# 使用 keys: endpoints.names / endpoints.active / endpoint.<name>.*
#
# 如果同时配置了两种方式ai_endpoint_mgr 的 chat 调用优先走 endpoints.*。
# If both are configured, ai_endpoint_mgr chat calls prefer endpoints.*.
# ============================================================================
# ----------------------------------------------------------------------------
# 方式 1: 单 Provider 模式 / Mode 1: Single Provider
# ----------------------------------------------------------------------------
# 取消下方注释即可使用 / Uncomment to use
# ai.provider = "ai_openai" # ai_openai 或 ai_anthropic / ai_openai or ai_anthropic
#
# api.base_url = "https://api.openai.com/v1"
# api.api_key = "sk-your-key-here"
# api.model = "gpt-4o"
# 或者用 Anthropic / Or use Anthropic:
# ai.provider = "ai_anthropic"
# api.base_url = "https://api.anthropic.com"
# api.api_key = "sk-ant-your-key-here"
# api.model = "claude-sonnet-4-20250514"
# ----------------------------------------------------------------------------
# 方式 2: 多 Endpoint 模式 / Mode 2: Multi-Endpoint
# ----------------------------------------------------------------------------
# 取消下方注释即可使用,多个 endpoint 在对话中通过 /endpoint 命令切换。
# Uncomment to use. Switch endpoints during a session via the /endpoint command.
# 逗号分隔的 endpoint 名称列表(至少一个) / Comma-separated endpoint names (at least one)
# endpoints.names = "openai_main, anthropic_alt"
# 默认激活的 endpoint可选不设置则取列表第一个 / Default active endpoint (optional, defaults to first in list)
# endpoints.active = "openai_main"
# --- openai_main ---
# provider 必须 / required
# endpoint.openai_main.provider = "ai_openai"
# base_url 可选 / optional (默认按 provider 自动填 / defaults by provider: OpenAI→api.openai.com/v1, Anthropic→api.anthropic.com)
# endpoint.openai_main.base_url = "https://api.openai.com/v1"
# api_key 必须 / required
# endpoint.openai_main.api_key = "sk-your-key-here"
# model 必须 / required
# endpoint.openai_main.model = "gpt-4o"
# max_tokens 可选 / optional (默认 4096) / default 4096
# endpoint.openai_main.max_tokens = 4096
# temperature 可选 / optional (默认 0.7, 范围 0.0~2.0) / default 0.7, range 0.0~2.0
# endpoint.openai_main.temperature = 0.7
# --- anthropic_alt ---
# endpoint.anthropic_alt.provider = "ai_anthropic"
# base_url 未设置时自动使用 https://api.anthropic.com / defaults to https://api.anthropic.com when unset
# endpoint.anthropic_alt.api_key = "sk-ant-your-key-here"
# endpoint.anthropic_alt.model = "claude-sonnet-4-20250514"
# endpoint.anthropic_alt.max_tokens = 8192
# --- deepseek (自定义 base_url 示例 / custom base_url example) ---
# endpoint.deepseek.provider = "ai_openai"
# endpoint.deepseek.base_url = "https://api.deepseek.com/v1"
# endpoint.deepseek.api_key = "sk-deepseek-your-key-here"
# endpoint.deepseek.model = "deepseek-chat"
# 提示 / Tips:
# - list_json 输出不含 api_key安全脱敏
# list_json output excludes api_key (security de-identification).
# - 未知 provider 必须显式配置 base_url否则 endpoint 加载失败。
# Unknown providers must explicitly set base_url or the endpoint won't load.