91 lines
3.1 KiB
Go
91 lines
3.1 KiB
Go
// Package sdk is the standalone plugin SDK for Cyrene v2. Third-party plugins
|
|
// import this package, implement the Tool, Skill and Channel interfaces, and
|
|
// register themselves through the Registrar that the core capability registry
|
|
// (internal/capability/registry) implements.
|
|
//
|
|
// Plugins are compiled into the binary and registered at startup; there is no
|
|
// Go plugin dynamic loading. That keeps the plugin surface portable across
|
|
// Windows, ARM and other targets, as required by DevDocs/design/09 §2.
|
|
//
|
|
// The three plugin categories mirror DevDocs/design/09 §0:
|
|
//
|
|
// - Tool: a function plus an input JSON Schema, callable directly by the
|
|
// agent (calculator, web-search, file, ...).
|
|
// - Skill: a reusable workflow (an ordered set of steps) with prompts,
|
|
// references and guardrails, higher-level than a Tool (daily brief, code
|
|
// review, multi-stage report).
|
|
// - Channel: a platform adapter (QQ, WeChat, Telegram, ...).
|
|
//
|
|
// Capabilities are globally shared and always available to every character and
|
|
// mode; the registry is what makes them visible. A plugin never needs to know
|
|
// the registry's concrete type — it registers through the Registrar interface.
|
|
package sdk
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
)
|
|
|
|
// ErrNilRegistrar is returned by the helper registration functions when the
|
|
// supplied Registrar is nil.
|
|
var ErrNilRegistrar = errors.New("sdk: nil registrar")
|
|
|
|
// Registrar is the subset of a capability registry that accepts plugins. The
|
|
// core registry (internal/capability/registry) implements it, and third-party
|
|
// plugins register through it.
|
|
type Registrar interface {
|
|
// RegisterTool registers a Tool.
|
|
RegisterTool(t Tool) error
|
|
// RegisterSkill registers a Skill.
|
|
RegisterSkill(s Skill) error
|
|
// RegisterChannel registers a Channel adapter.
|
|
RegisterChannel(c Channel) error
|
|
}
|
|
|
|
// ConfigHook validates or mutates a plugin's configuration section at startup,
|
|
// before the runtime uses it. The host applies hooks in registration order and
|
|
// stops at the first error or on context cancellation.
|
|
type ConfigHook func(ctx context.Context, config map[string]any) error
|
|
|
|
// RegisterTool registers t with r. It returns ErrNilRegistrar when r is nil.
|
|
func RegisterTool(r Registrar, t Tool) error {
|
|
if r == nil {
|
|
return ErrNilRegistrar
|
|
}
|
|
return r.RegisterTool(t)
|
|
}
|
|
|
|
// RegisterSkill registers s with r. It returns ErrNilRegistrar when r is nil.
|
|
func RegisterSkill(r Registrar, s Skill) error {
|
|
if r == nil {
|
|
return ErrNilRegistrar
|
|
}
|
|
return r.RegisterSkill(s)
|
|
}
|
|
|
|
// RegisterChannel registers c with r. It returns ErrNilRegistrar when r is nil.
|
|
func RegisterChannel(r Registrar, c Channel) error {
|
|
if r == nil {
|
|
return ErrNilRegistrar
|
|
}
|
|
return r.RegisterChannel(c)
|
|
}
|
|
|
|
// RunConfigHooks applies hooks in order against config, stopping at the first
|
|
// error or when ctx is canceled. Nil hooks are skipped. It returns nil when
|
|
// every hook succeeds.
|
|
func RunConfigHooks(ctx context.Context, config map[string]any, hooks ...ConfigHook) error {
|
|
for _, h := range hooks {
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
if h == nil {
|
|
continue
|
|
}
|
|
if err := h(ctx, config); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|