44using BotSharp . Abstraction . Translation . Models ;
55using Fluid ;
66using Fluid . Ast ;
7+ using Fluid . Values ;
78using System . Collections ;
89using System . IO ;
910using System . Reflection ;
1011using System . Text . Encodings . Web ;
12+ using System . Text . RegularExpressions ;
1113
1214namespace BotSharp . Core . Templating ;
1315
@@ -36,9 +38,11 @@ public TemplateRender(IServiceProvider services, ILogger<TemplateRender> logger)
3638 _options . MemberAccessStrategy . Register < UserIdentity > ( ) ;
3739 _options . MemberAccessStrategy . Register < TranslationInput > ( ) ;
3840
39- _parser . RegisterIdentifierTag ( "link" , ( string identifier , TextWriter writer , TextEncoder encoder , TemplateContext context ) =>
41+ _options . Filters . AddFilter ( "from_agent" , FromAgentFilter ) ;
42+
43+ _parser . RegisterExpressionTag ( "link" , ( Expression expression , TextWriter writer , TextEncoder encoder , TemplateContext context ) =>
4044 {
41- return RenderIdentifierTag ( "link" , identifier , writer , encoder , context ) ;
45+ return RenderTag ( "link" , expression , writer , encoder , context , services ) ;
4246 } ) ;
4347 }
4448
@@ -82,20 +86,46 @@ public void RegisterType(Type type)
8286
8387
8488 #region Private methods
85- private static async ValueTask < Completion > RenderIdentifierTag ( string tag , string identifier , TextWriter writer , TextEncoder encoder , TemplateContext context )
89+ private static async ValueTask < Completion > RenderTag (
90+ string tag ,
91+ Expression expression ,
92+ TextWriter writer ,
93+ TextEncoder encoder ,
94+ TemplateContext context ,
95+ IServiceProvider services )
8696 {
8797 try
8898 {
89- var value = await context . Model . GetValueAsync ( TemplateRenderConstant . RENDER_AGENT , context ) ;
99+ var value = await expression . EvaluateAsync ( context ) ;
100+ var expStr = value ? . ToStringValue ( ) ?? string . Empty ;
101+
102+ value = await context . Model . GetValueAsync ( TemplateRenderConstant . RENDER_AGENT , context ) ;
90103 var agent = value ? . ToObjectValue ( ) as Agent ;
91- var found = agent ? . Templates ? . FirstOrDefault ( x => x . Name . IsEqualTo ( identifier ) ) ;
92- var key = $ "{ agent ? . Id } | { tag } | { identifier } ";
93104
94- if ( found == null || ( context . AmbientValues . TryGetValue ( key , out var visited ) && ( bool ) visited ) )
105+ var splited = Regex . Split ( expStr , @"\s*from_agent\s*" , RegexOptions . IgnoreCase | RegexOptions . CultureInvariant )
106+ . Where ( x => ! string . IsNullOrWhiteSpace ( x ) )
107+ . Select ( x => x . Trim ( ) )
108+ . ToArray ( ) ;
109+
110+ var templateName = splited . ElementAtOrDefault ( 0 ) ;
111+ var agentName = splited . ElementAtOrDefault ( 1 ) ;
112+
113+ if ( splited . Length > 1 && ! agentName . IsEqualTo ( agent ? . Name ) )
114+ {
115+ using var scope = services . CreateScope ( ) ;
116+ var agentService = scope . ServiceProvider . GetRequiredService < IAgentService > ( ) ;
117+ var result = await agentService . GetAgents ( new ( ) { SimilarName = agentName } ) ;
118+ agent = result ? . Items ? . FirstOrDefault ( ) ;
119+ }
120+
121+ var template = agent ? . Templates ? . FirstOrDefault ( x => x . Name . IsEqualTo ( templateName ) ) ;
122+ var key = $ "{ tag } | { agent ? . Id } | { templateName } ";
123+
124+ if ( template == null || ( context . AmbientValues . TryGetValue ( key , out var visited ) && ( bool ) visited ) )
95125 {
96126 writer . Write ( string . Empty ) ;
97127 }
98- else if ( _parser . TryParse ( found . Content , out var t , out _ ) )
128+ else if ( _parser . TryParse ( template . Content , out var t , out _ ) )
99129 {
100130 context . AmbientValues [ key ] = true ;
101131 var rendered = t . Render ( context ) ;
@@ -115,6 +145,16 @@ private static async ValueTask<Completion> RenderIdentifierTag(string tag, strin
115145 return Completion . Normal ;
116146 }
117147
148+ private static ValueTask < FluidValue > FromAgentFilter (
149+ FluidValue input ,
150+ FilterArguments arguments ,
151+ TemplateContext context )
152+ {
153+ var inputStr = input ? . ToStringValue ( ) ?? string . Empty ;
154+ var fromAgent = arguments . At ( 0 ) . ToStringValue ( ) ;
155+ return new StringValue ( $ "{ inputStr } from_agent { fromAgent } ") ;
156+ }
157+
118158 private static bool IsStringType ( Type type )
119159 {
120160 return type == typeof ( string ) ;
0 commit comments