mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 18:44:30 -07:00
172 lines
4.7 KiB
TypeScript
172 lines
4.7 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
extractMessageText,
|
|
extractTaskText,
|
|
extractIdsFromResponse,
|
|
} from './a2aUtils.js';
|
|
import type { Message, Task, TextPart, DataPart, FilePart } from '@a2a-js/sdk';
|
|
|
|
describe('a2aUtils', () => {
|
|
describe('extractIdsFromResponse', () => {
|
|
it('should extract IDs from a message response', () => {
|
|
const message: Message = {
|
|
kind: 'message',
|
|
role: 'agent',
|
|
messageId: 'm1',
|
|
contextId: 'ctx-1',
|
|
taskId: 'task-1',
|
|
parts: [],
|
|
};
|
|
|
|
const result = extractIdsFromResponse(message);
|
|
expect(result).toEqual({ contextId: 'ctx-1', taskId: 'task-1' });
|
|
});
|
|
|
|
it('should extract IDs from an in-progress task response', () => {
|
|
const task: Task = {
|
|
id: 'task-2',
|
|
contextId: 'ctx-2',
|
|
kind: 'task',
|
|
status: { state: 'working' },
|
|
};
|
|
|
|
const result = extractIdsFromResponse(task);
|
|
expect(result).toEqual({ contextId: 'ctx-2', taskId: 'task-2' });
|
|
});
|
|
});
|
|
|
|
describe('extractMessageText', () => {
|
|
it('should extract text from simple text parts', () => {
|
|
const message: Message = {
|
|
kind: 'message',
|
|
role: 'user',
|
|
messageId: '1',
|
|
parts: [
|
|
{ kind: 'text', text: 'Hello' } as TextPart,
|
|
{ kind: 'text', text: 'World' } as TextPart,
|
|
],
|
|
};
|
|
expect(extractMessageText(message)).toBe('Hello\nWorld');
|
|
});
|
|
|
|
it('should extract data from data parts', () => {
|
|
const message: Message = {
|
|
kind: 'message',
|
|
role: 'user',
|
|
messageId: '1',
|
|
parts: [{ kind: 'data', data: { foo: 'bar' } } as DataPart],
|
|
};
|
|
expect(extractMessageText(message)).toBe('Data: {"foo":"bar"}');
|
|
});
|
|
|
|
it('should extract file info from file parts', () => {
|
|
const message: Message = {
|
|
kind: 'message',
|
|
role: 'user',
|
|
messageId: '1',
|
|
parts: [
|
|
{
|
|
kind: 'file',
|
|
file: {
|
|
name: 'test.txt',
|
|
uri: 'file://test.txt',
|
|
mimeType: 'text/plain',
|
|
},
|
|
} as FilePart,
|
|
{
|
|
kind: 'file',
|
|
file: {
|
|
uri: 'http://example.com/doc',
|
|
mimeType: 'application/pdf',
|
|
},
|
|
} as FilePart,
|
|
],
|
|
};
|
|
// The formatting logic in a2aUtils prefers name over uri
|
|
expect(extractMessageText(message)).toContain('File: test.txt');
|
|
expect(extractMessageText(message)).toContain(
|
|
'File: http://example.com/doc',
|
|
);
|
|
});
|
|
|
|
it('should handle mixed parts', () => {
|
|
const message: Message = {
|
|
kind: 'message',
|
|
role: 'user',
|
|
messageId: '1',
|
|
parts: [
|
|
{ kind: 'text', text: 'Here is data:' } as TextPart,
|
|
{ kind: 'data', data: { value: 123 } } as DataPart,
|
|
],
|
|
};
|
|
expect(extractMessageText(message)).toBe(
|
|
'Here is data:\nData: {"value":123}',
|
|
);
|
|
});
|
|
|
|
it('should return empty string for undefined or empty message', () => {
|
|
expect(extractMessageText(undefined)).toBe('');
|
|
expect(
|
|
extractMessageText({
|
|
kind: 'message',
|
|
role: 'user',
|
|
messageId: '1',
|
|
parts: [],
|
|
} as Message),
|
|
).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('extractTaskText', () => {
|
|
it('should extract basic task info (clean)', () => {
|
|
const task: Task = {
|
|
id: 'task-1',
|
|
contextId: 'ctx-1',
|
|
kind: 'task',
|
|
status: {
|
|
state: 'working',
|
|
message: {
|
|
kind: 'message',
|
|
role: 'agent',
|
|
messageId: 'm1',
|
|
parts: [{ kind: 'text', text: 'Processing...' } as TextPart],
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = extractTaskText(task);
|
|
expect(result).not.toContain('ID: task-1');
|
|
expect(result).not.toContain('State: working');
|
|
expect(result).toBe('Processing...');
|
|
});
|
|
|
|
it('should extract artifacts with headers', () => {
|
|
const task: Task = {
|
|
id: 'task-1',
|
|
contextId: 'ctx-1',
|
|
kind: 'task',
|
|
status: { state: 'completed' },
|
|
artifacts: [
|
|
{
|
|
artifactId: 'art-1',
|
|
name: 'Report',
|
|
parts: [{ kind: 'text', text: 'This is the report.' } as TextPart],
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = extractTaskText(task);
|
|
expect(result).toContain('Artifact (Report):');
|
|
expect(result).toContain('This is the report.');
|
|
expect(result).not.toContain('Artifacts:');
|
|
expect(result).not.toContain(' - Name: Report');
|
|
});
|
|
});
|
|
});
|