From 0d0364cfd3b5f9bb2fd8f2feca2ce198af56d129 Mon Sep 17 00:00:00 2001 From: iliya Date: Wed, 18 Mar 2026 14:01:21 +0200 Subject: [PATCH] feat: introduce MEMBER_DELEGATE_DESCRIPTION for action mode protocols - Added MEMBER_DELEGATE_DESCRIPTION constant to centralize the delegate instructions for action mode protocols, improving code maintainability. - Updated buildActionModeProtocolText to utilize the new constant, enhancing clarity and reducing duplication. - Enhanced messageStore and TeamProvisioningService to support filePath handling in attachments, improving metadata management. - Updated type definitions to reflect the addition of MEMBER_DELEGATE_DESCRIPTION in the protocols interface. --- agent-teams-controller/src/controller.js | 1 + agent-teams-controller/src/internal/messageStore.js | 3 +++ agent-teams-controller/src/internal/tasks.js | 8 +++++--- mcp-server/src/agent-teams-controller.d.ts | 1 + src/main/services/team/TeamProvisioningService.ts | 8 ++++---- src/main/services/team/TeamTaskReader.ts | 6 ++++++ src/types/agent-teams-controller.d.ts | 1 + 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/agent-teams-controller/src/controller.js b/agent-teams-controller/src/controller.js index 987b92d9..f48f29b7 100644 --- a/agent-teams-controller/src/controller.js +++ b/agent-teams-controller/src/controller.js @@ -40,6 +40,7 @@ module.exports = { agentBlocks, protocols: { buildActionModeProtocolText: tasks.buildActionModeProtocolText, + MEMBER_DELEGATE_DESCRIPTION: tasks.MEMBER_DELEGATE_DESCRIPTION, buildProcessProtocolText: tasks.buildProcessProtocolText, }, tasks, diff --git a/agent-teams-controller/src/internal/messageStore.js b/agent-teams-controller/src/internal/messageStore.js index c966edd7..9a88f8fe 100644 --- a/agent-teams-controller/src/internal/messageStore.js +++ b/agent-teams-controller/src/internal/messageStore.js @@ -45,6 +45,9 @@ function normalizeAttachments(attachments) { filename: String(item.filename || '').trim(), mimeType: String(item.mimeType || '').trim(), size: Number(item.size || 0), + ...(typeof item.filePath === 'string' && item.filePath.trim() + ? { filePath: item.filePath.trim() } + : {}), })) .filter((item) => item.id && item.filename && item.mimeType && Number.isFinite(item.size)); diff --git a/agent-teams-controller/src/internal/tasks.js b/agent-teams-controller/src/internal/tasks.js index c5c0a17e..f245664e 100644 --- a/agent-teams-controller/src/internal/tasks.js +++ b/agent-teams-controller/src/internal/tasks.js @@ -368,10 +368,11 @@ function buildActionModeProtocolText(delegateDescription) { ].join('\n'); } +const MEMBER_DELEGATE_DESCRIPTION = + 'Do not implement yourself. Pass the task with full context (what you know, what is needed) to your team lead or another teammate and let them handle it.'; + function buildMemberActionModeProtocol() { - return buildActionModeProtocolText( - 'Do not implement yourself. Pass the task with full context (what you know, what is needed) to your team lead or another teammate and let them handle it.' - ); + return buildActionModeProtocolText(MEMBER_DELEGATE_DESCRIPTION); } function buildMemberTaskProtocol(teamName) { @@ -616,6 +617,7 @@ module.exports = { softDeleteTask, startTask, buildActionModeProtocolText, + MEMBER_DELEGATE_DESCRIPTION, buildProcessProtocolText, memberBriefing, taskBriefing, diff --git a/mcp-server/src/agent-teams-controller.d.ts b/mcp-server/src/agent-teams-controller.d.ts index 188dd1c0..fcf7b3e1 100644 --- a/mcp-server/src/agent-teams-controller.d.ts +++ b/mcp-server/src/agent-teams-controller.d.ts @@ -102,6 +102,7 @@ declare module 'agent-teams-controller' { /** Context-free protocol text builders, shared across lead and member prompts. */ export interface ProtocolsApi { buildActionModeProtocolText(delegateDescription: string): string; + MEMBER_DELEGATE_DESCRIPTION: string; buildProcessProtocolText(teamName: string): string; } diff --git a/src/main/services/team/TeamProvisioningService.ts b/src/main/services/team/TeamProvisioningService.ts index a87673c0..9804c48f 100644 --- a/src/main/services/team/TeamProvisioningService.ts +++ b/src/main/services/team/TeamProvisioningService.ts @@ -99,8 +99,6 @@ import type { const logger = createLogger('Service:TeamProvisioning'); const { createController, protocols } = agentTeamsControllerModule; const TEAM_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,127}$/; -const MEMBER_DELEGATE_DESCRIPTION = - 'Do not implement yourself. Pass the task with full context (what you know, what is needed) to your team lead or another teammate and let them handle it.'; const RUN_TIMEOUT_MS = 300_000; const VERIFY_TIMEOUT_MS = 15_000; const VERIFY_POLL_MS = 500; @@ -423,7 +421,9 @@ function buildMemberSpawnPrompt( const workflowBlock = member.workflow?.trim() ? `\n\nYour workflow and how you should behave:${formatWorkflowBlock(member.workflow, '')}` : ''; - const actionModeProtocol = protocols.buildActionModeProtocolText(MEMBER_DELEGATE_DESCRIPTION); + const actionModeProtocol = protocols.buildActionModeProtocolText( + protocols.MEMBER_DELEGATE_DESCRIPTION + ); return `You are ${member.name}, a ${role} on team "${displayName}" (${teamName}).${workflowBlock} ${getAgentLanguageInstruction()} @@ -455,7 +455,7 @@ function buildReconnectMemberSpawnPrompt( ? `\n\nYour workflow and how you should behave:${formatWorkflowBlock(member.workflow, ' ')}` : ''; const actionModeProtocol = indentMultiline( - protocols.buildActionModeProtocolText(MEMBER_DELEGATE_DESCRIPTION), + protocols.buildActionModeProtocolText(protocols.MEMBER_DELEGATE_DESCRIPTION), ' ' ); return ` For "${member.name}": diff --git a/src/main/services/team/TeamTaskReader.ts b/src/main/services/team/TeamTaskReader.ts index 45b84829..d5091d05 100644 --- a/src/main/services/team/TeamTaskReader.ts +++ b/src/main/services/team/TeamTaskReader.ts @@ -253,6 +253,9 @@ export class TeamTaskReader { mimeType: String(a.mimeType).trim(), size: a.size, addedAt: a.addedAt, + ...('filePath' in a && typeof a.filePath === 'string' + ? { filePath: a.filePath } + : {}), })); return filtered.length > 0 ? filtered : undefined; })() @@ -288,6 +291,9 @@ export class TeamTaskReader { mimeType: String(a.mimeType).trim(), size: a.size, addedAt: a.addedAt, + ...(a.filePath != null && typeof a.filePath === 'string' + ? { filePath: a.filePath } + : {}), })) : undefined, reviewState: getReviewStateFromTask({ diff --git a/src/types/agent-teams-controller.d.ts b/src/types/agent-teams-controller.d.ts index d75b2c71..7c173299 100644 --- a/src/types/agent-teams-controller.d.ts +++ b/src/types/agent-teams-controller.d.ts @@ -89,6 +89,7 @@ declare module 'agent-teams-controller' { /** Context-free protocol text builders, shared across lead and member prompts. */ export interface ProtocolsApi { buildActionModeProtocolText(delegateDescription: string): string; + MEMBER_DELEGATE_DESCRIPTION: string; buildProcessProtocolText(teamName: string): string; }