Why: Downstream products must extend the base through a public package and host API instead of editing internal code. Evidence: go test ./... passed, including plugin v2 assets, sidecar startup, migration v13, pending confirms, HITL timeout, hash embedder, command pairs, and the extension surface snapshot. Impact: apiVersion 2.0-experimental rejects empty network allowlists for declarative HTTP. Hash embeddings stay opt-in via models.embedding.provider=hash. Plugin secrets resolve per owner at execution time. Refs: docs/proposals/2026-10-01-plugin-contract-v2.md Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.0 KiB
Go
87 lines
2.0 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
|
|
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)
|
|
}
|