ci / vet-and-test (pull_request) Successful in 41s
Why: 进程内插件命令此前只登记规格不绑处理器,分发即 "no host handler bound", 且插件无 owner 凭证(H4);EXT-1 最小集补上处理器绑定与 owner 作用域宿主句柄。 Evidence: pkg/extension 新增 Request/Handler/Host + Registry.AddCommandHandler(surface.txt 12→15); cmdbus.RegisterPluginCommand 三例测试(committed/未绑 rejected/高危确认卡先拦); rag.IndexChunks 抽出并两例直测;internal/app hostcaps+inprocHost 复用 hostapi owner 作用域实现, applyCompiled 携 caps,inproc_host_test 双 owner 隔离 + provider=hash 向量写入均通过;go test ./... 29 包全绿。 Impact: 公开面依赖从零外部模块变为 +agent-system-core(声明式 go.mod 需按 compat-policy §4 加 core require+replace); 既有路径语义不变,SurfaceVersion 保持 2.0.0-experimental。 Refs: documents 提案 2026-10-05-ext-1-inproc-command-handler.md;V1.2 方案批注 1。
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
// Package extension 是基座对下游仓的公开扩展面。
|
|
// 下游只能依赖本包(以及 agent-system-core 的类型),不能导入 internal。
|
|
package extension
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
// SurfaceVersion 是本包导出面的实验版本。变更导出符号必须同时更新 surface.txt。
|
|
const SurfaceVersion = "2.0.0-experimental"
|
|
|
|
// ErrNotLinked 表示进程没有空白导入 link 包,Main 无法启动服务。
|
|
var ErrNotLinked = errors.New("extension: runner not linked; blank-import agent-system-backend/pkg/extension/link")
|
|
|
|
// Registry 是进程内扩展的注册口。实现在基座内部,对下游只暴露这些方法。
|
|
type Registry interface {
|
|
AddSkill(name, markdown string) error
|
|
AddCommand(spec json.RawMessage) error
|
|
// AddCommandHandler 注册插件命令规格并绑定进程内处理器(EXT-1):
|
|
// 基座在分发时按请求 Owner 构造 Host 句柄调用 h。
|
|
AddCommandHandler(spec json.RawMessage, h Handler) error
|
|
Note(kind, name string, payload json.RawMessage) error
|
|
}
|
|
|
|
// InProc 是随下游二进制编译进来的扩展。
|
|
type InProc struct {
|
|
ID string
|
|
Register func(reg Registry) error
|
|
}
|
|
|
|
// Options 是下游自有二进制的启动参数,字段与 agent-system serve 对齐。
|
|
type Options struct {
|
|
Addr string
|
|
DataDir string
|
|
PluginsDir string
|
|
Mock bool
|
|
StorageDSN string
|
|
ArtifactsDir string
|
|
AuthMode string
|
|
}
|
|
|
|
var (
|
|
mu sync.Mutex
|
|
compiled []InProc
|
|
runner func(Options) error
|
|
)
|
|
|
|
// RegisterCompiled 在 init 中登记进程内扩展。
|
|
func RegisterCompiled(e InProc) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
compiled = append(compiled, e)
|
|
}
|
|
|
|
// Compiled 返回已登记扩展的副本。
|
|
func Compiled() []InProc {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
out := make([]InProc, len(compiled))
|
|
copy(out, compiled)
|
|
return out
|
|
}
|
|
|
|
// ResetCompiled 只给测试清状态。
|
|
func ResetCompiled() {
|
|
mu.Lock()
|
|
compiled = nil
|
|
mu.Unlock()
|
|
}
|
|
|
|
// SetRunner 由 link 包在 init 时注入。下游不要调用。
|
|
func SetRunner(fn func(Options) error) {
|
|
mu.Lock()
|
|
runner = fn
|
|
mu.Unlock()
|
|
}
|
|
|
|
// Main 启动带有已登记扩展的服务。
|
|
func Main(opt Options) error {
|
|
mu.Lock()
|
|
fn := runner
|
|
mu.Unlock()
|
|
if fn == nil {
|
|
return ErrNotLinked
|
|
}
|
|
return fn(opt)
|
|
}
|