Documentation
¶
Overview ¶
Package plugin:插件实现与**传输**之间的接缝。
一个插件的实现(schema 声明 + handler)应当只有一份,被两种传输承接:
server 进程内直调 —— 平台自己就是宿主 plugin-builtin sokel + NATS —— 单独部署到别的机器
差别只有传输。所以实现不该认识 *sokel.Plugin / sokel.Ctx 这些 NATS 那侧的类型, 只认下面这几个接口;由谁来实现它们,就决定了这次调用走哪条路。
这几个接口刻意小:真实插件用到的运行时能力就这么多(凭证、取文件、存文件、报状态)。 接口一大,两种传输就都难实现,而且大出来的部分多半只有一侧用得上。
Index ¶
- func DeclareCapabilities(h Host, caps map[string]bool)
- func DeclareDoc(h Host, markdown, url string)
- type AuthChallenge
- type AuthHandlers
- type AuthHost
- type AuthState
- type CapabilityHost
- type CredentialHost
- type Ctx
- type DocHost
- type EventHost
- type File
- type Host
- type Invoke
- type Sink
- type SourceCtx
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DeclareCapabilities ¶
DeclareCapabilities:宿主支持就收下能力位,不支持就静默跳过(进程内/远端两边同一份代码)。
func DeclareDoc ¶
DeclareDoc:宿主支持就交出说明书,不支持就静默跳过(进程内/远端两边同一份代码)。
markdown 与 url 给一个即可:自己写一段,或指向已有的文档站—— 抄一份进来的那份迟早与站上的不一致。
Types ¶
type AuthChallenge ¶
type AuthChallenge struct {
// AuthID:这一次认证尝试的 id;poll/submit 会带着它回来。留空则 SDK 自动生成。
AuthID string
// Kind:留空取声明里的 Kind。同一插件的不同凭证走不同形态时才需要按次覆盖。
Kind string
// QRImage:kind=qr 的二维码,data-uri(如 "data:image/png;base64,…")。
QRImage string
// Prompt:给人看的一句话(kind=input 时同时作为输入框 placeholder)。
Prompt string
// ExpiresIn:有效期(秒)。0 = 不告诉面板。
ExpiresIn int
}
AuthChallenge:start 交给面板的「题目」。
type AuthHandlers ¶
type AuthHandlers struct {
Start func(Ctx) (*AuthChallenge, error)
Poll func(ctx Ctx, authID string) (*AuthState, error)
Submit func(ctx Ctx, authID, input string) error
}
AuthHandlers:认证流的实现侧。哪几步非空由声明的 Steps 决定(生成的 RegisterAuth 保证对齐)。
type AuthHost ¶
type AuthHost interface {
SetAuthFlow(meta contract.AuthMeta, h AuthHandlers)
}
AuthHost:能接住协作式认证流的宿主(SDK 的 *sokel.Plugin 实现它)。 与 CredentialHost 同理:小接口、单方法,生成物因此不必 import go-sdk。
type AuthState ¶
type AuthState struct {
// Status:pending / scanned(已扫码待确认)/ confirmed / expired。
Status string
// Session:confirmed 时的会话凭据,交**平台**写进凭证行——不回前端,浏览器不经手明文。
//
// 必须是 JSON **对象**形态。给字符串会被再包一层引号(双重编码),
// 插件下次读凭证时就解不回来了。
Session []byte
}
AuthState:poll 的回答。
type CapabilityHost ¶
CapabilityHost:能接住「可选能力自报」的宿主。
与 DocHost 同一个模式(小接口、可选实现)。它解决的是「操作有没有」之外的那一半: 同一个操作,两家实现做到的程度可以差很远——存储插件都有 keyword_query, 但一家是带中文分词的 BM25、另一家是相似度近似。不报的话平台只能静默忽略, 用户配了字段加权却毫无体现,那比「不支持」更坏。
type CredentialHost ¶
CredentialHost:能接住凭证契约的宿主(SDK 的 *sokel.Plugin 实现它)。
单独一个小接口而不是并进 Host:进程内宿主没有「上报凭证契约」这回事, 而生成的代码要能同时挂两边。生成物也因此不必 import go-sdk—— plugin-core 反过来依赖 SDK 会成环(内核自带的契约声明就在 plugin-core 里)。
type Ctx ¶
type Ctx interface {
context.Context
// Credential 本次调用的凭证字段(平台解析后下发;无凭证返回 nil)。
Credential() map[string]string
// Upload 把字节存进平台文件层,得到一个文件引用(可直接作为出参交给下游)。
Upload(name, mime string, data []byte) (*File, error)
// UploadReader 同上,但**边读边传**:内存占用是一个块(1MB),与文件大小无关。
//
// 几百 MB 以上的东西(NAS 上的视频、压缩包)一律走这条——Upload 要求先把整个文件
// 读进内存,那不是"慢一点",是插件进程直接被撑爆。
UploadReader(name, mime string, r io.Reader) (*File, error)
// Fetch 取回文件字节。File.Blob 是它的方法形式,插件里一般写 f.Blob(ctx)。
Fetch(f *File) ([]byte, error)
}
Ctx:一次调用能用到的运行时能力。
各传输的实现方式不同,但语义一致——比如 Upload:NATS 那侧分块传回平台, 进程内那侧直接落存储层。handler 不必知道自己跑在哪。
type DocHost ¶
type DocHost interface {
SetDoc(markdown, url string)
}
DocHost:能接住「使用说明」的宿主。
与凭证契约同一个模式(小接口、可选实现):插件把自己的说明书交出来, 平台原样收下并在界面上渲染。这样「这个 key 去哪申请」「有什么坑」 跟着插件代码走,而不是散在平台前端的硬编码表、凭证字段的 placeholder 和作者的记忆里——那三处正是它现在待的地方。
type EventHost ¶
type EventHost interface {
// DeclareEvent 声明一种事件。
DeclareEvent(e contract.Event)
// DeclareEventsCommon 声明「所有事件共有」的字段(平台会平铺到触发输入顶层)。
DeclareEventsCommon(fields []contract.Field, names []string)
}
EventHost:声明事件契约的宿主。
type File ¶
type File struct {
ID string `json:"id,omitempty"` // 平台文件 id(f_…)
URL string `json:"url,omitempty"` // 平台下载路径(/api/v1/files/<id>)
Name string `json:"name,omitempty"` // 文件名
Mime string `json:"mime,omitempty"` // MIME 类型
// Size 不能 omitempty:0 字节是一个**要能被看见**的值。此前 size=0 时字段整个
// 消失,下游想写「file.size > 0」的空文件闸都无从引用(实测:空下载的输出里
// 没有 size 键,用户对着有 size 的成功样例照抄条件,永远判不中)。
Size int64 `json:"size"` // 字节数
Data []byte `json:"data,omitempty"` // 内联字节兜底(小文件/测试;正常路径为空)
}
File:平台文件引用。**只是数据**——取字节要通过 Ctx,因为那依赖传输。
json tag 与平台的文件值形态对齐,故可直接作为出参字段交出去。
type Invoke ¶
type Invoke func(ctx Ctx, raw json.RawMessage, out Sink) error
Invoke:一次调用。raw 是入参 JSON(由生成的代码解到具体类型),产出走 Sink。
type Sink ¶
type Sink interface {
// Vars 类型化输出变量(进下游节点),按 sokel tag 落为契约名。
Vars(v any)
// Text 人类可读文本(展示 / tracing,不进下游变量)。
Text(s string)
// JSON 结构化展示。
JSON(v any)
}
Sink:产出。多次调用 = 多帧(流式);非流式由传输侧缓冲合并。
type SourceCtx ¶
type SourceCtx interface {
Ctx
// Trigger 推一条事件。eventID 用于平台侧去重(同一条外部消息重复推只触发一次)。
//
// payload 收 any 而不是 map:传输侧按 sokel tag 把 struct 展成契约名(与 Sink.Vars 同一套),
// 类型安全由生成的 TriggerXxx 在外层保证——这里再收窄一次只会让生成物多一道转换。
Trigger(event, eventID string, payload any) error
// UpdateCredential 回写凭证字段(如刷新到的 token)。
UpdateCredential(patch map[string]string) error
// ReportStatus 上报本源的状态(随心跳带回平台,凭证列表上可见)。
ReportStatus(status, msg string)
}
SourceCtx:常驻事件源能用到的运行时能力。比 Ctx 多两样:推事件、改凭证。