Files
Agent-System-Backend/pkg/extension/extension.go
T
weichenandCursor cd5b82186d Add the public extension surface and platform services
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>
2026-10-01 10:35:02 +00:00

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)
}