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