@@ -341,41 +341,37 @@ impl Dotprompt {
341341 } ,
342342 ) ;
343343
344- // Add @state from context.state if available
344+ // Add all context variables as @-prefixed variables
345+ // Each key in context becomes accessible as @key in templates
346+ // e.g., context: {state: {...}, auth: {...}} creates @state and @auth
347+ let mut template_to_render = parsed. template . clone ( ) ;
345348 if let ( serde_json:: Value :: Object ( map) , Some ( context) ) =
346349 ( & mut render_context, & data. context )
347350 {
348- // context is HashMap<String, Value>, get "state" key
349- // Add state as __state ( workaround for Handlebars @ prefix)
350- if let Some ( state ) = context . get ( "state" ) {
351- if let Some ( state_obj ) = state . as_object ( ) {
352- for ( k , v ) in state_obj {
353- // Add each state field as __state.field
354- let at_state = map
355- . entry ( "__state" . to_string ( ) )
356- . or_insert ( serde_json :: Value :: Object ( serde_json :: Map :: new ( ) ) ) ;
357- if let serde_json :: Value :: Object ( at_state_map ) = at_state {
358- at_state_map . insert ( k . clone ( ) , v . clone ( ) ) ;
359- }
360- }
361- } else {
362- // If state is not an object, just insert it directly
363- map . insert ( "__state" . to_string ( ) , state . clone ( ) ) ;
364- }
351+ for ( key , value ) in context {
352+ // Use __ctx_{key} as workaround since Handlebars treats @ as private data prefix
353+ let internal_key = format ! ( "__ctx_{key}" ) ;
354+ map . insert ( internal_key . clone ( ) , value . clone ( ) ) ;
355+
356+ // Replace all occurrences of @{key} with __ctx_{key} in template
357+ template_to_render = template_to_render
358+ . replace ( & format ! ( "{{{{@{key}." ) , & format ! ( "{{{{__{key}." ) )
359+ . replace ( & format ! ( "{{{{ @{key}." ) , & format ! ( "{{{{ __{key}." ) ) ;
360+
361+ // Also handle shortcut for just the key (e.g., {{@isAdmin}})
362+ template_to_render = template_to_render
363+ . replace ( & format ! ( "{{{{@{key}}}}}" ) , & format ! ( "{{{{__{key}}}}}" ) )
364+ . replace ( & format ! ( "{{{{ @{key} }}}}" ) , & format ! ( "{{{{ __{key} }}}}" ) ) ;
365+
366+ // Insert with __ prefix for template access
367+ map . insert ( format ! ( "__{key}" ) , value . clone ( ) ) ;
365368 }
366369 }
367370
368- // Preprocess template to replace @state with __state for Handlebars compatibility
369- // Handlebars treats @ as special prefix for private data, so we use __state as workaround
370- let preprocessed_template = parsed
371- . template
372- . replace ( "{{@state." , "{{__state." )
373- . replace ( "{{ @state." , "{{ __state." ) ;
374-
375371 // Render template
376372 let rendered_string = self
377373 . handlebars
378- . render_template ( & preprocessed_template , & render_context)
374+ . render_template ( & template_to_render , & render_context)
379375 . map_err ( |e| DotpromptError :: RenderError ( e. to_string ( ) ) ) ?;
380376
381377 // Convert to messages (passing data for history)
0 commit comments