mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
refactor: clean up A2A task output for users and LLMs (#16561)
This commit is contained in:
@@ -124,7 +124,7 @@ describe('a2aUtils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('extractTaskText', () => {
|
describe('extractTaskText', () => {
|
||||||
it('should extract basic task info', () => {
|
it('should extract basic task info (clean)', () => {
|
||||||
const task: Task = {
|
const task: Task = {
|
||||||
id: 'task-1',
|
id: 'task-1',
|
||||||
contextId: 'ctx-1',
|
contextId: 'ctx-1',
|
||||||
@@ -141,12 +141,12 @@ describe('a2aUtils', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const result = extractTaskText(task);
|
const result = extractTaskText(task);
|
||||||
expect(result).toContain('ID: task-1');
|
expect(result).not.toContain('ID: task-1');
|
||||||
expect(result).toContain('State: working');
|
expect(result).not.toContain('State: working');
|
||||||
expect(result).toContain('Status Message: Processing...');
|
expect(result).toBe('Processing...');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract artifacts', () => {
|
it('should extract artifacts with headers', () => {
|
||||||
const task: Task = {
|
const task: Task = {
|
||||||
id: 'task-1',
|
id: 'task-1',
|
||||||
contextId: 'ctx-1',
|
contextId: 'ctx-1',
|
||||||
@@ -162,10 +162,10 @@ describe('a2aUtils', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const result = extractTaskText(task);
|
const result = extractTaskText(task);
|
||||||
expect(result).toContain('Artifacts:');
|
expect(result).toContain('Artifact (Report):');
|
||||||
expect(result).toContain(' - Name: Report');
|
expect(result).toContain('This is the report.');
|
||||||
expect(result).toContain(' Content:');
|
expect(result).not.toContain('Artifacts:');
|
||||||
expect(result).toContain(' This is the report.');
|
expect(result).not.toContain(' - Name: Report');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,14 +18,11 @@ import type {
|
|||||||
* Handles Text, Data (JSON), and File parts.
|
* Handles Text, Data (JSON), and File parts.
|
||||||
*/
|
*/
|
||||||
export function extractMessageText(message: Message | undefined): string {
|
export function extractMessageText(message: Message | undefined): string {
|
||||||
if (!message || !message.parts) {
|
if (!message) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const parts = message.parts
|
return extractPartsText(message.parts);
|
||||||
.map((part) => extractPartText(part))
|
|
||||||
.filter(Boolean);
|
|
||||||
return parts.join('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,41 +53,47 @@ export function extractPartText(part: Part): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts a human-readable text summary from a Task object.
|
* Extracts a clean, human-readable text summary from a Task object.
|
||||||
* Includes status, ID, and any artifact content.
|
* 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 {
|
export function extractTaskText(task: Task): string {
|
||||||
let output = `ID: ${task.id}\n`;
|
const parts: string[] = [];
|
||||||
output += `State: ${task.status.state}\n`;
|
|
||||||
|
|
||||||
// Status Message
|
// Status Message
|
||||||
const statusMessageText = extractMessageText(task.status.message);
|
const statusMessageText = extractMessageText(task.status?.message);
|
||||||
if (statusMessageText) {
|
if (statusMessageText) {
|
||||||
output += `Status Message: ${statusMessageText}\n`;
|
parts.push(statusMessageText);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Artifacts
|
// Artifacts
|
||||||
if (task.artifacts && task.artifacts.length > 0) {
|
if (task.artifacts) {
|
||||||
output += `Artifacts:\n`;
|
|
||||||
for (const artifact of task.artifacts) {
|
for (const artifact of task.artifacts) {
|
||||||
output += ` - Name: ${artifact.name}\n`;
|
const artifactContent = extractPartsText(artifact.parts);
|
||||||
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');
|
|
||||||
|
|
||||||
if (artifactContent) {
|
if (artifactContent) {
|
||||||
// Indent content for readability
|
const header = artifact.name
|
||||||
const indentedContent = artifactContent.replace(/^/gm, ' ');
|
? `Artifact (${artifact.name}):`
|
||||||
output += ` Content:\n${indentedContent}\n`;
|
: '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
|
// Type Guards
|
||||||
|
|||||||
@@ -166,16 +166,16 @@ export class RemoteAgentInvocation extends BaseToolInvocation<
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Extract the output text
|
// Extract the output text
|
||||||
const resultData = response;
|
const outputText =
|
||||||
let outputText = '';
|
response.kind === 'task'
|
||||||
|
? extractTaskText(response)
|
||||||
|
: response.kind === 'message'
|
||||||
|
? extractMessageText(response)
|
||||||
|
: JSON.stringify(response);
|
||||||
|
|
||||||
if (resultData.kind === 'message') {
|
debugLogger.debug(
|
||||||
outputText = extractMessageText(resultData);
|
`[RemoteAgent] Response from ${this.definition.name}:\n${JSON.stringify(response, null, 2)}`,
|
||||||
} else if (resultData.kind === 'task') {
|
);
|
||||||
outputText = extractTaskText(resultData);
|
|
||||||
} else {
|
|
||||||
outputText = JSON.stringify(resultData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
llmContent: [{ text: outputText }],
|
llmContent: [{ text: outputText }],
|
||||||
|
|||||||
Reference in New Issue
Block a user