Match role service tier precedence

This commit is contained in:
Ahmed Ibrahim
2026-05-11 23:50:47 +03:00
parent 04a51a3542
commit 9b0fc86046
4 changed files with 60 additions and 4 deletions

View File

@@ -82,6 +82,9 @@ impl ToolHandler for Handler {
.await;
let mut config =
build_agent_spawn_config(&session.get_base_instructions().await, turn.as_ref())?;
if let Some(service_tier) = args.service_tier.as_ref() {
config.service_tier = Some(service_tier.clone());
}
if args.fork_context {
reject_full_fork_spawn_overrides(
role_name,

View File

@@ -342,9 +342,13 @@ pub(crate) async fn apply_spawn_agent_service_tier(
parent_service_tier: Option<&str>,
requested_service_tier: Option<&str>,
) -> Result<(), FunctionCallError> {
let Some(candidate_service_tier) = requested_service_tier
.map(str::to_string)
.or_else(|| config.service_tier.clone())
let requested_service_tier_is_effective =
requested_service_tier.is_some_and(|requested_service_tier| {
config.service_tier.as_deref() == Some(requested_service_tier)
});
let Some(candidate_service_tier) = config
.service_tier
.clone()
.or_else(|| parent_service_tier.map(str::to_string))
else {
config.service_tier = None;
@@ -366,7 +370,7 @@ pub(crate) async fn apply_spawn_agent_service_tier(
return Ok(());
}
if requested_service_tier.is_none() {
if !requested_service_tier_is_effective {
config.service_tier = None;
return Ok(());
}

View File

@@ -567,6 +567,52 @@ async fn spawn_agent_role_service_tier_persists_in_child_config() {
);
}
#[tokio::test]
async fn spawn_agent_role_service_tier_overrides_spawn_argument() {
#[derive(Debug, Deserialize)]
struct SpawnAgentResult {
agent_id: String,
}
let (mut session, mut turn) = make_session_and_context().await;
let role_name = install_role_with_service_tier(&mut turn, "gpt-5.4").await;
let manager = thread_manager();
let root = manager
.start_thread((*turn.config).clone())
.await
.expect("root thread should start");
session.services.agent_control = manager.agent_control();
session.conversation_id = root.thread_id;
let output = SpawnAgentHandler::default()
.handle(invocation(
Arc::new(session),
Arc::new(turn),
"spawn_agent",
function_payload(json!({
"message": "inspect this repo",
"agent_type": role_name,
"service_tier": "turbo"
})),
))
.await
.expect("role-configured service tier should win over the spawn argument");
let (content, _) = expect_text_output(output);
let result: SpawnAgentResult =
serde_json::from_str(&content).expect("spawn_agent result should be json");
let snapshot = manager
.get_thread(parse_agent_id(&result.agent_id))
.await
.expect("spawned agent thread should exist")
.config_snapshot()
.await;
assert_eq!(
snapshot.service_tier,
Some(ServiceTier::Fast.request_value().to_string())
);
}
#[tokio::test]
async fn spawn_agent_service_tier_override_rejects_unknown_tier() {
let (session, turn) = make_session_and_context().await;

View File

@@ -81,6 +81,9 @@ impl ToolHandler for Handler {
.await;
let mut config =
build_agent_spawn_config(&session.get_base_instructions().await, turn.as_ref())?;
if let Some(service_tier) = args.service_tier.as_ref() {
config.service_tier = Some(service_tier.clone());
}
if matches!(fork_mode, Some(SpawnAgentForkMode::FullHistory)) {
reject_full_fork_spawn_overrides(
role_name,