-
Notifications
You must be signed in to change notification settings - Fork 35
Add logging for invalid WebSocket payloads and new properties #49
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 | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -429,6 +429,11 @@ public async Task ConnectAsync(bool autoSendSetup = true,CancellationToken cance | |||||||||||||||||||||||
| _logger?.LogConnectionClosedWithError(info.Type, info.Exception!); | ||||||||||||||||||||||||
| ErrorOccurred?.Invoke(this, new ErrorEventArgs(info.Exception!)); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| else if (info.CloseStatus == WebSocketCloseStatus.InvalidPayloadData) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| //log info.CloseStatusDescription | ||||||||||||||||||||||||
| _logger?.LogConnectionClosedWithInvalidPyload(info.CloseStatusDescription!); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+432
to
+436
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainFix the typo and verify null safety. Two issues in this code segment:
Apply this diff to fix the typo: - _logger?.LogConnectionClosedWithInvalidPyload(info.CloseStatusDescription!);
+ _logger?.LogConnectionClosedWithInvalidPayload(info.CloseStatusDescription!);Verify that 🏁 Script executed: #!/bin/bash
# Description: Check if CloseStatusDescription can be null for InvalidPayloadData scenarios
# Search for WebSocketCloseStatus.InvalidPayloadData usage patterns
rg -A 5 -B 5 "InvalidPayloadData"
# Look for any null checks on CloseStatusDescription
rg -A 3 -B 3 "CloseStatusDescription"Length of output: 2680 Fix typo, handle possible null, and update extension method Two issues found in
Please update both call site and extension definition, and guard against a null description. Example diff: In src/GenerativeAI.Live/Models/MultiModalLiveClient.cs: - else if (info.CloseStatus == WebSocketCloseStatus.InvalidPayloadData)
- {
- //log info.CloseStatusDescription
- _logger?.LogConnectionClosedWithInvalidPyload(info.CloseStatusDescription!);
- }
+ else if (info.CloseStatus == WebSocketCloseStatus.InvalidPayloadData)
+ {
+ // ensure description is never null
+ var description = info.CloseStatusDescription ?? "No payload description";
+ _logger?.LogConnectionClosedWithInvalidPayload(description);
+ }In src/GenerativeAI.Live/Logging/LoggingExtensions.cs: - [LoggerMessage(EventId = 113, Level = LogLevel.Error,
- Message = "WebSocket connection closed caused by invalid payload: {CloseStatusDescription}")]
- public static partial void LogConnectionClosedWithInvalidPyload(this ILogger logger, string closeStatusDescription);
+ [LoggerMessage(EventId = 113, Level = LogLevel.Error,
+ Message = "WebSocket connection closed caused by invalid payload: {CloseStatusDescription}")]
+ public static partial void LogConnectionClosedWithInvalidPayload(this ILogger logger, string closeStatusDescription);
📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| else | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| _logger?.LogConnectionClosed(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,4 +43,14 @@ public class BidiGenerateContentSetup | ||||||||||||||||
| /// </summary> | |||||||||||||||||
| [JsonPropertyName("tools")] | |||||||||||||||||
| public Tool[]? Tools { get; set; } | |||||||||||||||||
|
|
|||||||||||||||||
| [JsonPropertyName("outputAudioTranscription")] | |||||||||||||||||
| public OutputAudioTranscription? OutputAudioTranscription { get; set; } = new OutputAudioTranscription(); | |||||||||||||||||
|
|
|||||||||||||||||
| [JsonPropertyName("inputAudioTranscription")] | |||||||||||||||||
| public OutputAudioTranscription? InputAudioTranscription { get; set; } | |||||||||||||||||
|
Comment on lines
+47
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainReconsider the type design for input and output transcription. Both
Verify the intended design by checking the API documentation or related usage: 🌐 Web query: 💡 Result: Differences Between
|
|||||||||||||||||
| Feature | inputAudioTranscription | outputAudioTranscription |
|---|---|---|
| Transcribes | Incoming (user) audio | Outgoing (assistant/model) audio |
| Text aligns with | Input audio language | Output audio language code |
| Use case | Capture/understand user speech in real time | Display/understand model's spoken responses in text |
| Activated by | Including input_audio_transcription in setup |
Including output_audio_transcription in setup |
Typical Use in Configuration
In a typical session configuration, both can be enabled simultaneously for full conversational visibility:
config = {
"response_modalities": ["AUDIO"],
"input_audio_transcription": {},
"output_audio_transcription": {}
}- This setup will provide both the user's spoken input and the assistant's spoken output as synchronized text streams, facilitating live transcription on both ends[5].
Practical Example
- When a user speaks,
inputAudioTranscriptionprovides a real-time transcript of their speech. - When the model replies via synthesized speech,
outputAudioTranscriptiondelivers the text equivalent of that synthesized audio.
Summary
inputAudioTranscription: Transcribes and exposes the user's input speech.outputAudioTranscription: Transcribes and exposes the model's spoken output, strictly following the language code specified for output.
This dual transcription capability ensures clear, accessible, and auditable interactions in voice or multimodal applications using the Gemini Multimodal Live API[1][5].
Citations:
- 1: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-live
- 2: https://ai.google.dev/gemini-api/docs/live
- 3: https://docs.pipecat.ai/server/services/s2s/gemini
- 4: https://ai.google.dev/gemini-api/docs/audio
- 5: https://cloud.google.com/vertex-ai/generative-ai/docs/live-api
- 6: https://www.youtube.com/watch?v=LMhe2egLsrQ
- 7: https://www.youtube.com/watch?v=1eybCQYOJnY
- 8: https://www.googlecloudcommunity.com/gc/Gemini-Code-Assist/Summary-after-audio-conversation-in-Gemini-s-multimodal-live-API/m-p/854353
- 9: https://www.youtube.com/watch?v=MGHwe7j2TyI
- 10: https://firebase.google.com/docs/ai-logic/analyze-audio
Refactor audio‐transcription types and property initialization
Both input and output transcription share the same (currently empty) configuration shape, so the OutputAudioTranscription type name is misleading and the two properties shouldn’t be initialized inconsistently. Please:
- Rename the placeholder class to a more generic name, e.g.:
/// <summary> /// Configuration for transcribing audio streams. /// </summary> public class AudioTranscription { }
- Update your properties in
BidiGenerateContentSetup.cs(around lines 47–51) to use this new type and remove the default instantiation:- [JsonPropertyName("outputAudioTranscription")] - public OutputAudioTranscription? OutputAudioTranscription { get; set; } = new OutputAudioTranscription(); + /// <summary> + /// Transcribes the assistant’s outgoing audio into text. + /// </summary> + [JsonPropertyName("outputAudioTranscription")] + public AudioTranscription? OutputAudioTranscription { get; set; } - [JsonPropertyName("inputAudioTranscription")] - public OutputAudioTranscription? InputAudioTranscription { get; set; } + /// <summary> + /// Transcribes the user’s incoming audio into text. + /// </summary> + [JsonPropertyName("inputAudioTranscription")] + public AudioTranscription? InputAudioTranscription { get; set; }
- Add XML documentation on both the class and its properties to clarify their distinct roles.
These changes will make the intent clear, avoid confusion over type reuse, and enforce explicit configuration for each transcription stream.
🤖 Prompt for AI Agents
In src/GenerativeAI/Types/MultimodalLive/BidiGenerateContentSetup.cs around
lines 47 to 51, rename the OutputAudioTranscription class to a more generic name
like AudioTranscription to reflect its shared configuration role. Update both
InputAudioTranscription and OutputAudioTranscription properties to use this new
AudioTranscription type and remove the default initialization on
OutputAudioTranscription to keep consistency. Add XML documentation comments on
the AudioTranscription class and on both properties to clearly describe their
distinct purposes for input and output audio transcription configurations.
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.
Fix the typo in the method name.
The method name
LogConnectionClosedWithInvalidPyloadhas a typo - it should beLogConnectionClosedWithInvalidPayload(missing 'a' in "Payload").Apply this diff to fix the typo:
📝 Committable suggestion
🤖 Prompt for AI Agents