Model Picker — Swift source
Filter every major model by context window, price, modality, and tier — sort by cost, context, or tokens-per-dollar to find the right model for the task.
This is the Swift implementation — the same logic the interactive tool runs, in a shareable, citable form.
// model-picker — Swift port: filter + rank the AI model catalog.
import Foundation
/// Pricing projection of the TS AiModel record; optionals play TS null.
struct Model {
let id: String, tier: String
let contextWindow: Int // context window in tokens.
let inputPerM: Double?, outputPerM: Double? // USD per 1M tokens; nil = unpriced.
let released: String? // ISO date; nil = unknown.
}
/// Projection of the TS ModelFilter — the three constraints the presets use.
struct ModelFilter {
var tier: String? = nil
var minContext: Int? = nil
var maxInputPerM: Double? = nil // nil prices never satisfy this.
}
/// Curated entry points: a filter + the sort that makes that filter useful.
let presets: [String: (filter: ModelFilter, sort: String)] = [
"long-context": (ModelFilter(minContext: 500_000), "context"),
"cheap-bulk": (ModelFilter(maxInputPerM: 1), "price"),
"flagship": (ModelFilter(tier: "flagship"), "tokensPerDollar"),
]
/// Output tokens per USD: 1e6 / outputPerM, or nil when unpriced.
func tokensPerDollar(_ m: Model) -> Double? { m.outputPerM.map { 1_000_000 / $0 } }
/// Comparator core: value order (desc when asked), nil last, id asc on ties —
/// the TS COMPARATORS contract; full ordering keeps sorted(by:) deterministic.
func rank<T: Comparable>(desc: Bool = false, _ key: @escaping (Model) -> T?) -> (Model, Model) -> Bool {
{ a, b in
switch (key(a), key(b)) {
case (nil, nil): return a.id < b.id
case (nil, _): return false // a is nil — sorts after everything.
case (_, nil): return true
case let (va?, vb?): return va == vb ? a.id < b.id : (desc ? va > vb : va < vb)
}
}
}
/// Sort comparator per key: value order first, nil last, id asc on ties.
let comparators: [String: (Model, Model) -> Bool] = [
"price": rank { $0.inputPerM },
"context": rank(desc: true) { $0.contextWindow },
"tokensPerDollar": rank(desc: true) { tokensPerDollar($0) },
"released": rank(desc: true) { $0.released },
]
/// Filter step, inlined from listModels in src/lib/ai/models.ts (nil prices never satisfy maxInputPerM).
func listModels(_ models: [Model], _ filter: ModelFilter = ModelFilter()) -> [Model] {
models.filter { m in
(filter.tier == nil || m.tier == filter.tier) &&
(filter.minContext == nil || m.contextWindow >= filter.minContext!) &&
(filter.maxInputPerM == nil ||
(m.inputPerM != nil && m.inputPerM! <= filter.maxInputPerM!))
}
}
/// Filter the model list, then sort it (see comparators for the exact order).
func pickModels(_ models: [Model], _ filter: ModelFilter = ModelFilter(), _ sort: String = "price") -> [Model] {
listModels(models, filter).sorted(by: comparators[sort]!)
}
let models = [
Model(id: "atlas-flagship", tier: "flagship", contextWindow: 1_000_000, inputPerM: 3.0, outputPerM: 15.0, released: "2025-03-01"),
Model(id: "atlas-mini", tier: "fast", contextWindow: 200_000, inputPerM: 0.5, outputPerM: 2.0, released: "2025-01-15"),
Model(id: "nova-open", tier: "balanced", contextWindow: 1_000_000, inputPerM: nil, outputPerM: nil, released: nil), // unpriced
Model(id: "zeta-budget", tier: "budget", contextWindow: 128_000, inputPerM: 0.5, outputPerM: 1.0, released: "2024-12-01"),
]
let preset = presets["long-context"]!
print("long-context (minContext >= \(preset.filter.minContext!), sort \(preset.sort)):")
for m in pickModels(models, preset.filter, preset.sort) {
print(" \(m.id.padding(toLength: 14, withPad: " ", startingAt: 0))ctx \(m.contextWindow)")
}
print("price sort (all models, unpriced last, ties by id):")
for m in pickModels(models) {
let label = m.id.padding(toLength: 14, withPad: " ", startingAt: 0)
if let price = m.inputPerM { print(" \(label)$\(String(format: "%.2f", price))/M in") }
else { print(" \(label)unpriced") }
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →