Files
Cyrene_v2/internal/runtime/orchestration/auditcontext.go
T
AskaEth eb1828ee7a
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
docs(comments): 注释中文化 · internal/runtime/orchestration(29 文件,纯替换)
- 只翻注释/文档字符串:剥离注释后代码行逐字节不变(机械校验只剩允许的行尾注释形态)
- 裁决编号与 design 节号(02.4.3 / 11.4.2 / design/05 §9 等)逐字保留
- 复核:go build 绿;orchestration 及其子包(audit/comm)测试绿;gofmt 干净
2026-10-04 13:30:04 +08:00

92 lines
3.1 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 orchestration
import (
"context"
"fmt"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/orchestration/audit"
)
// AuditMode 选择子代理上下文为 subagent_ask 上游 WS 路由裁剪成什么形状。它与
// audit.ContextAuditor 的表面(Full/Tail/Keyword)一一对应,使网关能按客户端所请求
// 的窗口精确取用。
type AuditMode string
const (
// AuditFull 返回整段会话上下文。
AuditFull AuditMode = "full"
// AuditTail 返回上下文最后 n 条消息。
AuditTail AuditMode = "tail"
// AuditKeyword 返回首个关键词命中处附近的窗口。
AuditKeyword AuditMode = "keyword"
)
// AuditResult 是审计一个子代理会话上下文的只读结果。Messages 承载被选中的窗口;
// Line 与 Match 仅在关键词查询时填充。它是 ws.subagent_event 应答的线上载荷。
type AuditResult struct {
AgentID string `json:"agentId"`
Status Status `json:"status"`
Goal string `json:"goal,omitempty"`
Mode AuditMode `json:"mode"`
Messages []model.Message `json:"messages,omitempty"`
Line int `json:"line,omitempty"`
Match string `json:"match,omitempty"`
}
// AuditContext 返回子代理 id 的会话上下文只读视图,供 subagent_ask WS 路由使用。
// mode 选择窗口:AuditFull 返回整段上下文,AuditTail 返回最后 n 条消息,
// AuditKeyword 返回首个 query 命中处附近的窗口。未知 id 包装 ErrAgentNotFound,
// 关键词查询为空则包装 audit.ErrQueryEmpty,两者都以 %w 包装,便于调用方用
// errors.Is 归类。
func (s *Scheduler) AuditContext(ctx context.Context, id string, mode AuditMode, n int, query string) (*AuditResult, error) {
if err := ctx.Err(); err != nil {
return nil, fmt.Errorf("orchestration: audit %q: %w", id, err)
}
s.mu.Lock()
sub := s.agents[id]
s.mu.Unlock()
if sub == nil {
return nil, fmt.Errorf("orchestration: audit %q: %w", id, ErrAgentNotFound)
}
a := audit.NewContextAuditor(sub.Context)
res := &AuditResult{AgentID: sub.ID, Status: sub.Status(), Goal: sub.Goal, Mode: mode}
switch mode {
case AuditFull:
res.Messages = a.Full()
case AuditTail:
res.Messages = a.Tail(n)
case AuditKeyword:
loc, err := a.Keyword(ctx, query)
if err != nil {
return nil, fmt.Errorf("orchestration: audit %q: %w", id, err)
}
if loc == nil {
res.Messages = []model.Message{}
break
}
res.Line = loc.Line
res.Messages = loc.Surrounding
res.Match = messageText(loc.Surrounding[len(loc.Surrounding)-1])
default:
return nil, fmt.Errorf("orchestration: audit %q: unknown mode %q", id, mode)
}
return res, nil
}
// messageText 拼接一条消息的各个文本分段。它与 audit 子包自己的同名辅助函数保持一致,
// 使结果载荷能给出人类可读的命中文本,而无需导出跨包的文本提取器。
func messageText(m model.Message) string {
var text string
for _, c := range m.Content {
if c.Type == model.ContentTypeText && c.Text != "" {
if text != "" {
text += " "
}
text += c.Text
}
}
return text
}