You've already forked agentic-coding-workflow
修改
This commit is contained in:
+33
-16
@@ -47,17 +47,22 @@ type Supervisor struct {
|
||||
mu sync.RWMutex
|
||||
procs map[uuid.UUID]*Process
|
||||
|
||||
repo Repository
|
||||
audit audit.Recorder
|
||||
notify *notify.Dispatcher
|
||||
repo Repository
|
||||
audit audit.Recorder
|
||||
notify *notify.Dispatcher
|
||||
wtSvc workspace.WorktreeService
|
||||
wsRepo workspace.Repository
|
||||
mcpTokens mcp.TokenService // spec §6.3 — onExit revokes system token
|
||||
crypto *crypto.Encryptor
|
||||
cfg SupervisorConfig
|
||||
log *slog.Logger
|
||||
permSvc *PermissionService // 工具调用权限审批;可为 nil(部分测试)
|
||||
cfg SupervisorConfig
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
// SetPermissionService 注入权限审批服务。与 Supervisor 互相依赖,故装配时回填
|
||||
// (permSvc 需要 Supervisor 作为 RelayLocator,Supervisor 需要 permSvc 注入 handler)。
|
||||
func (s *Supervisor) SetPermissionService(p *PermissionService) { s.permSvc = p }
|
||||
|
||||
// NewSupervisor 构造空 Supervisor。Start 不需要 — supervisor 是被动的(spawn 时
|
||||
// 起 goroutine,无主循环)。Stop 在 ShutdownAll 中实现。
|
||||
func NewSupervisor(repo Repository, rec audit.Recorder, disp *notify.Dispatcher,
|
||||
@@ -68,16 +73,16 @@ func NewSupervisor(repo Repository, rec audit.Recorder, disp *notify.Dispatcher,
|
||||
log = slog.Default()
|
||||
}
|
||||
return &Supervisor{
|
||||
procs: map[uuid.UUID]*Process{},
|
||||
repo: repo,
|
||||
audit: rec,
|
||||
notify: disp,
|
||||
wtSvc: wtSvc,
|
||||
wsRepo: wsRepo,
|
||||
procs: map[uuid.UUID]*Process{},
|
||||
repo: repo,
|
||||
audit: rec,
|
||||
notify: disp,
|
||||
wtSvc: wtSvc,
|
||||
wsRepo: wsRepo,
|
||||
mcpTokens: mcpTokens,
|
||||
crypto: enc,
|
||||
cfg: cfg,
|
||||
log: log,
|
||||
crypto: enc,
|
||||
cfg: cfg,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +100,7 @@ type Process struct {
|
||||
Stderr io.ReadCloser
|
||||
Relay *Relay
|
||||
|
||||
StderrBuf *stderrRing // 排障 ring buffer
|
||||
StderrBuf *stderrRing // 排障 ring buffer
|
||||
StartedAt time.Time
|
||||
KilledByUs atomic.Bool // true → exited,false → crashed
|
||||
done chan struct{} // monitor 退出时 close
|
||||
@@ -185,13 +190,17 @@ func (s *Supervisor) Spawn(ctx context.Context, sess *Session, kind *AgentKind,
|
||||
return nil, fmt.Errorf("start: %w", err)
|
||||
}
|
||||
|
||||
var decider handlers.PermissionDecider
|
||||
if s.permSvc != nil {
|
||||
decider = s.permSvc
|
||||
}
|
||||
relay := NewRelay(
|
||||
sess.ID,
|
||||
NewDecoder(stdout, s.cfg.EventMaxPayload),
|
||||
NewEncoder(stdin),
|
||||
s.repo,
|
||||
handlers.NewFsHandler(),
|
||||
handlers.NewPermissionHandler(),
|
||||
handlers.NewPermissionHandler(decider),
|
||||
RelayConfig{
|
||||
EventMaxPayload: s.cfg.EventMaxPayload,
|
||||
EventTruncateField: s.cfg.EventTruncateField,
|
||||
@@ -227,6 +236,7 @@ func (s *Supervisor) Spawn(ctx context.Context, sess *Session, kind *AgentKind,
|
||||
UserID: sess.UserID,
|
||||
CwdPath: sess.CwdPath,
|
||||
AgentSessionID: sess.AgentSessionID,
|
||||
ToolAllowlist: kind.ToolAllowlist,
|
||||
})
|
||||
|
||||
if err := s.handshake(ctx, sess, relay, proc); err != nil {
|
||||
@@ -441,6 +451,13 @@ func (s *Supervisor) onExit(ctx context.Context, proc *Process, status SessionSt
|
||||
}
|
||||
}
|
||||
_ = waitErr // 已通过 KilledByUs / ExitError 编码到 status / exitCode
|
||||
|
||||
// 终止会话的全部挂起权限请求:标 expired 并唤醒阻塞的 Decide goroutine,
|
||||
// 避免 agent 端永久挂起。须在 Relay.Close 之前(Close 后 FanoutControl 静默丢弃)。
|
||||
if s.permSvc != nil {
|
||||
s.permSvc.CancelSession(ctx, proc.SessionID)
|
||||
}
|
||||
|
||||
// Revoke session's system MCP tokens (spec §6.3)
|
||||
if s.mcpTokens != nil {
|
||||
if err := s.mcpTokens.RevokeBySession(ctx, proc.SessionID); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user