Files
Agent-System-Backend/pkg/extension/host.go
T
weichen 4ae125a3ef
ci / vet-and-test (pull_request) Successful in 57s
Add AdminProvider capability and HostProjectID context (EXT-18)
Why: RDM KTD4 dual-layer admin requires base isAdmin visibility (superuser slot); KTD5 host-project binding needs trusted current-project context.

Evidence: SELF 4 ext18 tests pass + surface snapshot regenerated + full pkg/extension + internal/app suites green.

Impact: extension.Request gains HostProjectID; optional AdminProvider interface (EXT-17 pattern); inprocHost implements IsAdmin via GetUserAuthState; three dispatch sites set HostProjectID from conversation.

Refs: RDM docs/proposals U1 base extension requests
2026-10-11 16:23:15 +00:00

90 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package extension
import (
"context"
core "agent-system-core"
)
// Request 是进程内命令处理器收到的一次分发请求(cmdbus.Request 的子集)。
type Request struct {
ID string
Params map[string]any
Entrance string // button | card | slash | chat | api(归一)
Actor string
Owner string
ConversationID string
// HostProjectID 本次分发所属基座项目(EXT-18 可选上下文;空=无项目
// 上下文——API 入口无对话或对话未关联项目时为零值)。下游按显式映射
// 解析(如 RDM rdm_host_project_map),不得据此替代自身授权判定。
HostProjectID string
}
// AdminProvider 是 EXT-18 可选能力接口:调用方平台管理角色查询。
// 通过对分发 Host 句柄做类型断言获取(断言失败=能力缺失,明确报错不降级)。
// 语义:IsAdmin() 返回本次分发主体(Actor)是否持基座平台管理角色。
// 下游不得将此作为唯一授权依据——须与自身权限体系组合(如 RDM KTD4 双层)。
type AdminProvider interface {
// IsAdmin 报告本次分发主体是否为基座平台管理员(accounts.is_admin)。
// 非 dispatch 上下文(EXT-11 scoped host)无 Actor 时恒返回 false。
IsAdmin() bool
}
// Handler 是下游注册的进程内命令处理器:每次分发由基座构造 owner 作用域的
// Host 句柄传入,处理器经句柄访问基座能力,不得自行越权持有 owner 凭证。
type Handler func(ctx context.Context, h Host, req Request) (any, error)
// Host 是基座在分发时构造的 owner 作用域宿主句柄(EXT-1 最小集 + EXT-5 解析)。
// 所有能力的可见范围都以本次分发的 Owner 为准;artifacts 只读
// (写入属完整集,另行评估)。实现由基座 internal 提供。
//
// 可选能力接口(type assertion 获取,断言失败=明确报错):
// - AdminProvider — EXT-18:调用方平台管理角色查询
// - SurfaceHost — EXT-17:页面保存/读取
type Host interface {
// PluginID 返回注册处理器的插件标识(形如 rdm)。
PluginID() string
// Owner 返回本次分发的作用域 owner。
Owner() string
// KVPut/KVGet 插件 KV(按 pluginID+owner 隔离)。
KVPut(key, value string) error
KVGet(key string) (value string, ok bool, err error)
// Audit 写一条 owner 名下的审计事件。
Audit(action, target, evidence string) error
// Complete 经基座 LLM 路由补全(owner 的模型配置生效)。
Complete(ctx context.Context, prompt string) (string, error)
// KnowledgePublish 幂等发布(EXT-9):按 docs 的 ref 整批替换——先清该 owner
// 下相同 ref 的旧行与旧向量,再走 KnowledgeWrite 语义(Owner/Source 强制同彼)。
// 重试产生相同结果;embed=true 时重建向量。
KnowledgePublish(ctx context.Context, docs []core.KnowledgeDoc, embed bool) error
// KnowledgeDelete 撤销本插件来源的知识索引(EXT-9):sourcePrefix 必须是
// "plugin:<本插件ID>"——manual 或他人来源拒绝;删除行与向量,幂等(无匹配不报错)。
KnowledgeDelete(ctx context.Context, sourcePrefix string) error
// KnowledgeSearch 混合检索(owner 可见范围)。
KnowledgeSearch(ctx context.Context, projectID core.ID, text string, topK int) ([]core.RetrievalHit, error)
// KnowledgeWrite 写知识分块;embed=true 时同步建向量(失败降级纯全文)。
// docs 各项的 Owner 由基座强制改写为本次 owner;Source 为空补 "plugin:<PluginID>"。
KnowledgeWrite(ctx context.Context, docs []core.KnowledgeDoc, embed bool) error
// TaskCreate/TaskUpdate 后台任务台账(进度/状态记账,执行体由下游自跑)。
TaskCreate(kind, title, conversationID string) (taskID string, err error)
TaskUpdate(taskID, status string, progress int, errText string) error
// ArtifactGet/ArtifactContent 工件只读(R1-3 ingest 读原件)。
ArtifactGet(artifactID string) (core.Artifact, error)
ArtifactContent(artifactID string) ([]byte, error)
// ParseDocument 用基座内置解析器把文档字节解析为 ParsedDocument(EXT-5)。
// 纯计算,不读写 owner 数据——要解析工件原件先经 ArtifactContent 取字节,
// owner 作用域由它保证。按扩展名分派;不可解析返回带 Warnings 的文档
//(显式失败),只有 ctx 取消与输入超过 100MiB 两种情况返回 error。
ParseDocument(ctx context.Context, filename, mime string, content []byte) (core.ParsedDocument, error)
}
// —— AdminProvider 定义移至本文件上方(Request 之后)——