W17: extract ai_common shared module + fix anthropic data race + brace bugs
- New plugins_upper/ai_common/ static library: shared PluginConfig, ToolCallAccum, StreamContext, secure_zero, extract_host_port, serialize_tool_calls, free_chat_result - Refactored openai/anthropic plugins to use dstalk_ai:: namespace from ai_common - Fixed anthropic g_config raw pointer → std::atomic (data race) - Added SSE parse error counter with threshold abort (kMaxSseParseErrors=5) - Fixed missing closing brace in both plugins' error-body catch block - Updated test targets: ai_common include path + link, using namespace dstalk_ai - plugin_loader_test: added stub_unreg + service_registry.cpp for unregister_service - Includes pre-existing uncommitted changes from prior waves Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -90,7 +90,7 @@ struct dstalk_ai_service_t {
|
||||
每种服务都有一个预定义的 vtable 结构体(定义在 `dstalk_services.h`)。第三方也可以扩展自己的服务 vtable,版本号随注册一起提供,允许消费者做最低版本检查。
|
||||
|
||||
服务注册采用 **name + version** 两要素:
|
||||
- 全局唯一名称(如 `"ai.openai"`、`"http"`、`"file_io"`)。
|
||||
- 全局唯一名称(如 `"ai_openai"`、`"http"`、`"file_io"`)。
|
||||
- 版本号(消费者可以要求 `min_version`)。
|
||||
|
||||
---
|
||||
|
||||
@@ -87,7 +87,7 @@ Host 收到非零返回值后,会跳过后续插件的初始化并报告警告
|
||||
**契约 3:register_service 注册自己的服务。** 插件将自己的 vtable 注册到服务注册表后,其他依赖它的插件才能在后续的 `on_init` 中通过 `query_service` 找到它。
|
||||
|
||||
```c
|
||||
return host->register_service("ai.openai", 1, &g_service);
|
||||
return host->register_service("ai_openai", 1, &g_service);
|
||||
```
|
||||
|
||||
注册表内的 vtable 是原始指针,不拷贝。因此 vtable 指向的结构体必须是**静态生命周期**(全局变量或 static 局部变量)。
|
||||
|
||||
@@ -110,7 +110,7 @@ Linux/macOS 通常共享 libc,但静态链接或不同 libc 版本时同样可
|
||||
### 4.2 重复注册
|
||||
|
||||
同一 `name` 不可重复注册:第二次调用返回 `-2`(`service_registry.cpp:13`)。插件应检查返回
|
||||
值,在共享服务名(如 `"ai.openai"`)的场景中避免冲突。
|
||||
值,在共享服务名(如 `"ai_openai"`)的场景中避免冲突。
|
||||
|
||||
### 4.3 版本协商
|
||||
|
||||
|
||||
@@ -6,35 +6,65 @@
|
||||
|
||||
## 1. 安装工具链
|
||||
|
||||
dstalk 需要 CMake、Ninja、LLVM/Clang 和 Conan2。`setup.bat` 全自动下载安装到 `tools/` 目录。
|
||||
dstalk 需要 CMake、Ninja、LLVM/Clang 和 Conan2。`tools/` 下的脚本全自动安装。
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
cd tools
|
||||
setup.bat
|
||||
```
|
||||
|
||||
**Mac:**
|
||||
```bash
|
||||
# 方式 A: 手动安装后运行脚本
|
||||
brew install cmake ninja
|
||||
cd tools && bash setup.sh
|
||||
|
||||
# 方式 B: 脚本全自动 (推荐)
|
||||
cd tools && bash setup.sh
|
||||
```
|
||||
|
||||
**Linux (Ubuntu/Debian):**
|
||||
```bash
|
||||
# 方式 A: 手动安装后运行脚本
|
||||
sudo apt install cmake ninja-build
|
||||
cd tools && bash setup.sh
|
||||
|
||||
# 方式 B: 脚本全自动 (推荐)
|
||||
cd tools && bash setup.sh
|
||||
```
|
||||
|
||||
> **前提**: 系统需已安装 Python 3.10+。
|
||||
>
|
||||
> 网络不畅时, 可手动下载放入对应目录:
|
||||
> - [Ninja](https://github.com/ninja-build/ninja/releases) → `tools/ninja/ninja.exe`
|
||||
> - [CMake](https://cmake.org/download/) → `tools/cmake/bin/cmake.exe`
|
||||
> - [LLVM](https://github.com/llvm/llvm-project/releases) → `tools/llvm/bin/clang.exe`
|
||||
> - Conan2 通过 pip 安装到 `tools/.venv/Scripts/conan.exe`
|
||||
> - [Ninja](https://github.com/ninja-build/ninja/releases) → `tools/ninja/ninja` (或 `ninja.exe`)
|
||||
> - [CMake](https://cmake.org/download/) → `tools/cmake/bin/cmake` (或 `cmake.exe`)
|
||||
> - [LLVM](https://github.com/llvm/llvm-project/releases) → `tools/llvm/bin/clang` (或 `clang.exe`)
|
||||
> - Conan2 通过 pip 安装到 `tools/.venv/Scripts/conan.exe` (Win) 或 `tools/.venv/bin/conan` (Mac/Linux)
|
||||
|
||||
---
|
||||
|
||||
## 2. 编译
|
||||
|
||||
项目根目录提供 `build.bat`, 一键完成: Conan 拉取依赖 -> CMake 配置 -> Ninja 编译。
|
||||
项目根目录提供 `build.bat` (Windows) / `build.sh` (Mac/Linux), 一键完成: Conan 拉取依赖 -> CMake 配置 -> Ninja 编译。
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
build.bat
|
||||
```
|
||||
|
||||
编译产物输出到 `build/` 目录。核心产物:
|
||||
- `build/dstalk_core/dstalk.dll` —— 核心 DLL
|
||||
- `build/dstalk_cli/dstalk_cli.exe` —— 命令行前端
|
||||
- `build/plugins/*.dll` —— 功能插件
|
||||
**Mac / Linux:**
|
||||
```bash
|
||||
bash build.sh
|
||||
```
|
||||
|
||||
编译产物输出到 `build/` 目录:
|
||||
|
||||
| 产物 | Windows | Mac | Linux |
|
||||
|------|---------|-----|-------|
|
||||
| 核心 DLL | `build/bin/dstalk.dll` | `build/bin/libdstalk.dylib` | `build/bin/libdstalk.so` |
|
||||
| CLI 前端 | `build/bin/dstalk_cli.exe` | `build/bin/dstalk_cli` | `build/bin/dstalk_cli` |
|
||||
| 功能插件 | `build/plugins/*.dll` | `build/plugins/*.dylib` | `build/plugins/*.so` |
|
||||
|
||||
---
|
||||
|
||||
@@ -49,15 +79,15 @@ build.bat
|
||||
**config.toml 示例:**
|
||||
|
||||
```toml
|
||||
# 选择 AI 后端插件: ai.openai 或 ai.anthropic
|
||||
ai.provider = "ai.openai"
|
||||
# 选择 AI 后端插件: ai_openai 或 ai_anthropic
|
||||
ai.provider = "ai_openai"
|
||||
|
||||
# OpenAI-compatible
|
||||
api.base_url = "https://api.openai.com/v1"
|
||||
api.api_key = "sk-xxxxxxxx"
|
||||
api.model = "gpt-4o"
|
||||
|
||||
# Anthropic Claude (切换 ai.provider 为 "ai.anthropic" 即可)
|
||||
# Anthropic Claude (切换 ai.provider 为 "ai_anthropic" 即可)
|
||||
# api.base_url = "https://api.anthropic.com/v1"
|
||||
# api.api_key = "sk-ant-xxxxxxxx"
|
||||
# api.model = "claude-opus-4-20250514"
|
||||
@@ -71,8 +101,14 @@ api.model = "gpt-4o"
|
||||
|
||||
## 4. 运行 dstalk_cli
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
build/dstalk_cli/dstalk_cli.exe
|
||||
build\bin\dstalk_cli.exe
|
||||
```
|
||||
|
||||
**Mac / Linux:**
|
||||
```bash
|
||||
build/bin/dstalk_cli
|
||||
```
|
||||
|
||||
启动后显示欢迎横幅:
|
||||
|
||||
Reference in New Issue
Block a user