use super::effort;
use super::speed::priced_speed;
use super::verbosity_standard;
use crate::model_profile_data::types::{
CostTier, Modality, ModelCost, ModelLimits, ModelModalities, ModelProfile, ReasoningEffort,
ReasoningEffortConfig, Speed, SpeedConfig,
};
pub(super) fn profile_data(model_id: &str) -> Option<ModelProfile> {
match model_id {
"gpt-6-astra" => Some(ModelProfile {
speed: Some(speeds(Speed::Priority, true)),
..profile(
"GPT-6 Astra",
"gpt-6-astra",
"OpenAI's most capable model, built for the hardest end-to-end work: complex reasoning, coding, computer use, research, and document creation.",
"2026-09-04",
"2026-04-30",
[10.00, 50.00, 1.00],
efforts(&ALL_EFFORTS[1..]),
)
}),
"gpt-6-sol" => Some(profile(
"GPT-6 Sol",
"gpt-6-sol",
"Balanced GPT-6 tier. Astra-level reliability for agentic coding and multi-step analysis at a fraction of the cost.",
"2026-09-22",
"2026-04-20",
[2.00, 10.00, 0.20],
efforts(&ALL_EFFORTS),
)),
"gpt-6-luna" => Some(profile(
"GPT-6 Luna",
"gpt-6-luna",
"Fastest, most cost-efficient GPT-6 tier. Built for high-volume, latency-sensitive agent work, classification, extraction, and routing.",
"2026-09-22",
"2026-05-18",
[0.10, 0.50, 0.01],
efforts(&ALL_EFFORTS),
)),
"gpt-6.1-sol" => {
let mut sol = profile(
"GPT-6.1 Sol",
"gpt-6.1-sol",
"Near-Astra performance at a lower cost for complex coding, computer use, and professional work.",
"2026-09-29",
"2026-04-30",
[2.00, 10.00, 0.10],
efforts(&ALL_EFFORTS[1..]),
);
sol.speed = Some(speeds(Speed::Fast, false));
if let Some(limits) = sol.limits.as_mut() {
limits.input = Some(922_000);
}
Some(sol)
}
_ => None,
}
}
const ALL_EFFORTS: [(ReasoningEffort, &str); 6] = [
(ReasoningEffort::None, "None"),
(ReasoningEffort::Low, "Low"),
(ReasoningEffort::Medium, "Medium"),
(ReasoningEffort::High, "High"),
(ReasoningEffort::Xhigh, "Extra High"),
(ReasoningEffort::Max, "Max"),
];
fn efforts(values: &[(ReasoningEffort, &str)]) -> ReasoningEffortConfig {
ReasoningEffortConfig {
values: values
.iter()
.map(|&(value, name)| effort(value, name))
.collect(),
default: ReasoningEffort::Medium,
}
}
fn speeds(premium: Speed, ultrafast: bool) -> SpeedConfig {
let mut values = vec![
priced_speed(Speed::Flex, "Flex", 0.5),
priced_speed(Speed::Default, "Standard", 1.0),
priced_speed(premium, "Fast", 2.0),
];
if ultrafast {
values.push(priced_speed(Speed::Ultrafast, "Ultrafast", 6.0));
}
SpeedConfig {
values,
default: Speed::Default,
}
}
fn profile(
name: &str,
family: &str,
description: &str,
released: &str,
knowledge: &str,
[input, output, cache_read]: [f64; 3],
reasoning_effort: ReasoningEffortConfig,
) -> ModelProfile {
ModelProfile {
name: name.into(),
family: family.into(),
description: Some(description.into()),
release_date: Some(released.into()),
last_updated: Some(released.into()),
attachment: true,
reasoning: true,
temperature: false,
knowledge: Some(knowledge.into()),
tool_call: true,
structured_output: true,
open_weights: false,
cost: Some(ModelCost {
input,
output,
cache_read: Some(cache_read),
cache_write: Some(input * 1.25),
cost_tiers: vec![CostTier {
above_tokens: 272_000,
input: input * 2.0,
output: output * 1.5,
cache_read: Some(cache_read * 2.0),
cache_write: Some(input * 2.5),
}],
}),
limits: Some(ModelLimits {
context: 1_050_000,
input: None,
output: 128_000,
max_media: None,
}),
modalities: Some(ModelModalities {
input: vec![Modality::Text, Modality::Image],
output: vec![Modality::Text],
}),
reasoning_effort: Some(reasoning_effort),
speed: Some(speeds(Speed::Priority, false)),
verbosity: Some(verbosity_standard()),
tool_search: true,
supported_parameters: Vec::new(),
supports_phases: true,
supports_server_compaction: false,
}
}
#[cfg(test)]
mod tests {
use super::super::get_model_profile;
use super::*;
#[test]
fn test_gpt6_profiles() {
for (id, name, knowledge, released, rates, tier_rates, effort_values) in [
(
"gpt-6-astra",
"GPT-6 Astra",
"2026-04-30",
"2026-09-04",
[10.00, 50.00, 1.00],
[20.00, 75.00, 2.00],
&ALL_EFFORTS[1..],
),
(
"gpt-6-sol",
"GPT-6 Sol",
"2026-04-20",
"2026-09-22",
[2.00, 10.00, 0.20],
[4.00, 15.00, 0.40],
&ALL_EFFORTS[..],
),
(
"gpt-6-luna",
"GPT-6 Luna",
"2026-05-18",
"2026-09-22",
[0.10, 0.50, 0.01],
[0.20, 0.75, 0.02],
&ALL_EFFORTS[..],
),
(
"gpt-6.1-sol",
"GPT-6.1 Sol",
"2026-04-30",
"2026-09-29",
[2.00, 10.00, 0.10],
[4.00, 15.00, 0.20],
&ALL_EFFORTS[1..],
),
] {
let profile = get_model_profile("openai", id).unwrap();
assert_eq!(profile.name, name);
assert_eq!(profile.family, id);
assert!(profile.reasoning);
assert!(!profile.temperature);
assert!(profile.tool_call);
assert!(profile.structured_output);
assert!(profile.tool_search);
assert!(profile.supports_phases);
assert!(profile.verbosity.is_some());
assert!(profile.speed.is_some());
assert_eq!(profile.knowledge.as_deref(), Some(knowledge));
assert_eq!(profile.release_date.as_deref(), Some(released));
let limits = profile.limits.unwrap();
assert_eq!(limits.context, 1_050_000);
assert_eq!(limits.output, 128_000);
let close = |a: f64, b: f64| (a - b).abs() < 1e-9;
let cost = profile.cost.unwrap();
assert!(close(cost.input, rates[0]), "{id}");
assert!(close(cost.output, rates[1]), "{id}");
assert!(close(cost.cache_read.unwrap(), rates[2]), "{id}");
assert!(close(cost.cache_write.unwrap(), rates[0] * 1.25), "{id}");
assert_eq!(cost.cost_tiers.len(), 1);
let tier = &cost.cost_tiers[0];
assert_eq!(tier.above_tokens, 272_000);
assert!(close(tier.input, tier_rates[0]), "{id}");
assert!(close(tier.output, tier_rates[1]), "{id}");
assert!(close(tier.cache_read.unwrap(), tier_rates[2]), "{id}");
let effort = profile.reasoning_effort.unwrap();
assert_eq!(effort.default, ReasoningEffort::Medium);
assert_eq!(
effort.values.iter().map(|v| v.value).collect::<Vec<_>>(),
effort_values.iter().map(|&(v, _)| v).collect::<Vec<_>>(),
"{id}"
);
}
}
#[test]
fn test_gpt6_speed_tiers() {
let tiers = |id: &str| {
get_model_profile("openai", id)
.unwrap()
.speed
.unwrap()
.values
.into_iter()
.map(|v| (v.value, v.cost_multiplier))
.collect::<Vec<_>>()
};
use Speed::*;
let base = |premium| {
vec![
(Flex, Some(0.5)),
(Default, Some(1.0)),
(premium, Some(2.0)),
]
};
let mut astra = base(Priority);
astra.push((Ultrafast, Some(6.0)));
assert_eq!(tiers("gpt-6-astra"), astra);
assert_eq!(tiers("gpt-6-sol"), base(Priority));
assert_eq!(tiers("gpt-6-luna"), base(Priority));
assert_eq!(tiers("gpt-6.1-sol"), base(Fast));
let sol = get_model_profile("openai", "gpt-6.1-sol").unwrap();
assert_eq!(sol.limits.unwrap().input, Some(922_000));
}
}