in packages/core/src/core/coreToolScheduler.ts [137:196]
export function convertToFunctionResponse(
toolName: string,
callId: string,
llmContent: PartListUnion,
): PartListUnion {
const contentToProcess =
Array.isArray(llmContent) && llmContent.length === 1
? llmContent[0]
: llmContent;
if (typeof contentToProcess === 'string') {
return createFunctionResponsePart(callId, toolName, contentToProcess);
}
if (Array.isArray(contentToProcess)) {
const functionResponse = createFunctionResponsePart(
callId,
toolName,
'Tool execution succeeded.',
);
return [functionResponse, ...contentToProcess];
}
// After this point, contentToProcess is a single Part object.
if (contentToProcess.functionResponse) {
if (contentToProcess.functionResponse.response?.content) {
const stringifiedOutput =
getResponseTextFromParts(
contentToProcess.functionResponse.response.content as Part[],
) || '';
return createFunctionResponsePart(callId, toolName, stringifiedOutput);
}
// It's a functionResponse that we should pass through as is.
return contentToProcess;
}
if (contentToProcess.inlineData || contentToProcess.fileData) {
const mimeType =
contentToProcess.inlineData?.mimeType ||
contentToProcess.fileData?.mimeType ||
'unknown';
const functionResponse = createFunctionResponsePart(
callId,
toolName,
`Binary content of type ${mimeType} was processed.`,
);
return [functionResponse, contentToProcess];
}
if (contentToProcess.text !== undefined) {
return createFunctionResponsePart(callId, toolName, contentToProcess.text);
}
// Default case for other kinds of parts.
return createFunctionResponsePart(
callId,
toolName,
'Tool execution succeeded.',
);
}