Skip to content

Commit a684e7a

Browse files
authored
Add support for Gemini 3 Pro Preview (#226)
1 parent acfde6f commit a684e7a

4 files changed

Lines changed: 32 additions & 18 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dependencies = [
1919
"pixi",
2020
"pipx>=1.7.1,<2",
2121
"pgdumplib>=3.1.0,<4",
22-
"litellm==1.76.0"
22+
"litellm==1.80.0"
2323
]
2424

2525
[build-system]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ numpy>=1.23.0
99
psycopg2
1010
pyyaml
1111
nest_asyncio
12-
litellm==1.76.0
12+
litellm==1.80.0
1313
pydantic

src/agents/mcpmark_agent.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -477,33 +477,33 @@ async def _execute_anthropic_native_tool_loop(
477477
log_msg += f" | Reasoning: {total_tokens['reasoning_tokens']:,}"
478478
logger.info(log_msg)
479479
logger.info(f"| Turns: {turn_count}")
480-
480+
481481
# Convert messages to SDK format
482-
# sdk_format_messages = self._convert_to_sdk_format(messages)
483-
482+
sdk_format_messages = self._convert_to_sdk_format(messages)
483+
484484
if hit_turn_limit:
485485
return {
486486
"success": False,
487-
"output": messages,
487+
"output": sdk_format_messages,
488488
"token_usage": total_tokens,
489489
"turn_count": turn_count,
490490
"error": f"Max turns ({max_turns}) exceeded",
491491
"litellm_run_model_name": self.litellm_run_model_name,
492492
}
493-
493+
494494
if error_msg:
495495
return {
496496
"success": False,
497-
"output": messages,
497+
"output": sdk_format_messages,
498498
"token_usage": total_tokens,
499499
"turn_count": turn_count,
500500
"error": error_msg,
501501
"litellm_run_model_name": self.litellm_run_model_name,
502502
}
503-
503+
504504
return {
505505
"success": True,
506-
"output": messages,
506+
"output": sdk_format_messages,
507507
"token_usage": total_tokens,
508508
"turn_count": turn_count,
509509
"error": None,
@@ -632,45 +632,54 @@ async def _execute_litellm_tool_loop(
632632
else:
633633
await asyncio.sleep(2 ** consecutive_failures)
634634
continue
635-
635+
636636
# Extract actual model name from response (first turn only)
637637
if turn_count == 0 and hasattr(response, 'model') and response.model:
638638
self.litellm_run_model_name = response.model.split("/")[-1]
639-
639+
640640
# Update token usage including reasoning tokens
641641
if hasattr(response, 'usage') and response.usage:
642642
input_tokens = response.usage.prompt_tokens or 0
643643
total_tokens_count = response.usage.total_tokens or 0
644644
# Calculate output tokens as total - input for consistency
645645
output_tokens = total_tokens_count - input_tokens if total_tokens_count > 0 else (response.usage.completion_tokens or 0)
646-
646+
647647
total_tokens["input_tokens"] += input_tokens
648648
total_tokens["output_tokens"] += output_tokens
649649
total_tokens["total_tokens"] += total_tokens_count
650-
650+
651651
# Extract reasoning tokens if available
652652
if hasattr(response.usage, 'completion_tokens_details'):
653653
details = response.usage.completion_tokens_details
654654
if hasattr(details, 'reasoning_tokens'):
655655
total_tokens["reasoning_tokens"] += details.reasoning_tokens or 0
656-
656+
657657
# Get response message
658658
choices = response.choices
659659
if len(choices):
660660
message = choices[0].message
661+
# deeply dump the message to ensure we capture all fields
661662
message_dict = message.model_dump() if hasattr(message, 'model_dump') else dict(message)
662-
663+
664+
# Explicitly preserve function_call if present (even if tool_calls exists),
665+
# as it may contain provider-specific metadata (e.g. Gemini thought_signature)
666+
if hasattr(message, 'function_call') and message.function_call:
667+
# Ensure it's in the dict if model_dump missed it or it was excluded
668+
if 'function_call' not in message_dict or not message_dict['function_call']:
669+
fc = message.function_call
670+
message_dict['function_call'] = fc.model_dump() if hasattr(fc, 'model_dump') else fc
671+
663672
# Log assistant's text content if present
664673
if hasattr(message, 'content') and message.content:
665674
# Display the content with line prefix
666675
for line in message.content.splitlines():
667676
logger.info(f"| {line}")
668-
677+
669678
# Also log to file if specified
670679
if tool_call_log_file:
671680
with open(tool_call_log_file, 'a', encoding='utf-8') as f:
672681
f.write(f"{message.content}\n")
673-
682+
674683
# Check for tool calls (newer format)
675684
if hasattr(message, 'tool_calls') and message.tool_calls:
676685
messages.append(message_dict)

src/model_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ class ModelConfig:
123123
"api_key_var": "GEMINI_API_KEY",
124124
"litellm_input_model_name": "gemini/gemini-2.5-flash",
125125
},
126+
"gemini-3-pro-preview": {
127+
"provider": "google",
128+
"api_key_var": "GEMINI_API_KEY",
129+
"litellm_input_model_name": "gemini/gemini-3-pro-preview",
130+
},
126131
# Moonshot models
127132
"kimi-k2-0711": {
128133
"provider": "moonshot",

0 commit comments

Comments
 (0)