diff --git a/packages/core/src/agents/a2aUtils.test.ts b/packages/core/src/agents/a2aUtils.test.ts index 0527b54bdd..dcb911f2c0 100644 --- a/packages/core/src/agents/a2aUtils.test.ts +++ b/packages/core/src/agents/a2aUtils.test.ts @@ -124,7 +124,7 @@ describe('a2aUtils', () => { }); describe('extractTaskText', () => { - it('should extract basic task info', () => { + it('should extract basic task info (clean)', () => { const task: Task = { id: 'task-1', contextId: 'ctx-1', @@ -141,12 +141,12 @@ describe('a2aUtils', () => { }; const result = extractTaskText(task); - expect(result).toContain('ID: task-1'); - expect(result).toContain('State: working'); - expect(result).toContain('Status Message: Processing...'); + expect(result).not.toContain('ID: task-1'); + expect(result).not.toContain('State: working'); + expect(result).toBe('Processing...'); }); - it('should extract artifacts', () => { + it('should extract artifacts with headers', () => { const task: Task = { id: 'task-1', contextId: 'ctx-1', @@ -162,10 +162,10 @@ describe('a2aUtils', () => { }; const result = extractTaskText(task); - expect(result).toContain('Artifacts:'); - expect(result).toContain(' - Name: Report'); - expect(result).toContain(' Content:'); - expect(result).toContain(' This is the report.'); + expect(result).toContain('Artifact (Report):'); + expect(result).toContain('This is the report.'); + expect(result).not.toContain('Artifacts:'); + expect(result).not.toContain(' - Name: Report'); }); }); }); diff --git a/packages/core/src/agents/a2aUtils.ts b/packages/core/src/agents/a2aUtils.ts index fc19eceb05..311658118b 100644 --- a/packages/core/src/agents/a2aUtils.ts +++ b/packages/core/src/agents/a2aUtils.ts @@ -18,14 +18,11 @@ import type { * Handles Text, Data (JSON), and File parts. */ export function extractMessageText(message: Message | undefined): string { - if (!message || !message.parts) { + if (!message) { return ''; } - const parts = message.parts - .map((part) => extractPartText(part)) - .filter(Boolean); - return parts.join('\n'); + return extractPartsText(message.parts); } /** @@ -56,41 +53,47 @@ export function extractPartText(part: Part): string { } /** - * Extracts a human-readable text summary from a Task object. - * Includes status, ID, and any artifact content. + * Extracts a clean, human-readable text summary from a Task object. + * Includes the status message and any artifact content with context headers. + * Technical metadata like ID and State are omitted for better clarity and token efficiency. */ export function extractTaskText(task: Task): string { - let output = `ID: ${task.id}\n`; - output += `State: ${task.status.state}\n`; + const parts: string[] = []; // Status Message - const statusMessageText = extractMessageText(task.status.message); + const statusMessageText = extractMessageText(task.status?.message); if (statusMessageText) { - output += `Status Message: ${statusMessageText}\n`; + parts.push(statusMessageText); } // Artifacts - if (task.artifacts && task.artifacts.length > 0) { - output += `Artifacts:\n`; + if (task.artifacts) { for (const artifact of task.artifacts) { - output += ` - Name: ${artifact.name}\n`; - if (artifact.parts && artifact.parts.length > 0) { - // Treat artifact parts as a message for extraction - const artifactContent = artifact.parts - .map((p) => extractPartText(p)) - .filter(Boolean) - .join('\n'); + const artifactContent = extractPartsText(artifact.parts); - if (artifactContent) { - // Indent content for readability - const indentedContent = artifactContent.replace(/^/gm, ' '); - output += ` Content:\n${indentedContent}\n`; - } + if (artifactContent) { + const header = artifact.name + ? `Artifact (${artifact.name}):` + : 'Artifact:'; + parts.push(`${header}\n${artifactContent}`); } } } - return output; + return parts.join('\n\n'); +} + +/** + * Extracts text from an array of parts. + */ +function extractPartsText(parts: Part[] | undefined): string { + if (!parts || parts.length === 0) { + return ''; + } + return parts + .map((p) => extractPartText(p)) + .filter(Boolean) + .join('\n'); } // Type Guards diff --git a/packages/core/src/agents/remote-invocation.ts b/packages/core/src/agents/remote-invocation.ts index 9acb7794ea..a5894c37b4 100644 --- a/packages/core/src/agents/remote-invocation.ts +++ b/packages/core/src/agents/remote-invocation.ts @@ -166,16 +166,16 @@ export class RemoteAgentInvocation extends BaseToolInvocation< }); // Extract the output text - const resultData = response; - let outputText = ''; + const outputText = + response.kind === 'task' + ? extractTaskText(response) + : response.kind === 'message' + ? extractMessageText(response) + : JSON.stringify(response); - if (resultData.kind === 'message') { - outputText = extractMessageText(resultData); - } else if (resultData.kind === 'task') { - outputText = extractTaskText(resultData); - } else { - outputText = JSON.stringify(resultData); - } + debugLogger.debug( + `[RemoteAgent] Response from ${this.definition.name}:\n${JSON.stringify(response, null, 2)}`, + ); return { llmContent: [{ text: outputText }],