summaryrefslogtreecommitdiff
path: root/packages/core/src/utils/generateContentResponseUtilities.ts
diff options
context:
space:
mode:
authorJerop Kipruto <[email protected]>2025-06-15 01:48:01 -0400
committerGitHub <[email protected]>2025-06-15 01:48:01 -0400
commitab932ffaa535d9fee4872f5513a7551abc2ffe2a (patch)
tree55ca302df3dcdd1ba8c7f67c19df9f8043a40063 /packages/core/src/utils/generateContentResponseUtilities.ts
parente717c51aa1e46d1a1aabdb7e770c248b93e437a6 (diff)
Telemetry: Improve API response logging with function call details (#1064)
Diffstat (limited to 'packages/core/src/utils/generateContentResponseUtilities.ts')
-rw-r--r--packages/core/src/utils/generateContentResponseUtilities.ts112
1 files changed, 105 insertions, 7 deletions
diff --git a/packages/core/src/utils/generateContentResponseUtilities.ts b/packages/core/src/utils/generateContentResponseUtilities.ts
index d575bca8..c5125753 100644
--- a/packages/core/src/utils/generateContentResponseUtilities.ts
+++ b/packages/core/src/utils/generateContentResponseUtilities.ts
@@ -4,18 +4,116 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { GenerateContentResponse, Part } from '@google/genai';
+import { GenerateContentResponse, Part, FunctionCall } from '@google/genai';
export function getResponseText(
response: GenerateContentResponse,
): string | undefined {
- return (
- response.candidates?.[0]?.content?.parts
- ?.map((part) => part.text)
- .join('') || undefined
- );
+ const parts = response.candidates?.[0]?.content?.parts;
+ if (!parts) {
+ return undefined;
+ }
+ const textSegments = parts
+ .map((part) => part.text)
+ .filter((text): text is string => typeof text === 'string');
+
+ if (textSegments.length === 0) {
+ return undefined;
+ }
+ return textSegments.join('');
}
export function getResponseTextFromParts(parts: Part[]): string | undefined {
- return parts?.map((part) => part.text).join('') || undefined;
+ if (!parts) {
+ return undefined;
+ }
+ const textSegments = parts
+ .map((part) => part.text)
+ .filter((text): text is string => typeof text === 'string');
+
+ if (textSegments.length === 0) {
+ return undefined;
+ }
+ return textSegments.join('');
+}
+
+export function getFunctionCalls(
+ response: GenerateContentResponse,
+): FunctionCall[] | undefined {
+ const parts = response.candidates?.[0]?.content?.parts;
+ if (!parts) {
+ return undefined;
+ }
+ const functionCallParts = parts
+ .filter((part) => !!part.functionCall)
+ .map((part) => part.functionCall as FunctionCall);
+ return functionCallParts.length > 0 ? functionCallParts : undefined;
+}
+
+export function getFunctionCallsFromParts(
+ parts: Part[],
+): FunctionCall[] | undefined {
+ if (!parts) {
+ return undefined;
+ }
+ const functionCallParts = parts
+ .filter((part) => !!part.functionCall)
+ .map((part) => part.functionCall as FunctionCall);
+ return functionCallParts.length > 0 ? functionCallParts : undefined;
+}
+
+export function getFunctionCallsAsJson(
+ response: GenerateContentResponse,
+): string | undefined {
+ const functionCalls = getFunctionCalls(response);
+ if (!functionCalls) {
+ return undefined;
+ }
+ return JSON.stringify(functionCalls, null, 2);
+}
+
+export function getFunctionCallsFromPartsAsJson(
+ parts: Part[],
+): string | undefined {
+ const functionCalls = getFunctionCallsFromParts(parts);
+ if (!functionCalls) {
+ return undefined;
+ }
+ return JSON.stringify(functionCalls, null, 2);
+}
+
+export function getStructuredResponse(
+ response: GenerateContentResponse,
+): string | undefined {
+ const textContent = getResponseText(response);
+ const functionCallsJson = getFunctionCallsAsJson(response);
+
+ if (textContent && functionCallsJson) {
+ return `${textContent}\n${functionCallsJson}`;
+ }
+ if (textContent) {
+ return textContent;
+ }
+ if (functionCallsJson) {
+ return functionCallsJson;
+ }
+ return undefined;
+}
+
+export function getStructuredResponseFromParts(
+ parts: Part[],
+): string | undefined {
+ const textContent = getResponseTextFromParts(parts);
+ const functionCallsJson = getFunctionCallsFromPartsAsJson(parts);
+
+ if (textContent && functionCallsJson) {
+ return `${textContent}\n${functionCallsJson}`;
+ }
+ if (textContent) {
+ return textContent;
+ }
+ if (functionCallsJson) {
+ return functionCallsJson;
+ }
+ return undefined;
}