chore(teams): remove deprecated delegation tools

Remove delegate_search, evaluate_loop, handoff from:
- Seed data, system prompt, i18n keys/catalogs, channel events
- Consumer handler (handleHandoffAnnounce), handoff route lookup
- HandoffRouteData struct + PG implementation
- Protocol events, MCP bridge comment
- Web UI locale files (en/vi/zh)
This commit is contained in:
viettranx committed 2026-03-16 22:46:18 +07:00
1 parent 514c5e0bfc
commit 3f2b6e258e
17 files changed
+38 -205

No files matched your search

-14
View File
@@ -106,20 +106,6 @@ func builtinToolSeedData() []store.BuiltinToolDef {
{Name: "use_skill", DisplayName: "Use Skill", Description: "Activate a skill to use its specialized capabilities (tracing marker)", Category: "skills", Enabled: true},
{Name: "publish_skill", DisplayName: "Publish Skill", Description: "Register a skill directory (created via skill-creator) in the system database, making it discoverable and grantable to agents", Category: "skills", Enabled: true},
// delegation (deprecated — team_tasks is the coordination mechanism now)
{Name: "delegate_search", DisplayName: "Delegate Search", Description: "Search for available delegation targets by keyword (deprecated)", Category: "delegation", Enabled: false,
Requires: []string{"managed_mode", "agent_links"},
Metadata: json.RawMessage(`{"deprecated":true}`),
},
{Name: "evaluate_loop", DisplayName: "Evaluate Loop", Description: "Run a generate→evaluate→revise loop between two agents (deprecated)", Category: "delegation", Enabled: false,
Requires: []string{"managed_mode", "agent_links"},
Metadata: json.RawMessage(`{"deprecated":true}`),
},
{Name: "handoff", DisplayName: "Handoff", Description: "Transfer the conversation to another agent (deprecated)", Category: "delegation", Enabled: false,
Requires: []string{"managed_mode", "agent_links"},
Metadata: json.RawMessage(`{"deprecated":true}`),
},
// teams
{Name: "team_tasks", DisplayName: "Team Tasks", Description: "View, create, update, and complete tasks on the team task board", Category: "teams", Enabled: true,
Requires: []string{"managed_mode", "teams"},
-3
View File
@@ -101,9 +101,6 @@ func consumeInboundMessages(ctx context.Context, msgBus *bus.MessageBus, agents
if handleDelegateAnnounce(ctx, msg, cfg, sched, channelMgr, msgBus, getAnnounceMu) {
continue
}
if handleHandoffAnnounce(ctx, msg, cfg, sched, channelMgr, msgBus) {
continue
}
if handleTeammateMessage(ctx, msg, cfg, sched, channelMgr, teamStore, agentStore, msgBus, postTurn, &taskRunSessions) {
continue
}
+36 -89
View File
@@ -309,88 +309,6 @@ func handleDelegateAnnounce(
return true
}
// handleHandoffAnnounce processes handoff announce messages: route initial message
// to target agent session using the "delegate" lane.
// Returns true if the message was handled (caller should continue).
func handleHandoffAnnounce(
ctx context.Context,
msg bus.InboundMessage,
cfg *config.Config,
sched *scheduler.Scheduler,
channelMgr *channels.Manager,
msgBus *bus.MessageBus,
) bool {
if !(msg.Channel == tools.ChannelSystem && strings.HasPrefix(msg.SenderID, "handoff:")) {
return false
}
origChannel := msg.Metadata["origin_channel"]
origPeerKind := msg.Metadata["origin_peer_kind"]
origLocalKey := msg.Metadata["origin_local_key"]
origChannelType := resolveChannelType(channelMgr, origChannel)
targetAgent := msg.AgentID
if targetAgent == "" {
targetAgent = cfg.ResolveDefaultAgentID()
}
if origPeerKind == "" {
origPeerKind = string(sessions.PeerDirect)
}
if origChannel == "" || msg.ChatID == "" {
slog.Warn("handoff announce: missing origin", "sender", msg.SenderID)
return true
}
sessionKey := sessions.BuildScopedSessionKey(targetAgent, origChannel, sessions.PeerKind(origPeerKind), msg.ChatID, cfg.Sessions.Scope, cfg.Sessions.DmScope, cfg.Sessions.MainKey)
sessionKey = overrideSessionKeyFromLocalKey(sessionKey, origLocalKey, targetAgent, origChannel, msg.ChatID, origPeerKind)
slog.Info("handoff announce → scheduler (delegate lane)",
"handoff", msg.SenderID,
"to", targetAgent,
"session", sessionKey,
)
announceUserID := msg.UserID
if origPeerKind == string(sessions.PeerGroup) && msg.ChatID != "" {
announceUserID = fmt.Sprintf("group:%s:%s", origChannel, msg.ChatID)
}
outMeta := buildAnnounceOutMeta(origLocalKey)
outCh := sched.Schedule(ctx, scheduler.LaneDelegate, agent.RunRequest{
SessionKey: sessionKey,
Message: msg.Content,
Channel: origChannel,
ChannelType: origChannelType,
ChatID: msg.ChatID,
PeerKind: origPeerKind,
LocalKey: origLocalKey,
UserID: announceUserID,
RunID: fmt.Sprintf("handoff-%s", msg.Metadata["handoff_id"]),
Stream: false,
})
go func(origCh, chatID string, meta map[string]string) {
outcome := <-outCh
if outcome.Err != nil {
slog.Error("handoff announce: agent run failed", "error", outcome.Err)
return
}
if (outcome.Result.Content == "" && len(outcome.Result.Media) == 0) || agent.IsSilentReply(outcome.Result.Content) {
return
}
outMsg := bus.OutboundMessage{
Channel: origCh,
ChatID: chatID,
Content: outcome.Result.Content,
Metadata: meta,
}
appendMediaToOutbound(&outMsg, outcome.Result.Media)
msgBus.PublishOutbound(outMsg)
}(origChannel, msg.ChatID, outMeta)
return true
}
// handleTeammateMessage processes teammate messages: bypass debounce, route to target
// agent session using the "delegate" lane, then announce result back to lead.
@@ -548,6 +466,21 @@ func handleTeammateMessage(
if !alreadyTerminal {
toAgent := inMeta["to_agent"]
now := time.Now().UTC().Format("2006-01-02T15:04:05Z")
// Enrich event payload with task details for notifications.
taskSubject := ""
taskNumber := 0
taskChannel := inMeta["origin_channel"]
taskChatID := inMeta["origin_chat_id"]
if currentTask != nil {
taskSubject = currentTask.Subject
taskNumber = currentTask.TaskNumber
if currentTask.Channel != "" {
taskChannel = currentTask.Channel
}
if currentTask.ChatID != "" {
taskChatID = currentTask.ChatID
}
}
if outcome.Err != nil {
if err := teamStore.FailTask(ctx, teamTaskID, teamID, outcome.Err.Error()); err != nil {
slog.Warn("auto-complete: FailTask error", "task_id", teamTaskID, "error", err)
@@ -555,12 +488,17 @@ func handleTeammateMessage(
msgBus.Broadcast(bus.Event{
Name: protocol.EventTeamTaskFailed,
Payload: protocol.TeamTaskEventPayload{
TeamID: teamID.String(),
TaskID: teamTaskID.String(),
Status: store.TeamTaskStatusFailed,
Timestamp: now,
ActorType: "agent",
ActorID: toAgent,
TeamID: teamID.String(),
TaskID: teamTaskID.String(),
TaskNumber: taskNumber,
Subject: taskSubject,
Status: store.TeamTaskStatusFailed,
Reason: outcome.Err.Error(),
Channel: taskChannel,
ChatID: taskChatID,
Timestamp: now,
ActorType: "agent",
ActorID: toAgent,
},
})
}
@@ -580,8 +518,12 @@ func handleTeammateMessage(
Payload: protocol.TeamTaskEventPayload{
TeamID: teamID.String(),
TaskID: teamTaskID.String(),
TaskNumber: taskNumber,
Subject: taskSubject,
Status: store.TeamTaskStatusCompleted,
OwnerAgentKey: toAgent,
Channel: taskChannel,
ChatID: taskChatID,
Timestamp: now,
ActorType: "agent",
ActorID: toAgent,
@@ -865,7 +807,12 @@ func buildTaskBoardSnapshot(ctx context.Context, teamStore store.TeamStore, team
if teamStore == nil || originTraceID == "" {
return ""
}
allTasks, err := teamStore.ListTasks(ctx, teamID, "", store.TeamTaskFilterAll, "", "", chatID, 0)
// Shared workspace: show all tasks across chats.
snapshotChatID := chatID
if team, err := teamStore.GetTeam(ctx, teamID); err == nil && tools.IsSharedWorkspace(team.Settings) {
snapshotChatID = ""
}
allTasks, err := teamStore.ListTasks(ctx, teamID, "", store.TeamTaskFilterAll, "", "", snapshotChatID, 0)
if err != nil || len(allTasks) == 0 {
return ""
}
-9
View File
@@ -43,15 +43,6 @@ func processNormalMessage(
agentID = resolveAgentRoute(cfg, msg.Channel, msg.ChatID, msg.PeerKind)
}
// Check handoff routing override
if teamStore != nil && msg.AgentID == "" {
if route, _ := teamStore.GetHandoffRoute(ctx, msg.Channel, msg.ChatID); route != nil {
agentID = route.ToAgentKey
slog.Info("inbound: handoff route active",
"channel", msg.Channel, "chat", msg.ChatID, "to", agentID)
}
}
agentLoop, err := agents.Get(agentID)
if err != nil {
slog.Warn("inbound: agent not found", "agent", agentID, "channel", msg.Channel)