Skip to content

Commit cd396a8

Browse files
committed
feat(models): add gemini-3-flash
1 parent 6a8e87c commit cd396a8

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

Sources/Tachikoma/Models/Model.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ public enum LanguageModel: Sendable, CustomStringConvertible, Hashable {
238238
}
239239

240240
public enum Google: String, Sendable, Hashable, CaseIterable {
241+
case gemini3Flash = "gemini-3-flash"
241242
case gemini25Pro = "gemini-2.5-pro"
242243
case gemini25Flash = "gemini-2.5-flash"
243244
case gemini25FlashLite = "gemini-2.5-flash-lite"
@@ -247,7 +248,7 @@ public enum LanguageModel: Sendable, CustomStringConvertible, Hashable {
247248

248249
public var supportsAudioInput: Bool {
249250
switch self {
250-
case .gemini25Pro, .gemini25Flash:
251+
case .gemini3Flash, .gemini25Pro, .gemini25Flash:
251252
true
252253
case .gemini25FlashLite:
253254
false
@@ -258,7 +259,7 @@ public enum LanguageModel: Sendable, CustomStringConvertible, Hashable {
258259

259260
public var contextLength: Int {
260261
switch self {
261-
case .gemini25Pro, .gemini25Flash:
262+
case .gemini3Flash, .gemini25Pro, .gemini25Flash:
262263
1_048_576
263264
case .gemini25FlashLite:
264265
524_288
@@ -1178,6 +1179,42 @@ extension LanguageModel {
11781179
return .anthropic(.sonnet45)
11791180
}
11801181

1182+
// MARK: Google models
1183+
1184+
if dashed.contains("gemini-3-flash") || compact.contains("gemini3flash") {
1185+
return .google(.gemini3Flash)
1186+
}
1187+
1188+
if dashed.contains("gemini-2.5-pro") || dotted.contains("gemini-2-5-pro") || compact.contains("gemini25pro") {
1189+
return .google(.gemini25Pro)
1190+
}
1191+
1192+
if
1193+
dashed.contains("gemini-2.5-flash-lite") || dotted.contains("gemini-2-5-flash-lite") || compact
1194+
.contains("gemini25flashlite")
1195+
{
1196+
return .google(.gemini25FlashLite)
1197+
}
1198+
1199+
if
1200+
dashed.contains("gemini-2.5-flash") || dotted.contains("gemini-2-5-flash") || compact
1201+
.contains("gemini25flash")
1202+
{
1203+
return .google(.gemini25Flash)
1204+
}
1205+
1206+
let genericGeminiIdentifiers: Set<String> = [
1207+
"gemini",
1208+
"geminiflash",
1209+
"gemini-flash",
1210+
"gemini_flash",
1211+
"google",
1212+
]
1213+
1214+
if canonicalForms.contains(where: { genericGeminiIdentifiers.contains($0) }) {
1215+
return .google(.gemini3Flash)
1216+
}
1217+
11811218
// MARK: Grok models
11821219

11831220
if dotted.contains("grok-4-fast-reasoning") || compact.contains("grok4fastreasoning") {

Sources/Tachikoma/Models/ModelSelection.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,16 @@ public struct ModelSelector {
152152

153153
private static func parseGoogleModel(_ input: String) -> Model.Google? {
154154
switch input {
155+
case "gemini-3-flash", "gemini3flash", "gemini-3flash":
156+
.gemini3Flash
155157
case "gemini-2.5-pro", "gemini25pro", "gemini2.5pro":
156158
.gemini25Pro
157159
case "gemini-2.5-flash", "gemini25flash":
158160
.gemini25Flash
159161
case "gemini-2.5-flash-lite", "gemini25flashlite", "gemini-2.5-flashlite":
160162
.gemini25FlashLite
161163
case "gemini":
162-
.gemini25Flash
164+
.gemini3Flash
163165
case "google":
164166
.gemini25Pro
165167
default:
@@ -379,7 +381,7 @@ public func getAllAvailableModels() -> String {
379381
output += "\nShortcuts:\n"
380382
output += " • claude, claude-opus, opus → claude-opus-4-20250514\n"
381383
output += " • gpt, gpt4 → gpt-4.1\n"
382-
output += " • gemini → gemini-2.5-flash\n"
384+
output += " • gemini → gemini-3-flash\n"
383385
output += " • grok → grok-4-fast-reasoning\n"
384386
output += " • llama, llama3 → llama3.3\n"
385387

@@ -414,13 +416,13 @@ extension ModelSelector {
414416
case .coding:
415417
[.claude, .gpt4o, .google(.gemini25Pro)]
416418
case .vision:
417-
[.claude, .gpt4o, .google(.gemini25Flash)]
419+
[.claude, .gpt4o, .google(.gemini3Flash)]
418420
case .reasoning:
419421
[.openai(.gpt51Mini), .claude, .google(.gemini25Pro)]
420422
case .local:
421423
[.llama, .ollama(.mistralNemo), .ollama(.commandRPlus)]
422424
case .general:
423-
[.claude, .gpt4o, .google(.gemini25Flash), .grok(.grok4FastReasoning), .llama]
425+
[.claude, .gpt4o, .google(.gemini3Flash), .grok(.grok4FastReasoning), .llama]
424426
}
425427
}
426428
}

Sources/Tachikoma/Providers/ProviderParser.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,16 @@ public enum ProviderParser {
232232

233233
private static func parseGoogleModel(_ modelString: String) -> LanguageModel? {
234234
switch modelString.lowercased() {
235+
case "gemini-3-flash", "gemini3flash", "gemini-3flash":
236+
.google(.gemini3Flash)
235237
case "gemini-2.5-pro", "gemini25pro", "gemini2.5pro":
236238
.google(.gemini25Pro)
237239
case "gemini-2.5-flash", "gemini25flash":
238240
.google(.gemini25Flash)
239241
case "gemini-2.5-flash-lite", "gemini25flashlite", "gemini-2.5-flashlite":
240242
.google(.gemini25FlashLite)
241243
case "gemini":
242-
.google(.gemini25Flash)
244+
.google(.gemini3Flash)
243245
default:
244246
nil
245247
}

Sources/Tachikoma/Utilities/UsageTracking.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ public struct ModelCostCalculator: Sendable {
550550
// Google Pricing (estimates)
551551
case let .google(googleModel):
552552
switch googleModel {
553+
case .gemini3Flash: (0.50, 3.00)
553554
case .gemini25Pro: (1.25, 10.00)
554555
case .gemini25Flash: (0.30, 2.50)
555556
case .gemini25FlashLite: (0.10, 0.40)

0 commit comments

Comments
 (0)