You've already forked agentic-coding-workflow
bugfix
This commit is contained in:
+104
-15
@@ -12,15 +12,17 @@ import (
|
||||
)
|
||||
|
||||
// MCPBridge 适配 AgentKind/Session/Permission 三个服务到 mcp.ACPBridge。
|
||||
// repo 仅用于只读的回合列表(ListSessionTurns)——scope 校验先经 sessions.Get 完成。
|
||||
type MCPBridge struct {
|
||||
kinds AgentKindService
|
||||
sessions SessionService
|
||||
perms *PermissionService
|
||||
repo Repository
|
||||
}
|
||||
|
||||
// NewMCPBridge 构造桥接适配器,由 app.go 装配 mcp.ServerDeps 时调用。
|
||||
func NewMCPBridge(kinds AgentKindService, sessions SessionService, perms *PermissionService) *MCPBridge {
|
||||
return &MCPBridge{kinds: kinds, sessions: sessions, perms: perms}
|
||||
func NewMCPBridge(kinds AgentKindService, sessions SessionService, perms *PermissionService, repo Repository) *MCPBridge {
|
||||
return &MCPBridge{kinds: kinds, sessions: sessions, perms: perms, repo: repo}
|
||||
}
|
||||
|
||||
var _ mcp.ACPBridge = (*MCPBridge)(nil)
|
||||
@@ -109,6 +111,86 @@ func (b *MCPBridge) ListPendingPermissions(ctx context.Context, userID uuid.UUID
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ListPendingApprovals 返回调用者跨所有会话的待审权限请求(HITL inbox,read-only)。
|
||||
func (b *MCPBridge) ListPendingApprovals(ctx context.Context, userID uuid.UUID, isAdmin bool) ([]mcp.ACPPermission, error) {
|
||||
ps, err := b.perms.ListPendingForUser(ctx, Caller{UserID: userID, IsAdmin: isAdmin})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]mcp.ACPPermission, 0, len(ps))
|
||||
for _, p := range ps {
|
||||
out = append(out, mcp.ACPPermission{
|
||||
ID: p.ID,
|
||||
SessionID: p.SessionID,
|
||||
AgentRequestID: p.AgentRequestID,
|
||||
ToolName: p.ToolName,
|
||||
Status: string(p.Status),
|
||||
CreatedAt: p.CreatedAt,
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ListSessionTurns 返回会话的回合列表(只读)。先经 sessions.Get 做用户 + 项目
|
||||
// scope 校验(与 GetSession 同语义),再用 repo 读 acp_turns。
|
||||
func (b *MCPBridge) ListSessionTurns(ctx context.Context, userID uuid.UUID, isAdmin bool, sessionID uuid.UUID) ([]mcp.ACPTurn, error) {
|
||||
if _, err := b.sessions.Get(ctx, Caller{UserID: userID, IsAdmin: isAdmin}, sessionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ts, err := b.repo.ListTurnsBySession(ctx, sessionID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]mcp.ACPTurn, 0, len(ts))
|
||||
for _, t := range ts {
|
||||
out = append(out, mcp.ACPTurn{
|
||||
TurnIndex: t.TurnIndex,
|
||||
Status: string(t.Status),
|
||||
StopReason: t.StopReason,
|
||||
UpdateCount: t.UpdateCount,
|
||||
StartedAt: t.StartedAt,
|
||||
CompletedAt: t.CompletedAt,
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetRunDashboard 返回 run-history 汇总(owner scope;admin 全量,read-only)。
|
||||
func (b *MCPBridge) GetRunDashboard(ctx context.Context, userID uuid.UUID, isAdmin bool, in mcp.ACPRunDashboardInput) (*mcp.ACPRunDashboard, error) {
|
||||
res, err := b.sessions.Dashboard(ctx, Caller{UserID: userID, IsAdmin: isAdmin}, DashboardInput{
|
||||
ProjectID: in.ProjectID,
|
||||
RequirementID: in.RequirementID,
|
||||
From: in.From,
|
||||
To: in.To,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := &mcp.ACPRunDashboard{
|
||||
From: res.From,
|
||||
To: res.To,
|
||||
Total: res.Rollup.Total,
|
||||
Succeeded: res.Rollup.Succeeded,
|
||||
Crashed: res.Rollup.Crashed,
|
||||
Active: res.Rollup.Active,
|
||||
SuccessRate: res.Rollup.SuccessRate(),
|
||||
TotalCostUSD: res.Rollup.TotalCostUSD,
|
||||
TotalTokens: res.Rollup.TotalTokens,
|
||||
AvgDurationSeconds: res.Rollup.AvgDurationSeconds,
|
||||
ByDay: make([]mcp.ACPRunDayRow, 0, len(res.ByDay)),
|
||||
}
|
||||
for _, d := range res.ByDay {
|
||||
out.ByDay = append(out.ByDay, mcp.ACPRunDayRow{
|
||||
Day: d.Day,
|
||||
Total: d.Total,
|
||||
Succeeded: d.Succeeded,
|
||||
Crashed: d.Crashed,
|
||||
TotalCostUSD: d.TotalCostUSD,
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func agentKindToMCP(k *AgentKind) mcp.ACPAgentKind {
|
||||
return mcp.ACPAgentKind{
|
||||
ID: k.ID,
|
||||
@@ -122,18 +204,25 @@ func agentKindToMCP(k *AgentKind) mcp.ACPAgentKind {
|
||||
|
||||
func sessionToMCP(s *Session) mcp.ACPSession {
|
||||
return mcp.ACPSession{
|
||||
ID: s.ID,
|
||||
WorkspaceID: s.WorkspaceID,
|
||||
ProjectID: s.ProjectID,
|
||||
AgentKindID: s.AgentKindID,
|
||||
UserID: s.UserID,
|
||||
IssueID: s.IssueID,
|
||||
RequirementID: s.RequirementID,
|
||||
Branch: s.Branch,
|
||||
IsMainWorktree: s.IsMainWorktree,
|
||||
Status: string(s.Status),
|
||||
LastError: s.LastError,
|
||||
StartedAt: s.StartedAt,
|
||||
EndedAt: s.EndedAt,
|
||||
ID: s.ID,
|
||||
WorkspaceID: s.WorkspaceID,
|
||||
ProjectID: s.ProjectID,
|
||||
AgentKindID: s.AgentKindID,
|
||||
UserID: s.UserID,
|
||||
IssueID: s.IssueID,
|
||||
RequirementID: s.RequirementID,
|
||||
Branch: s.Branch,
|
||||
IsMainWorktree: s.IsMainWorktree,
|
||||
Status: string(s.Status),
|
||||
LastError: s.LastError,
|
||||
LastStopReason: s.LastStopReason,
|
||||
StartedAt: s.StartedAt,
|
||||
EndedAt: s.EndedAt,
|
||||
PromptTokens: s.PromptTokens,
|
||||
CompletionTokens: s.CompletionTokens,
|
||||
ThinkingTokens: s.ThinkingTokens,
|
||||
TotalCostUSD: s.TotalCostUSD,
|
||||
BudgetMaxCostUSD: s.BudgetMaxCostUSD,
|
||||
BudgetMaxTokens: s.BudgetMaxTokens,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user