feat(sdk): 通用反代声明项(DeclareProxy)+ ToolDef.Serial 串行标记 + 场面策略文档

本次一并提交工作区此前累积的改动(均已验证),并接入工具并发调度所需的
声明项。

把「谁来反代谁」从内核硬编码变成插件可声明。设备网关(remotedevice)
这类**编译进内核、没有独立插件目录与 plugin.json** 的服务,静态扫描扫不到,
此前只能靠约定。新增 DeclareProxy 让它们能自己声明反代路由。

ParallelSafe 的**反向**声明项。判据优先级:Serial 胜出,显式声明不允许被
ParallelSafe 或任何默认值覆盖。

为什么需要它:ParallelSafe 零值 false 已表达「安全/串行」,插件无法区分
「我没想过」和「我确认过必须串行」。没有这个区分,工具作者只能靠命名约定
传递意图,那不是契约。

ParallelSafe 本身也补齐了注释,明确其零值语义(默认串行、保守)与理由
(新语义下并发会改变工具的行为前提,让存量插件意外并发比慢一点危险得多)。

配套 ScenePolicy 声明项的使用说明。

remotedevice/ 整目录(C 实现的设备网关,已由 Go 侧 DeclareProxy 路径取代)。

- sdk/knowledge.go:随场面策略配套调整
- docs/api/*、docs/assets/api-index.json、docs/llms.txt、mkdocs.yml:
  由 tools/apidoc/build.sh 从源码重新生成(行号随 plugin.go 变动漂移)
This commit is contained in:
JianFeeeee
2026-09-27 14:52:26 +08:00
parent e417c69fc8
commit bd73a9b241
26 changed files with 719 additions and 3656 deletions

View File

@ -10,7 +10,7 @@
func (c *StageContext) IsResponded() bool
```
<small>`plugin.go:172`</small>
<small>`plugin.go:213`</small>
### `StageContext.Lock`
@ -27,7 +27,7 @@ func (c *StageContext) Lock()
| [`browser`](../examples/index.md#browser) | `example/browser/plugin.go:427` | `p.mu.Lock()` |
| [`calendar`](../examples/index.md#calendar) | `example/calendar/plugin.go:433` | `p.mu.Lock()` |
<small>`plugin.go:170`</small>
<small>`plugin.go:211`</small>
### `StageContext.RLock`
@ -44,7 +44,7 @@ func (c *StageContext) RLock()
| [`memo`](../examples/index.md#memo) | `example/memo/plugin.go:224` | `p.mu.RLock()` |
| [`qq`](../examples/index.md#qq) | `example/qq/plugin.go:1152` | `ctx.RLock()` |
<small>`plugin.go:168`</small>
<small>`plugin.go:209`</small>
### `StageContext.RUnlock`
@ -61,7 +61,7 @@ func (c *StageContext) RUnlock()
| [`memo`](../examples/index.md#memo) | `example/memo/plugin.go:229` | `p.mu.RUnlock()` |
| [`qq`](../examples/index.md#qq) | `example/qq/plugin.go:1155` | `ctx.RUnlock()` |
<small>`plugin.go:169`</small>
<small>`plugin.go:210`</small>
### `PluginSDK.RegisterStage`
@ -83,7 +83,7 @@ RegisterStage registers a handler for a pipeline stage.
| [`sanitizer`](../examples/index.md#sanitizer) | `example/sanitizer/plugin.go:52` | `s.RegisterStage(sdk.StageOnInput, func(ctx *sdk.StageContext) error {` |
| [`weather`](../examples/index.md#weather) | `example/weather/plugin.go:94` | `s.RegisterStage(sdk.StageAfterToolcall, func(ctx *sdk.StageContext) error {` |
<small>`plugin.go:472`</small>
<small>`plugin.go:571`</small>
### `Stage`
@ -103,7 +103,7 @@ type StageContext struct { mu sync.RWMutex RawMessage string UserID string Group
StageContext provides context for stage handlers.
<small>`plugin.go:148`</small>
<small>`plugin.go:189`</small>
### `StageHandler`
@ -123,7 +123,7 @@ type StageRegistrar func(stage Stage, handler StageHandler)
StageRegistrar registers a stage handler.
<small>`plugin.go:308`</small>
<small>`plugin.go:407`</small>
### `StageScope`
@ -133,7 +133,7 @@ type StageScope int
StageScope controls which events a stage handler receives.
<small>`plugin.go:294`</small>
<small>`plugin.go:393`</small>
### `StageContext.Unlock`
@ -150,5 +150,5 @@ func (c *StageContext) Unlock()
| [`browser`](../examples/index.md#browser) | `example/browser/plugin.go:432` | `p.mu.Unlock()` |
| [`calendar`](../examples/index.md#calendar) | `example/calendar/plugin.go:523` | `p.mu.Unlock()` |
<small>`plugin.go:171`</small>
<small>`plugin.go:212`</small>