google_ai: Add Gemini 3.8 Flash (#63643)
# Objective Add Gemini 3.8 Flash to Zed's built-in Google AI provider so it can be selected from the model dropdown. ## Solution Register `gemini-3.8-flash` with its 1 million token context window, 64k output limit, and Low, Medium, and High thinking levels. Medium is the default, and Low is used when thinking is disabled because the model rejects Minimal. Add tests covering the model metadata, serialization, token limits, thinking levels, and disabled-thinking behavior. ## Testing Tested on Windows using Rust 1.98 GNU: - `cargo test -p google_ai` — 23 passed - `cargo fmt --all --check` - `cargo +stable-x86_64-pc-windows-gnu clippy -p google_ai --release --all-targets --all-features -- --deny warnings` Reviewers can run `cargo test -p google_ai`. The pinned MSVC toolchain was not tested locally because `link.exe` was unavailable. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Added Gemini 3.8 Flash to the Google AI models
This commit is contained in:
1 parent
3c1fc637ad
commit
078d171ebc
2 files changed
+43
-3
No files matched your search
@@ -250,10 +250,11 @@ fn is_google_thinking_model(model_id: &str) -> bool {
|
||||
|
||||
fn disabled_thinking_level(model_id: &str) -> Option<ThinkingLevel> {
|
||||
match model_id {
|
||||
// `gemini-3.7-flash` rejects `MINIMAL` with a validation error, so `LOW` is
|
||||
// the lowest level available to it.
|
||||
// Gemini 3.7 and 3.8 Flash reject `MINIMAL` with a validation error, so
|
||||
// `LOW` is the lowest level available to them.
|
||||
model_id
|
||||
if model_id.starts_with("gemini-3.7-flash")
|
||||
|| model_id.starts_with("gemini-3.8-flash")
|
||||
|| (model_id.starts_with("gemini-3") && model_id.contains("-pro")) =>
|
||||
{
|
||||
Some(ThinkingLevel::Low)
|
||||
@@ -749,6 +750,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_disabled_thinking_level_per_model() {
|
||||
assert_eq!(
|
||||
disabled_thinking_level("gemini-3.8-flash"),
|
||||
Some(ThinkingLevel::Low)
|
||||
);
|
||||
assert_eq!(
|
||||
disabled_thinking_level("gemini-3.7-flash"),
|
||||
Some(ThinkingLevel::Low)
|
||||
|
||||
@@ -517,6 +517,8 @@ pub enum Model {
|
||||
Gemini36Flash,
|
||||
#[serde(rename = "gemini-3.7-flash")]
|
||||
Gemini37Flash,
|
||||
#[serde(rename = "gemini-3.8-flash")]
|
||||
Gemini38Flash,
|
||||
#[serde(rename = "gemini-3.1-pro-preview")]
|
||||
Gemini31Pro,
|
||||
#[serde(rename = "custom")]
|
||||
@@ -542,6 +544,7 @@ impl Model {
|
||||
Self::Gemini35Flash => "gemini-3.5-flash",
|
||||
Self::Gemini36Flash => "gemini-3.6-flash",
|
||||
Self::Gemini37Flash => "gemini-3.7-flash",
|
||||
Self::Gemini38Flash => "gemini-3.8-flash",
|
||||
Self::Gemini31Pro => "gemini-3.1-pro-preview",
|
||||
Self::Custom { name, .. } => name,
|
||||
}
|
||||
@@ -553,6 +556,7 @@ impl Model {
|
||||
Self::Gemini35Flash => "gemini-3.5-flash",
|
||||
Self::Gemini36Flash => "gemini-3.6-flash",
|
||||
Self::Gemini37Flash => "gemini-3.7-flash",
|
||||
Self::Gemini38Flash => "gemini-3.8-flash",
|
||||
Self::Gemini31Pro => "gemini-3.1-pro-preview",
|
||||
Self::Custom { name, .. } => name,
|
||||
}
|
||||
@@ -565,6 +569,7 @@ impl Model {
|
||||
Self::Gemini35Flash => "Gemini 3.5 Flash",
|
||||
Self::Gemini36Flash => "Gemini 3.6 Flash",
|
||||
Self::Gemini37Flash => "Gemini 3.7 Flash",
|
||||
Self::Gemini38Flash => "Gemini 3.8 Flash",
|
||||
Self::Gemini31Pro => "Gemini 3.1 Pro",
|
||||
Self::Custom {
|
||||
name, display_name, ..
|
||||
@@ -579,6 +584,7 @@ impl Model {
|
||||
| Self::Gemini35Flash
|
||||
| Self::Gemini36Flash
|
||||
| Self::Gemini37Flash
|
||||
| Self::Gemini38Flash
|
||||
| Self::Gemini31Pro => 1_048_576,
|
||||
Self::Custom { max_tokens, .. } => *max_tokens,
|
||||
}
|
||||
@@ -591,6 +597,7 @@ impl Model {
|
||||
| Model::Gemini35Flash
|
||||
| Model::Gemini36Flash
|
||||
| Model::Gemini37Flash
|
||||
| Model::Gemini38Flash
|
||||
| Model::Gemini31Pro => Some(65_536),
|
||||
Model::Custom { .. } => None,
|
||||
}
|
||||
@@ -612,6 +619,7 @@ impl Model {
|
||||
| Self::Gemini35Flash
|
||||
| Self::Gemini36Flash
|
||||
| Self::Gemini37Flash
|
||||
| Self::Gemini38Flash
|
||||
| Self::Gemini31Pro
|
||||
| Self::Custom {
|
||||
mode: GoogleModelMode::Thinking { .. },
|
||||
@@ -631,7 +639,7 @@ impl Model {
|
||||
ThinkingLevel::Medium,
|
||||
ThinkingLevel::High,
|
||||
],
|
||||
Self::Gemini37Flash | Self::Gemini31Pro => &[
|
||||
Self::Gemini37Flash | Self::Gemini38Flash | Self::Gemini31Pro => &[
|
||||
ThinkingLevel::Low,
|
||||
ThinkingLevel::Medium,
|
||||
ThinkingLevel::High,
|
||||
@@ -647,6 +655,7 @@ impl Model {
|
||||
Self::Gemini35Flash => Some(ThinkingLevel::Medium),
|
||||
Self::Gemini36Flash => Some(ThinkingLevel::Medium),
|
||||
Self::Gemini37Flash => Some(ThinkingLevel::Medium),
|
||||
Self::Gemini38Flash => Some(ThinkingLevel::Medium),
|
||||
Self::Gemini31Pro => Some(ThinkingLevel::High),
|
||||
_ => None,
|
||||
}
|
||||
@@ -659,6 +668,7 @@ impl Model {
|
||||
| Self::Gemini35Flash
|
||||
| Self::Gemini36Flash
|
||||
| Self::Gemini37Flash
|
||||
| Self::Gemini38Flash
|
||||
| Self::Gemini31Pro => GoogleModelMode::Thinking {
|
||||
budget_tokens: None,
|
||||
},
|
||||
@@ -735,6 +745,31 @@ mod tests {
|
||||
assert_eq!(deserialized, Model::Gemini37Flash);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gemini_3_8_flash_model_metadata() {
|
||||
let model = Model::Gemini38Flash;
|
||||
assert_eq!(model.id(), "gemini-3.8-flash");
|
||||
assert_eq!(model.request_id(), "gemini-3.8-flash");
|
||||
assert_eq!(model.display_name(), "Gemini 3.8 Flash");
|
||||
assert_eq!(model.max_token_count(), 1_048_576);
|
||||
assert_eq!(model.max_output_tokens(), Some(65_536));
|
||||
assert!(model.supports_thinking());
|
||||
assert_eq!(
|
||||
model.supported_thinking_levels(),
|
||||
&[
|
||||
ThinkingLevel::Low,
|
||||
ThinkingLevel::Medium,
|
||||
ThinkingLevel::High
|
||||
]
|
||||
);
|
||||
assert_eq!(model.default_thinking_level(), Some(ThinkingLevel::Medium));
|
||||
|
||||
let serialized = serde_json::to_value(&model).unwrap();
|
||||
assert_eq!(serialized, json!("gemini-3.8-flash"));
|
||||
let deserialized: Model = serde_json::from_value(json!("gemini-3.8-flash")).unwrap();
|
||||
assert_eq!(deserialized, Model::Gemini38Flash);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_call_part_with_signature_serializes_correctly() {
|
||||
let part = FunctionCallPart {
|
||||
|
||||
Reference in new issue
Block a user