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

View File

@@ -55,6 +55,15 @@ int main()
<< "provider = \"openai\"\n"
<< "base_url = \"https://api.openai.com/v1\"\n"
<< "api_key = \"test-key\"\n"
<< "model = \"gpt-4o\"\n"
<< "\n"
<< "# minimal endpoint config for ai_endpoint_mgr / 最小 endpoint 配置供 ai_endpoint_mgr 加载\n"
<< "[endpoints]\n"
<< "names = \"gpt4o\"\n"
<< "\n"
<< "[endpoint.gpt4o]\n"
<< "provider = \"ai_openai\"\n"
<< "api_key = \"test-key\"\n"
<< "model = \"gpt-4o\"\n";
}
@@ -217,6 +226,52 @@ int main()
// 测试 dstalk_log / Test dstalk_log
dstalk_log(DSTALK_LOG_INFO, "Smoke test completed successfully");
// ========================================================================
// 测试服务查询: ai_endpoint_mgr / Test service query: ai_endpoint_mgr
// 验证 endpoint 加载 / 列表脱敏 / count / get_active / Verify endpoint load / list sanitization / count / get_active
// 不调用真实 chat 网络 / No real chat network calls
// ========================================================================
{
auto* ep_mgr = static_cast<const dstalk_ai_endpoint_mgr_t*>(
dstalk_service_query("ai_endpoint_mgr", 1));
if (ep_mgr) {
std::cout << "[OK] ai_endpoint_mgr service found\n";
// 验证 endpoint 数量 >= 1 / Verify endpoint count >= 1
int n = ep_mgr->count();
if (n >= 1) {
std::cout << "[OK] ai_endpoint_mgr count = " << n << "\n";
} else {
std::cerr << "[FAIL] ai_endpoint_mgr count = " << n << " (expected >= 1)\n";
}
// 验证 list_json 非空且不泄露 api_key / Verify list_json non-null and no api_key leak
char* list = ep_mgr->list_json();
if (list) {
std::string list_str(list);
if (list_str.find("test-key") == std::string::npos) {
std::cout << "[OK] ai_endpoint_mgr list_json sanitized (no api_key leak): "
<< list << "\n";
} else {
std::cerr << "[FAIL] ai_endpoint_mgr list_json leaks api_key: " << list << "\n";
}
dstalk_free(list);
} else {
std::cerr << "[FAIL] ai_endpoint_mgr list_json returned null\n";
}
// 验证 get_active 非空 / Verify get_active non-null
const char* active = ep_mgr->get_active();
if (active) {
std::cout << "[OK] ai_endpoint_mgr get_active = " << active << "\n";
} else {
std::cerr << "[FAIL] ai_endpoint_mgr get_active returned null\n";
}
} else {
std::cerr << "[WARN] ai_endpoint_mgr service not found\n";
}
}
// ========================================================================
// 扩展测试块 C2: null-safety / 转义边界 / tools 调用链 / session 健壮性
// Extended test block C2: null-safety / escape boundaries / tools chain / session robustness
@@ -751,6 +806,15 @@ int main()
<< "provider = \"openai\"\n"
<< "base_url = \"https://api.openai.com/v1\"\n"
<< "api_key = \"test-key\"\n"
<< "model = \"gpt-4o\"\n"
<< "\n"
<< "# minimal endpoint config for ai_endpoint_mgr / 最小 endpoint 配置供 ai_endpoint_mgr 加载\n"
<< "[endpoints]\n"
<< "names = \"gpt4o\"\n"
<< "\n"
<< "[endpoint.gpt4o]\n"
<< "provider = \"ai_openai\"\n"
<< "api_key = \"test-key\"\n"
<< "model = \"gpt-4o\"\n";
}