feat: implement Gemini to OpenAI chat stream conversion with state management and terminal handling

This commit is contained in:
CaIon
2026-07-27 20:17:20 +08:00
parent f3ab2cff36
commit a043eef559
10 changed files with 894 additions and 37 deletions
@@ -14,7 +14,7 @@
"claude_cache_creation_1_h_tokens": 0
},
"role": "assistant",
"id": "chatcmpl-<uuid>",
"id": "stream_fixed",
"content": []
}
},
@@ -41,6 +41,53 @@
"type": "text_delta",
"text": " world"
}
},
{
"type": "content_block_stop",
"index": 0
},
{
"type": "message_delta",
"usage": {
"input_tokens": 4,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 2,
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0,
"billing_usage": {
"source": "oai_chat",
"semantic": "openai",
"openai_usage": {
"prompt_tokens": 4,
"completion_tokens": 2,
"total_tokens": 6,
"prompt_tokens_details": {
"cached_tokens": 0,
"text_tokens": 4,
"audio_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"text_tokens": 0,
"audio_tokens": 0,
"image_tokens": 0,
"reasoning_tokens": 0
},
"input_tokens": 0,
"output_tokens": 0,
"input_tokens_details": null,
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0
}
}
},
"delta": {
"stop_reason": "end_turn"
}
},
{
"type": "message_stop"
}
],
"usage": {
@@ -1,7 +1,7 @@
{
"events": [
{
"id": "chatcmpl-<uuid>",
"id": "stream_fixed",
"object": "chat.completion.chunk",
"created": 0,
"model": "upstream-model",
@@ -40,7 +40,7 @@
}
},
{
"id": "chatcmpl-<uuid>",
"id": "stream_fixed",
"object": "chat.completion.chunk",
"created": 0,
"model": "upstream-model",
@@ -92,6 +92,58 @@
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0
}
},
{
"id": "stream_fixed",
"object": "chat.completion.chunk",
"created": 0,
"model": "upstream-model",
"system_fingerprint": null,
"choices": [
{
"delta": {},
"logprobs": null,
"finish_reason": "stop",
"index": 0
}
],
"usage": {
"prompt_tokens": 4,
"completion_tokens": 2,
"total_tokens": 6,
"billing_usage": {
"source": "gemini_chat",
"semantic": "gemini",
"gemini_usage_metadata": {
"promptTokenCount": 4,
"toolUsePromptTokenCount": 0,
"candidatesTokenCount": 2,
"totalTokenCount": 6,
"thoughtsTokenCount": 0,
"cachedContentTokenCount": 0,
"promptTokensDetails": [],
"toolUsePromptTokensDetails": [],
"candidatesTokensDetails": []
}
},
"prompt_tokens_details": {
"cached_tokens": 0,
"text_tokens": 4,
"audio_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"text_tokens": 0,
"audio_tokens": 0,
"image_tokens": 0,
"reasoning_tokens": 0
},
"input_tokens": 0,
"output_tokens": 0,
"input_tokens_details": null,
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0
}
}
],
"usage": {
@@ -41,6 +41,53 @@
"type": "text_delta",
"text": " world"
}
},
{
"type": "content_block_stop",
"index": 0
},
{
"type": "message_delta",
"usage": {
"input_tokens": 4,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 2,
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0,
"billing_usage": {
"source": "oai_responses",
"semantic": "openai",
"openai_usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 6,
"prompt_tokens_details": {
"cached_tokens": 0,
"text_tokens": 0,
"audio_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"text_tokens": 0,
"audio_tokens": 0,
"image_tokens": 0,
"reasoning_tokens": 0
},
"input_tokens": 4,
"output_tokens": 2,
"input_tokens_details": null,
"claude_cache_creation_5_m_tokens": 0,
"claude_cache_creation_1_h_tokens": 0
}
}
},
"delta": {
"stop_reason": "end_turn"
}
},
{
"type": "message_stop"
}
],
"usage": {