plugin

package
v1.5.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: GPL-3.0 Imports: 9 Imported by: 0

README

目录结构

plugin/
  plugin.go                         # 统一接口、Manifest、Registry
  loader/
    loader.go                       # 集中导入已编译插件子包

主程序导入 plugin/loader 并调用 loader.DefaultRegistry()。loader 通过 blank import 导入插件子包,插件子包在 init() 中调用 plugin.Register(...) 完成注册。

统一接口

每个插件实现 plugin.Interface:

type Interface interface {
    Manifest() plugin.Manifest
    Apply(context.Context, *plugin.Context) error
}

Manifest() 声明插件元数据和适用范围:

plugin.Manifest{
    Name:        "gemini-include-thoughts",
    Label:       "Gemini include thoughts",
    Description: "Force generationConfig.thinkingConfig.includeThoughts to true.",
    Handlers:    []utils.HandlerType{utils.HandlerGemini},
    APITypes:    []utils.APIType{utils.APIGemini},
}

Apply 接收当前请求上下文并直接修改它。一个模型启用多个插件时,会按 models.plugin 中的名称顺序依次执行。

请求上下文

plugin.Context 包含:

  • Alias:用户请求里的模型别名
  • Origin:别名解析后的上游模型名
  • Handler:当前模型解析后的后端处理器,例如 gemini
  • APIType:当前 API 类型,例如 gemini
  • Stream:当前请求是否为流式请求

请求体通过方法访问:

  • JSON():返回当前请求体的共享 *ast.Node。多个 JSON 插件会复用同一个 AST。
  • SetBody([]byte):直接替换请求体,并清空已经解析的 AST。
  • Bytes():返回最终请求体。如果已经解析 JSON,会在插件链末尾统一 marshal。

bridge、内容亲和指纹和插件共用一个请求级 lazy AST,并在链末统一 marshal 一次。

新增插件

  1. 在 plugin/<handler/api>/<plugin-name>/ 下创建插件子包
  2. 实现 plugin.Interface
  3. 在 init() 中调用 plugin.Register(Plugin{})
  4. 在 plugin/loader/loader.go 添加 blank import

示例:

package myplugin

import (
    "context"

    "github.com/nekohy/MeowCLI/plugin"
    "github.com/nekohy/MeowCLI/utils"
)

type Plugin struct{}

func init() {
    plugin.Register(Plugin{})
}

func (Plugin) Manifest() plugin.Manifest {
    return plugin.Manifest{
        Name:        "gemini-my-plugin",
        Label:       "Gemini my plugin",
        Description: "Describe the request mutation.",
        Handlers:    []utils.HandlerType{utils.HandlerGemini},
        APITypes:    []utils.APIType{utils.APIGemini},
    }
}

func (Plugin) Apply(ctx context.Context, req *plugin.Context) error {
    // 不需要修改时直接返回 nil
    return nil
}

然后在 plugin/loader/loader.go 加载:

import (
    "github.com/nekohy/MeowCLI/plugin"

    _ "github.com/nekohy/MeowCLI/plugin/<handler/api>/<plugin-name>"
)

在模型上启用插件

models.plugin 字段保存模型启用的插件名称,使用英文逗号分隔:

gemini-include-thoughts,gemini-my-plugin

管理端 API 约定:

  • 模型列表返回每个模型的 plugin 字段
  • overview 中每个 handler 返回当前可用的 plugins 列表
  • 前端根据模型 handler 过滤可选插件

请求转发时,bridge 会读取当前模型解析结果中的启用插件列表,并在请求发往上游前按顺序执行

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseList

func ParseList(raw string) []string

func Register

func Register(p Interface)

Types

type Context

type Context struct {
	Alias   string
	Origin  string
	Handler utils.HandlerType
	APIType utils.APIType
	Stream  bool
	// contains filtered or unexported fields
}

func NewContext

func NewContext(body []byte) *Context

func (*Context) Bytes

func (c *Context) Bytes() ([]byte, error)

func (*Context) JSON

func (c *Context) JSON() (*ast.Node, error)

JSON 返回请求级共享的惰性 AST,bridge 和多个插件只解析一次

func (*Context) SetBody

func (c *Context) SetBody(body []byte)

type Interface

type Interface interface {
	Manifest() Manifest
	Apply(context.Context, *Context) error
}

type Manifest

type Manifest struct {
	Name        string              `json:"name"`
	Label       string              `json:"label"`
	Description string              `json:"description"`
	Handlers    []utils.HandlerType `json:"handlers"`
	APITypes    []utils.APIType     `json:"api_types"`
}

func (Manifest) Supports

func (m Manifest) Supports(handler utils.HandlerType, apiType utils.APIType) bool

func (Manifest) SupportsHandler

func (m Manifest) SupportsHandler(handler utils.HandlerType) bool

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

func DefaultRegistry

func DefaultRegistry() *Registry

func NewRegistry

func NewRegistry() *Registry

func (*Registry) Apply added in v1.5.0

func (r *Registry) Apply(ctx context.Context, enabled []string, req *Context) error

Apply 依次修改同一个请求 Context,不在插件链结束时强制序列化 调用方可以继续复用 Context 中缓存的最终 AST

func (*Registry) Available

func (r *Registry) Available(handler utils.HandlerType, apiType utils.APIType) []Manifest

func (*Registry) Get

func (r *Registry) Get(name string) (Interface, bool)

func (*Registry) Register

func (r *Registry) Register(p Interface)

func (*Registry) Run

func (r *Registry) Run(ctx context.Context, enabled []string, req *Context) ([]byte, error)

Directories

Path Synopsis
APIGemini
HandlerAntigravity
HandlerCodex

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL