@@ -195,6 +195,10 @@ fn latest_turn_error_message(stored: &StoredSession, turn_id: Option<&str>) -> O
195195
196196fn runtime_thread_read_from_stored_session ( stored : & StoredSession ) -> serde_json:: Value {
197197 let coding_activity = coding_activity_projection:: coding_activity_from_events ( stored) ;
198+ let model_routing = latest_model_routing_from_events ( & stored. events ) ;
199+ let service_model_slot = model_routing
200+ . as_ref ( )
201+ . and_then ( |routing| string_field ( routing, & [ "serviceModelSlot" , "service_model_slot" ] ) ) ;
198202 let latest_turn_status = stored
199203 . turns
200204 . last ( )
@@ -228,6 +232,8 @@ fn runtime_thread_read_from_stored_session(stored: &StoredSession) -> serde_json
228232 "tool_calls" : tool_calls_from_events( & stored. events) ,
229233 "commands" : coding_activity. commands,
230234 "tests" : coding_activity. tests,
235+ "model_routing" : model_routing. clone( ) ,
236+ "service_model_slot" : service_model_slot. clone( ) ,
231237 "artifacts" : artifact_projection:: stored_artifact_summaries_for_turn( stored, None ) ,
232238 "outputs" : output_refs:: read_model_outputs( stored. output_blobs. values( ) , None ) ,
233239 "diagnostics" : {
@@ -240,10 +246,91 @@ fn runtime_thread_read_from_stored_session(stored: &StoredSession) -> serde_json
240246 "runtime_summary" : {
241247 "latestTurnStatus" : latest_turn_status,
242248 "latestTurnErrorMessage" : latest_turn_error_message,
249+ "decisionSource" : model_routing
250+ . as_ref( )
251+ . and_then( |routing| string_field( routing, & [ "decisionSource" , "decision_source" ] ) ) ,
252+ "serviceModelSlot" : service_model_slot,
243253 } ,
244254 } )
245255}
246256
257+ fn latest_model_routing_from_events ( events : & [ AgentEvent ] ) -> Option < serde_json:: Value > {
258+ events
259+ . iter ( )
260+ . rev ( )
261+ . find ( |event| {
262+ matches ! (
263+ event. event_type. as_str( ) ,
264+ "routing.decision.made" | "routing.fallback.applied" | "routing.not_possible"
265+ )
266+ } )
267+ . map ( model_routing_from_event)
268+ }
269+
270+ fn model_routing_from_event ( event : & AgentEvent ) -> serde_json:: Value {
271+ let mut routing = event
272+ . payload
273+ . get ( "routingDecision" )
274+ . or_else ( || event. payload . get ( "routing_decision" ) )
275+ . and_then ( |value| value. as_object ( ) )
276+ . cloned ( )
277+ . unwrap_or_else ( || event. payload . as_object ( ) . cloned ( ) . unwrap_or_default ( ) ) ;
278+
279+ merge_optional_payload_value ( & mut routing, & event. payload , "modelSlot" , "modelSlot" ) ;
280+ merge_optional_payload_value ( & mut routing, & event. payload , "model_slot" , "model_slot" ) ;
281+ merge_optional_payload_value (
282+ & mut routing,
283+ & event. payload ,
284+ "providerReadiness" ,
285+ "providerReadiness" ,
286+ ) ;
287+ merge_optional_payload_value (
288+ & mut routing,
289+ & event. payload ,
290+ "provider_readiness" ,
291+ "provider_readiness" ,
292+ ) ;
293+ routing. insert (
294+ "sourceEventId" . to_string ( ) ,
295+ serde_json:: Value :: String ( event. event_id . clone ( ) ) ,
296+ ) ;
297+ routing. insert (
298+ "source_event_id" . to_string ( ) ,
299+ serde_json:: Value :: String ( event. event_id . clone ( ) ) ,
300+ ) ;
301+ routing. insert (
302+ "sourceEventType" . to_string ( ) ,
303+ serde_json:: Value :: String ( event. event_type . clone ( ) ) ,
304+ ) ;
305+ routing. insert (
306+ "source_event_type" . to_string ( ) ,
307+ serde_json:: Value :: String ( event. event_type . clone ( ) ) ,
308+ ) ;
309+ routing. insert (
310+ "timestamp" . to_string ( ) ,
311+ serde_json:: Value :: String ( event. timestamp . clone ( ) ) ,
312+ ) ;
313+ if event. event_type == "routing.not_possible" {
314+ routing. insert (
315+ "status" . to_string ( ) ,
316+ serde_json:: Value :: String ( "blocked" . to_string ( ) ) ,
317+ ) ;
318+ }
319+
320+ serde_json:: Value :: Object ( routing)
321+ }
322+
323+ fn merge_optional_payload_value (
324+ routing : & mut serde_json:: Map < String , serde_json:: Value > ,
325+ payload : & serde_json:: Value ,
326+ output_key : & str ,
327+ payload_key : & str ,
328+ ) {
329+ if let Some ( value) = payload. get ( payload_key) {
330+ routing. insert ( output_key. to_string ( ) , value. clone ( ) ) ;
331+ }
332+ }
333+
247334pub ( super ) fn replayed_action_required_from_stored_session (
248335 stored : & StoredSession ,
249336 request_id : & str ,
0 commit comments