-
Notifications
You must be signed in to change notification settings - Fork 3
Improve Gemini Logging #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -34,6 +34,7 @@ import type { | |||||
| ResponseOutputText, | ||||||
| ResponseOutputRefusal, | ||||||
| } from 'openai/resources/responses/responses'; | ||||||
| import type { Part } from '@google/genai'; | ||||||
| import { GoogleGenAI } from '@google/genai'; | ||||||
|
|
||||||
| interface ExtractionResult { | ||||||
|
|
@@ -155,10 +156,32 @@ export class AIService { | |||||
| }, | ||||||
| }) | ||||||
| .then((response) => { | ||||||
| this.aiServiceLogger.info('Gemini response structure:', { | ||||||
| hasCandidates: !!response.candidates, | ||||||
| candidatesLength: response.candidates?.length, | ||||||
| firstCandidateKeys: response.candidates?.[0] ? Object.keys(response.candidates[0]) : null, | ||||||
| contentKeys: response.candidates?.[0]?.content ? Object.keys(response.candidates[0].content) : null, | ||||||
| partsLength: response.candidates?.[0]?.content?.parts?.length, | ||||||
| fullResponse: JSON.stringify(response, null, 2), | ||||||
| }); | ||||||
|
|
||||||
| let imageBytes = Buffer.from([]); | ||||||
| response.candidates?.[0].content?.parts?.forEach((part) => { | ||||||
| if (!response.candidates || response.candidates.length === 0) { | ||||||
| this.aiServiceLogger.warn('No candidates in Gemini response'); | ||||||
| return ''; | ||||||
| } | ||||||
|
|
||||||
| const parts = response.candidates[0].content?.parts; | ||||||
| if (!parts || parts.length === 0) { | ||||||
| this.aiServiceLogger.warn('No parts in first candidate'); | ||||||
| return ''; | ||||||
| } | ||||||
|
|
||||||
| parts.forEach((part: Part) => { | ||||||
| if (part.inlineData?.data) { | ||||||
| imageBytes = Buffer.concat([imageBytes, Buffer.from(part.inlineData.data, 'base64')]); | ||||||
| } else { | ||||||
| this.aiServiceLogger.info('Part does not have inlineData.data:', Object.keys(part)); | ||||||
|
||||||
| this.aiServiceLogger.info('Part does not have inlineData.data:', Object.keys(part)); | |
| this.aiServiceLogger.debug('Part does not have inlineData.data:', Object.keys(part)); |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "Gemini generateImage response structure" message is logged at info for every image generation, which is likely to be high-volume and may bloat logs. Consider using debug, sampling, or logging this structure only when candidates/parts are missing (i.e., on the warning/error paths).
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This per-part info log in generateImage can be emitted many times and will add noise at scale. Consider moving it to debug and/or including more actionable context (e.g., part type) while avoiding high-cardinality logs.
| this.aiServiceLogger.info('GenerateImage part does not have inlineData.data:', Object.keys(part)); | |
| this.aiServiceLogger.debug('GenerateImage part does not have inlineData.data:', Object.keys(part)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging the full Gemini response at info level (including JSON.stringify(response)) will likely include the base64 image payload in
inlineData.data. This can leak sensitive content into logs and can generate extremely large log lines. Prefer removingfullResponse, or redacting/truncating binary fields and logging only at debug level (or only when an error/unexpected structure occurs).