@@ -865,6 +865,7 @@ async fn main() -> anyhow::Result<()> {
865865 } else {
866866 tools
867867 } ;
868+ apply_headless_review_query_defaults ( & mut query_config, github_context. as_ref ( ) ) ;
868869 let tools = filter_tools_for_hosted_review ( tools, & config) ;
869870
870871 // Spawn the background cron scheduler (fires cron tasks at scheduled times).
@@ -1564,6 +1565,18 @@ fn filter_search_only_tools() -> Arc<Vec<Box<dyn claurst_tools::Tool>>> {
15641565 Arc :: new ( filtered)
15651566}
15661567
1568+ fn apply_headless_review_query_defaults (
1569+ query_config : & mut claurst_query:: QueryConfig ,
1570+ github_context : Option < & SessionBrief > ,
1571+ ) {
1572+ if github_context
1573+ . map ( |brief| brief. review_mode ( ) != headless:: ReviewMode :: None )
1574+ . unwrap_or ( false )
1575+ {
1576+ query_config. max_turns = query_config. max_turns . max ( 20 ) ;
1577+ }
1578+ }
1579+
15671580// ---------------------------------------------------------------------------
15681581// Headless mode: read prompt from arg/stdin, run, print response
15691582// ---------------------------------------------------------------------------
@@ -5253,6 +5266,49 @@ mod tests {
52535266 }
52545267 }
52555268
5269+ #[ test]
5270+ fn hosted_review_headless_gets_extra_turn_budget ( ) {
5271+ let raw = r#"{
5272+ "contract_version": "2",
5273+ "trigger": "issue_mention",
5274+ "repo": { "owner": "o", "name": "r", "clone_url": "https://github.com/o/r.git", "default_branch": "main" },
5275+ "task": { "kind": "respond_to_mention", "issue_number": 7, "comment_body": "review this" },
5276+ "familiar": { "id": "cody", "display_name": "Cody", "skills": [] },
5277+ "workspace": { "root": "/tmp/ws" },
5278+ "review_context": { "kind": "pull_request", "files": [{ "filename": "src/lib.rs" }] }
5279+ }"# ;
5280+ let brief: SessionBrief = serde_json:: from_str ( raw) . expect ( "brief parses" ) ;
5281+ let mut query_config = claurst_query:: QueryConfig {
5282+ max_turns : 10 ,
5283+ ..Default :: default ( )
5284+ } ;
5285+
5286+ apply_headless_review_query_defaults ( & mut query_config, Some ( & brief) ) ;
5287+
5288+ assert_eq ! ( query_config. max_turns, 20 ) ;
5289+ }
5290+
5291+ #[ test]
5292+ fn non_review_headless_keeps_turn_budget ( ) {
5293+ let raw = r#"{
5294+ "contract_version": "2",
5295+ "trigger": "issue_mention",
5296+ "repo": { "owner": "o", "name": "r", "clone_url": "https://github.com/o/r.git", "default_branch": "main" },
5297+ "task": { "kind": "respond_to_mention", "issue_number": 7, "comment_body": "answer this" },
5298+ "familiar": { "id": "cody", "display_name": "Cody", "skills": [] },
5299+ "workspace": { "root": "/tmp/ws" }
5300+ }"# ;
5301+ let brief: SessionBrief = serde_json:: from_str ( raw) . expect ( "brief parses" ) ;
5302+ let mut query_config = claurst_query:: QueryConfig {
5303+ max_turns : 10 ,
5304+ ..Default :: default ( )
5305+ } ;
5306+
5307+ apply_headless_review_query_defaults ( & mut query_config, Some ( & brief) ) ;
5308+
5309+ assert_eq ! ( query_config. max_turns, 10 ) ;
5310+ }
5311+
52565312 #[ test]
52575313 fn hosted_review_filters_write_and_execute_tools_by_default ( ) {
52585314 let all = Arc :: new ( claurst_tools:: all_tools ( ) ) ;
0 commit comments