refactor(core): extract static concerns from CoreToolScheduler (#15589)

This commit is contained in:
Abhi
2025-12-26 15:51:39 -05:00
committed by GitHub
parent 65e2144b3d
commit 5566292cc8
16 changed files with 983 additions and 948 deletions
@@ -14,14 +14,20 @@ import {
getStructuredResponse,
getStructuredResponseFromParts,
getCitations,
convertToFunctionResponse,
} from './generateContentResponseUtilities.js';
import type {
GenerateContentResponse,
Part,
SafetyRating,
CitationMetadata,
PartListUnion,
} from '@google/genai';
import { FinishReason } from '@google/genai';
import {
DEFAULT_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL,
} from '../config/models.js';
const mockTextPart = (text: string): Part => ({ text });
const mockFunctionCallPart = (
@@ -72,6 +78,312 @@ const minimalMockResponse = (
});
describe('generateContentResponseUtilities', () => {
describe('convertToFunctionResponse', () => {
const toolName = 'testTool';
const callId = 'call1';
it('should handle simple string llmContent', () => {
const llmContent = 'Simple text output';
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
DEFAULT_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Simple text output' },
},
},
]);
});
it('should handle llmContent as a single Part with text', () => {
const llmContent: Part = { text: 'Text from Part object' };
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
DEFAULT_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Text from Part object' },
},
},
]);
});
it('should handle llmContent as a PartListUnion array with a single text Part', () => {
const llmContent: PartListUnion = [{ text: 'Text from array' }];
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
DEFAULT_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Text from array' },
},
},
]);
});
it('should handle llmContent as a PartListUnion array with multiple Parts', () => {
const llmContent: PartListUnion = [{ text: 'part1' }, { text: 'part2' }];
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
DEFAULT_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'part1\npart2' },
},
},
]);
});
it('should handle llmContent with fileData for Gemini 3 model (should be siblings)', () => {
const llmContent: Part = {
fileData: { mimeType: 'application/pdf', fileUri: 'gs://...' },
};
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Binary content provided (1 item(s)).' },
},
},
llmContent,
]);
});
it('should handle llmContent with inlineData for Gemini 3 model (should be nested)', () => {
const llmContent: Part = {
inlineData: { mimeType: 'image/png', data: 'base64...' },
};
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Binary content provided (1 item(s)).' },
parts: [llmContent],
},
},
]);
});
it('should handle llmContent with fileData for non-Gemini 3 models', () => {
const llmContent: Part = {
fileData: { mimeType: 'application/pdf', fileUri: 'gs://...' },
};
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
DEFAULT_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Binary content provided (1 item(s)).' },
},
},
llmContent,
]);
});
it('should preserve existing functionResponse metadata', () => {
const innerId = 'inner-call-id';
const innerName = 'inner-tool-name';
const responseMetadata = {
flags: ['flag1'],
isError: false,
customData: { key: 'value' },
};
const input: Part = {
functionResponse: {
id: innerId,
name: innerName,
response: responseMetadata,
},
};
const result = convertToFunctionResponse(
toolName,
callId,
input,
DEFAULT_GEMINI_MODEL,
);
expect(result).toHaveLength(1);
expect(result[0].functionResponse).toEqual({
id: callId,
name: toolName,
response: responseMetadata,
});
});
it('should handle llmContent as an array of multiple Parts (text and inlineData)', () => {
const llmContent: PartListUnion = [
{ text: 'Some textual description' },
{ inlineData: { mimeType: 'image/jpeg', data: 'base64data...' } },
{ text: 'Another text part' },
];
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: {
output: 'Some textual description\nAnother text part',
},
parts: [
{
inlineData: { mimeType: 'image/jpeg', data: 'base64data...' },
},
],
},
},
]);
});
it('should handle llmContent as an array with a single inlineData Part', () => {
const llmContent: PartListUnion = [
{ inlineData: { mimeType: 'image/gif', data: 'gifdata...' } },
];
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: 'Binary content provided (1 item(s)).' },
parts: llmContent,
},
},
]);
});
it('should handle llmContent as a generic Part (not text, inlineData, or fileData)', () => {
const llmContent: Part = { functionCall: { name: 'test', args: {} } };
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: {},
},
},
]);
});
it('should handle empty string llmContent', () => {
const llmContent = '';
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: { output: '' },
},
},
]);
});
it('should handle llmContent as an empty array', () => {
const llmContent: PartListUnion = [];
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: {},
},
},
]);
});
it('should handle llmContent as a Part with undefined inlineData/fileData/text', () => {
const llmContent: Part = {}; // An empty part object
const result = convertToFunctionResponse(
toolName,
callId,
llmContent,
PREVIEW_GEMINI_MODEL,
);
expect(result).toEqual([
{
functionResponse: {
name: toolName,
id: callId,
response: {},
},
},
]);
});
});
describe('getCitations', () => {
it('should return empty array for no candidates', () => {
expect(getCitations(minimalMockResponse(undefined))).toEqual([]);