Files
agent-exec-transport e942a35b73
governance / governance (pull_request) Successful in 14s
ci / vet-and-test (pull_request) Successful in 1m18s
agent-exec transport 8315c523cef26780543b9b2130f4f4a4/5c8333ec4e92
2026-10-19 12:21:32 +00:00

149 lines
6.8 KiB
Go
Raw Permalink 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"
"time"
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
// OperationID is generated by the trusted host bus before this handler runs.
// Persist it with an actual domain commit/outbox; never treat it as a retry key.
OperationID 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:页面保存/读取
// - WorkCompletionHost — X1:受信项目工作生成
// - WorkTaskHost — X1:分发期建立可恢复的受信项目任务绑定
// - HumanDecisionVerifier — 本次分发是否为认证人对确切待确认卡的响应
// - RolePolicyProvider — Backend 权威职位与动作默认/上限
// - CapabilityExplainProvider — 当前分发主体的创建者/成员/文档职责能力解释
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 之后)——
// HumanDecisionAudienceStructure is the only audience this proof can authorize.
// Another plugin cannot reuse the same human response as its own confirmation.
const HumanDecisionAudienceStructure = "rdm.structure.decide"
// HumanDecisionBinding is the exact object a human must have confirmed.
// Callers pass it to the host; they do not carry a copyable secret.
type HumanDecisionBinding struct {
Audience string
Actor string
ProjectID string
ProposalID string
ProposalRevision int
PayloadHash string
Decision string
}
// HumanDecisionCard is the pending object a person confirms.
type HumanDecisionCard struct {
CardID string
Question string
ExpiresAt time.Time
}
// HumanDecisionProof is a read-only statement that a person already responded.
// ProofID is a consumption key for the caller. The host does not mark it used.
type HumanDecisionProof struct {
ProofID string
Issuer string
HumanActor string
Audience string
ProjectID string
ProposalID string
Revision int
PayloadHash string
Decision string
IssuedAt time.Time
ExpiresAt time.Time
ConversationID string
RunID string
HITLResponseRef string
}
// HumanDecisionVerifier is optional. A missing assertion means the capability
// is absent and the caller must refuse the write.
type HumanDecisionVerifier interface {
IssueHumanDecision(binding HumanDecisionBinding, question string) (HumanDecisionCard, error)
VerifyHumanDecision(expected HumanDecisionBinding) (HumanDecisionProof, error)
RevokeHumanDecision(cardID string) error
}