11using BotSharp . Abstraction . Coding ;
2- using BotSharp . Abstraction . Coding . Enums ;
32using BotSharp . Abstraction . Coding . Contexts ;
3+ using BotSharp . Abstraction . Coding . Enums ;
44using BotSharp . Abstraction . Files . Options ;
55using BotSharp . Abstraction . Files . Proccessors ;
66using BotSharp . Abstraction . Instructs ;
@@ -23,7 +23,6 @@ public async Task<InstructResult> Execute(
2323 FileInstructOptions ? fileOptions = null )
2424 {
2525 var agentService = _services . GetRequiredService < IAgentService > ( ) ;
26- var state = _services . GetRequiredService < IConversationStateService > ( ) ;
2726 var agent = await agentService . LoadAgent ( agentId ) ;
2827
2928 var response = new InstructResult
@@ -32,7 +31,6 @@ public async Task<InstructResult> Execute(
3231 Template = templateName
3332 } ;
3433
35-
3634 if ( agent == null )
3735 {
3836 response . Text = $ "Agent (id: { agentId } ) does not exist!";
@@ -46,112 +44,14 @@ public async Task<InstructResult> Execute(
4644 return response ;
4745 }
4846
49-
5047 // Run code template
5148 var codeResponse = await RunCode ( agent , message , templateName , codeOptions ) ;
52- if ( ! string . IsNullOrWhiteSpace ( codeResponse ? . Text ) )
49+ if ( codeResponse != null )
5350 {
5451 return codeResponse ;
5552 }
5653
57-
58- // Before completion hooks
59- var hooks = _services . GetHooks < IInstructHook > ( agentId ) ;
60- foreach ( var hook in hooks )
61- {
62- await hook . BeforeCompletion ( agent , message ) ;
63-
64- // Interrupted by hook
65- if ( message . StopCompletion )
66- {
67- return new InstructResult
68- {
69- MessageId = message . MessageId ,
70- Text = message . Content
71- } ;
72- }
73- }
74-
75-
76- var provider = string . Empty ;
77- var model = string . Empty ;
78- var result = string . Empty ;
79-
80- // Render prompt
81- var prompt = string . IsNullOrEmpty ( templateName ) ?
82- agentService . RenderInstruction ( agent ) :
83- agentService . RenderTemplate ( agent , templateName ) ;
84-
85- var completer = CompletionProvider . GetCompletion ( _services ,
86- agentConfig : agent . LlmConfig ) ;
87-
88- if ( completer is ITextCompletion textCompleter )
89- {
90- instruction = null ;
91- provider = textCompleter . Provider ;
92- model = textCompleter . Model ;
93-
94- result = await GetTextCompletion ( textCompleter , agent , prompt , message . MessageId ) ;
95- response . Text = result ;
96- }
97- else if ( completer is IChatCompletion chatCompleter )
98- {
99- provider = chatCompleter . Provider ;
100- model = chatCompleter . Model ;
101-
102-
103- if ( instruction == "#TEMPLATE#" )
104- {
105- instruction = prompt ;
106- prompt = message . Content ;
107- }
108-
109- IFileProcessor ? fileProcessor = null ;
110- if ( ! files . IsNullOrEmpty ( ) && fileOptions != null )
111- {
112- fileProcessor = _services . GetServices < IFileProcessor > ( )
113- . FirstOrDefault ( x => x . Provider . IsEqualTo ( fileOptions . Processor ) ) ;
114- }
115-
116- if ( fileProcessor != null )
117- {
118- var fileResponse = await fileProcessor . HandleFilesAsync ( agent , prompt , files , new FileHandleOptions
119- {
120- Provider = provider ,
121- Model = model ,
122- Instruction = instruction ,
123- UserMessage = message . Content ,
124- TemplateName = templateName ,
125- InvokeFrom = $ "{ nameof ( InstructService ) } .{ nameof ( Execute ) } ",
126- Data = state . GetStates ( ) . ToDictionary ( x => x . Key , x => ( object ) x . Value )
127- } ) ;
128- result = fileResponse . Result . IfNullOrEmptyAs ( string . Empty ) ;
129- }
130- else
131- {
132- result = await GetChatCompletion ( chatCompleter , agent , instruction , prompt , message . MessageId , files ) ;
133- }
134- response . Text = result ;
135- }
136-
137- response . LogId = Guid . NewGuid ( ) . ToString ( ) ;
138- // After completion hooks
139- foreach ( var hook in hooks )
140- {
141- await hook . AfterCompletion ( agent , response ) ;
142- await hook . OnResponseGenerated ( new InstructResponseModel
143- {
144- LogId = response . LogId ,
145- AgentId = agentId ,
146- Provider = provider ,
147- Model = model ,
148- TemplateName = templateName ,
149- UserMessage = prompt ,
150- SystemInstruction = instruction ,
151- CompletionText = response . Text
152- } ) ;
153- }
154-
54+ response = await RunLlm ( agent , message , instruction , templateName , files , fileOptions ) ;
15555 return response ;
15656 }
15757
@@ -166,7 +66,7 @@ await hook.OnResponseGenerated(new InstructResponseModel
16666 private async Task < InstructResult ? > RunCode (
16767 Agent agent ,
16868 RoleDialogModel message ,
169- string templateName ,
69+ string ? templateName ,
17070 CodeInstructOptions ? codeOptions )
17171 {
17272 InstructResult ? instructResult = null ;
@@ -266,11 +166,16 @@ await hook.OnResponseGenerated(new InstructResponseModel
266166 UseProcess = useProcess
267167 } , cancellationToken : cts . Token ) ;
268168
169+ if ( codeResponse == null || ! codeResponse . Success )
170+ {
171+ return instructResult ;
172+ }
173+
269174 instructResult = new InstructResult
270175 {
271176 MessageId = message . MessageId ,
272177 Template = context . CodeScript ? . Name ,
273- Text = codeResponse ? . Result ?? string . Empty
178+ Text = codeResponse . Result
274179 } ;
275180
276181 var codeExecution = new CodeExecutionResponseModel
@@ -292,6 +197,123 @@ await hook.OnResponseGenerated(new InstructResponseModel
292197 return instructResult ;
293198 }
294199
200+
201+ private async Task < InstructResult > RunLlm (
202+ Agent agent ,
203+ RoleDialogModel message ,
204+ string ? instruction ,
205+ string ? templateName ,
206+ IEnumerable < InstructFileModel > ? files = null ,
207+ FileInstructOptions ? fileOptions = null )
208+ {
209+ var agentService = _services . GetRequiredService < IAgentService > ( ) ;
210+ var state = _services . GetRequiredService < IConversationStateService > ( ) ;
211+
212+ var response = new InstructResult
213+ {
214+ MessageId = message . MessageId ,
215+ Template = templateName
216+ } ;
217+
218+ // Before completion hooks
219+ var hooks = _services . GetHooks < IInstructHook > ( agent . Id ) ;
220+ foreach ( var hook in hooks )
221+ {
222+ await hook . BeforeCompletion ( agent , message ) ;
223+
224+ // Interrupted by hook
225+ if ( message . StopCompletion )
226+ {
227+ return new InstructResult
228+ {
229+ MessageId = message . MessageId ,
230+ Text = message . Content
231+ } ;
232+ }
233+ }
234+
235+ var provider = string . Empty ;
236+ var model = string . Empty ;
237+ var result = string . Empty ;
238+
239+ // Render prompt
240+ var prompt = string . IsNullOrEmpty ( templateName ) ?
241+ agentService . RenderInstruction ( agent ) :
242+ agentService . RenderTemplate ( agent , templateName ) ;
243+
244+ var completer = CompletionProvider . GetCompletion ( _services ,
245+ agentConfig : agent . LlmConfig ) ;
246+
247+ if ( completer is ITextCompletion textCompleter )
248+ {
249+ instruction = null ;
250+ provider = textCompleter . Provider ;
251+ model = textCompleter . Model ;
252+
253+ result = await GetTextCompletion ( textCompleter , agent , prompt , message . MessageId ) ;
254+ response . Text = result ;
255+ }
256+ else if ( completer is IChatCompletion chatCompleter )
257+ {
258+ provider = chatCompleter . Provider ;
259+ model = chatCompleter . Model ;
260+
261+ if ( instruction == "#TEMPLATE#" )
262+ {
263+ instruction = prompt ;
264+ prompt = message . Content ;
265+ }
266+
267+ IFileProcessor ? fileProcessor = null ;
268+ if ( ! files . IsNullOrEmpty ( ) && fileOptions != null )
269+ {
270+ fileProcessor = _services . GetServices < IFileProcessor > ( )
271+ . FirstOrDefault ( x => x . Provider . IsEqualTo ( fileOptions . Processor ) ) ;
272+ }
273+
274+ if ( fileProcessor != null )
275+ {
276+ var fileResponse = await fileProcessor . HandleFilesAsync ( agent , prompt , files , new FileHandleOptions
277+ {
278+ Provider = provider ,
279+ Model = model ,
280+ Instruction = instruction ,
281+ UserMessage = message . Content ,
282+ TemplateName = templateName ,
283+ InvokeFrom = $ "{ nameof ( InstructService ) } .{ nameof ( Execute ) } ",
284+ Data = state . GetStates ( ) . ToDictionary ( x => x . Key , x => ( object ) x . Value )
285+ } ) ;
286+ result = fileResponse . Result . IfNullOrEmptyAs ( string . Empty ) ;
287+ }
288+ else
289+ {
290+ result = await GetChatCompletion ( chatCompleter , agent , instruction , prompt , message . MessageId , files ) ;
291+ }
292+ response . Text = result ;
293+ }
294+
295+ response . LogId = Guid . NewGuid ( ) . ToString ( ) ;
296+ // After completion hooks
297+ foreach ( var hook in hooks )
298+ {
299+ await hook . AfterCompletion ( agent , response ) ;
300+ await hook . OnResponseGenerated ( new InstructResponseModel
301+ {
302+ LogId = response . LogId ,
303+ AgentId = agent . Id ,
304+ Provider = provider ,
305+ Model = model ,
306+ TemplateName = templateName ,
307+ UserMessage = prompt ,
308+ SystemInstruction = instruction ,
309+ CompletionText = response . Text
310+ } ) ;
311+ }
312+
313+ return response ;
314+ }
315+
316+
295317 private async Task < string > GetTextCompletion (
296318 ITextCompletion textCompleter ,
297319 Agent agent ,
0 commit comments