Details (original message): Add the optional intentgate decorator over agent-intent with pass-through and fail-closed tests.
57 lines
2.1 KiB
Go
57 lines
2.1 KiB
Go
// Package intentgate 提供可选的意图闸门装饰器:在把 Prompt 交给被装饰的
|
|
// 执行后端之前,用 agent-intent 做一次确定性识别;分支为守卫/命中/预期命中时
|
|
// 交由宿主 Handler 解释,Ambiguous/Fallback 或 Handler 放弃时原样透传。
|
|
//
|
|
// 本包是 Agent-Native 仓内唯一 import agent-intent 的地方。不使用本包时,
|
|
// 本仓与 agent-intent 无任何编译关系;未 Wrap 或快照零意图时,被装饰后端的
|
|
// 行为与原来完全一致。
|
|
package intentgate
|
|
|
|
import (
|
|
"context"
|
|
|
|
"agent-intent/intent"
|
|
"agent-native/exec"
|
|
)
|
|
|
|
// Handler 解释"识别到意图"的执行请求。返回 handled=false 表示宿主放弃处理,
|
|
// 装饰器回退为透传原后端。合成结果的语义(拒绝、引导、定向执行)由宿主定义,
|
|
// 本包不发明结果语义。
|
|
type Handler func(ctx context.Context, req exec.Request, res intent.Result) (result *exec.Result, err error, handled bool)
|
|
|
|
type gated struct {
|
|
next exec.Backend
|
|
rec intent.Recognizer
|
|
snap *intent.Snapshot
|
|
handler Handler
|
|
}
|
|
|
|
// Wrap 返回带意图闸门的后端。next/rec/snap/handler 任一为 nil 时直接返回 next
|
|
// (等价于未启用,行为不变)。
|
|
func Wrap(next exec.Backend, rec intent.Recognizer, snap *intent.Snapshot, h Handler) exec.Backend {
|
|
if next == nil || rec == nil || snap == nil || h == nil {
|
|
return next
|
|
}
|
|
return &gated{next: next, rec: rec, snap: snap, handler: h}
|
|
}
|
|
|
|
func (g *gated) Name() string { return g.next.Name() }
|
|
|
|
func (g *gated) Execute(ctx context.Context, req exec.Request) (*exec.Result, error) {
|
|
res, err := g.rec.Recognize(ctx, req.Prompt, g.snap)
|
|
if err != nil {
|
|
// 识别系统错误 fail-closed:不静默放行可能应拦截的内容,也不吞错。
|
|
return nil, err
|
|
}
|
|
switch res.Branch {
|
|
case intent.BranchGuardHit, intent.BranchMatched, intent.BranchExpectationHit:
|
|
default:
|
|
return g.next.Execute(ctx, req) // 无裁决:透传原后端
|
|
}
|
|
out, herr, handled := g.handler(ctx, req, res)
|
|
if !handled {
|
|
return g.next.Execute(ctx, req)
|
|
}
|
|
return out, herr
|
|
}
|