Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions python/mirascope/llm/providers/google/model_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"google/gemini-2.5-flash-lite-preview-09-2025",
"google/gemini-2.5-flash-preview-09-2025",
"google/gemini-2.5-pro",
"google/gemini-3-flash-preview",
"google/gemini-3-pro-image-preview",
"google/gemini-3-pro-preview",
"google/gemini-flash-latest",
Expand Down
2 changes: 1 addition & 1 deletion python/scripts/model_features/data/anthropic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,4 @@ models:
strict_structured_output:
status: supported
tested_at: '2025-12-15T15:40:34.228188'
last_discovery: '2025-12-15T15:40:13.290920'
last_discovery: '2026-01-08T23:03:02.705418'
17 changes: 16 additions & 1 deletion python/scripts/model_features/data/google.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,21 @@ models:
reason: unmet_dependencies
failed_dependencies:
- chat_model
gemini-3-flash-preview:
owned_by: google
deprecated: false
discovered_at: '2026-01-08T22:59:46.316610'
metadata:
display_name: Gemini 3 Flash Preview
features:
chat_model:
status: supported
tested_at: '2026-01-08T22:59:47.327767'
structured_output_with_tools:
status: supported
tested_at: '2026-01-08T22:59:48.732013'
metadata:
called_tool: true
gemini-3-pro-image-preview:
owned_by: google
deprecated: false
Expand Down Expand Up @@ -926,4 +941,4 @@ models:
reason: unmet_dependencies
failed_dependencies:
- chat_model
last_discovery: '2025-12-16T15:16:15.591396'
last_discovery: '2026-01-08T23:03:00.506074'
2 changes: 1 addition & 1 deletion python/scripts/model_features/data/openai.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4293,4 +4293,4 @@ models:
reason: unmet_dependencies
failed_dependencies:
- completions_api
last_discovery: '2025-12-18T11:37:47.379462'
last_discovery: '2026-01-08T23:03:01.901516'
143 changes: 143 additions & 0 deletions python/scripts/model_features/update_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
"""Run all model feature tests and code generation for all providers.

This script runs the test and codegen scripts for all supported providers:
- Google
- OpenAI
- Anthropic

For each provider, it:
1. Runs the test script to discover models and test feature support
2. Runs the codegen script to generate model_info.py files

Usage:
uv run python -m scripts.model_features.update_all [options]

Options:
--test-only Only run tests, skip code generation
--codegen-only Only run code generation, skip tests
--providers NAMES Comma-separated list of providers (default: all)
Valid providers: google, openai, anthropic

Requires API keys for each provider (loaded from .env if present):
- GOOGLE_API_KEY
- OPENAI_API_KEY
- ANTHROPIC_API_KEY
"""

import argparse
import subprocess
import sys
from pathlib import Path


def run_command(cmd: list[str], description: str) -> bool:
"""Run a command and return whether it succeeded.

Args:
cmd: Command to run as list of strings
description: Description of what the command does

Returns:
True if command succeeded, False otherwise
"""
print(f"\n{'=' * 80}")
print(f"{description}")
print(f"{'=' * 80}")
print(f"Running: {' '.join(cmd)}\n")

result = subprocess.run(cmd, cwd=Path(__file__).parent.parent.parent)

if result.returncode != 0:
print(f"\n❌ Failed: {description}")
return False

print(f"\n✅ Success: {description}")
return True


def main() -> int:
parser = argparse.ArgumentParser(
description="Run all model feature tests and code generation"
)
parser.add_argument(
"--test-only", action="store_true", help="Only run tests, skip code generation"
)
parser.add_argument(
"--codegen-only",
action="store_true",
help="Only run code generation, skip tests",
)
parser.add_argument(
"--providers",
type=str,
default="google,openai,anthropic",
help="Comma-separated list of providers (default: all)",
)

args = parser.parse_args()

# Parse providers
valid_providers = {"google", "openai", "anthropic"}
providers = [p.strip().lower() for p in args.providers.split(",")]

# Validate providers
invalid = set(providers) - valid_providers
if invalid:
print(f"Error: Invalid providers: {', '.join(invalid)}")
print(f"Valid providers: {', '.join(sorted(valid_providers))}")
return 1

# Track overall success
all_succeeded = True

# Run tests for each provider
if not args.codegen_only:
for provider in providers:
success = run_command(
[
"uv",
"run",
"python",
"-m",
f"scripts.model_features.test_{provider}",
],
f"Testing {provider.upper()} models",
)
if not success:
all_succeeded = False
print(f"\n⚠️ Warning: Test for {provider} failed, continuing anyway...")

# Run codegen for each provider
if not args.test_only:
for provider in providers:
success = run_command(
[
"uv",
"run",
"python",
"-m",
f"scripts.model_features.codegen_{provider}",
],
f"Generating code for {provider.upper()}",
)
if not success:
all_succeeded = False
print(
f"\n⚠️ Warning: Codegen for {provider} failed, continuing anyway..."
)

# Print summary
print(f"\n{'=' * 80}")
print("SUMMARY")
print(f"{'=' * 80}")

if all_succeeded:
print("✅ All operations completed successfully!")
return 0
else:
print("⚠️ Some operations failed. See output above for details.")
return 1


if __name__ == "__main__":
sys.exit(main())