11using BotSharp . Abstraction . Agents ;
22using BotSharp . Abstraction . Agents . Enums ;
33using BotSharp . Abstraction . Conversations ;
4+ using BotSharp . Abstraction . Functions . Models ;
5+ using BotSharp . Abstraction . Routing ;
46using BotSharp . Plugin . GoogleAI . Settings ;
57using LLMSharp . Google . Palm ;
68using Microsoft . Extensions . Logging ;
9+ using System . Diagnostics . Metrics ;
10+ using static System . Net . Mime . MediaTypeNames ;
711
812namespace BotSharp . Plugin . GoogleAI . Providers ;
913
@@ -33,18 +37,42 @@ public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> con
3337 hook . BeforeGenerating ( agent , conversations ) ) . ToArray ( ) ) ;
3438
3539 var client = new GooglePalmClient ( apiKey : _settings . PaLM . ApiKey ) ;
36- var messages = conversations . Select ( c => new PalmChatMessage ( c . Content , c . Role == AgentRole . User ? "user" : "AI" ) )
37- . ToList ( ) ;
3840
39- var agentService = _services . GetRequiredService < IAgentService > ( ) ;
40- var instruction = agentService . RenderedInstruction ( agent ) ;
41- var response = client . ChatAsync ( messages , instruction , null ) . Result ;
41+ var ( prompt , messages ) = PrepareOptions ( agent , conversations ) ;
42+
43+ RoleDialogModel msg ;
44+
45+ if ( messages == null )
46+ {
47+ // use text completion
48+ var response = client . GenerateTextAsync ( prompt , null ) . Result ;
49+
50+ var message = response . Candidates . First ( ) ;
4251
43- var message = response . Candidates . First ( ) ;
44- var msg = new RoleDialogModel ( AgentRole . Assistant , message . Content )
52+ // check if returns function calling
53+ var llmResponse = message . Output . JsonContent < FunctionCallingResponse > ( ) ;
54+
55+ msg = new RoleDialogModel ( llmResponse . Role , llmResponse . Content )
56+ {
57+ CurrentAgentId = agent . Id ,
58+ FunctionName = llmResponse . FunctionName ,
59+ FunctionArgs = JsonSerializer . Serialize ( llmResponse . Args )
60+ } ;
61+ }
62+ else
4563 {
46- CurrentAgentId = agent . Id
47- } ;
64+ var response = client . ChatAsync ( messages , context : prompt , examples : null , options : null ) . Result ;
65+
66+ var message = response . Candidates . First ( ) ;
67+
68+ // check if returns function calling
69+ var llmResponse = message . Content . JsonContent < FunctionCallingResponse > ( ) ;
70+
71+ msg = new RoleDialogModel ( llmResponse . Role , llmResponse . Content ?? message . Content )
72+ {
73+ CurrentAgentId = agent . Id
74+ } ;
75+ }
4876
4977 // After chat completion hook
5078 Task . WaitAll ( hooks . Select ( hook =>
@@ -56,6 +84,48 @@ public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> con
5684 return msg ;
5785 }
5886
87+ private ( string , List < PalmChatMessage > ) PrepareOptions ( Agent agent , List < RoleDialogModel > conversations )
88+ {
89+ var prompt = "" ;
90+
91+ var agentService = _services . GetRequiredService < IAgentService > ( ) ;
92+
93+ if ( ! string . IsNullOrEmpty ( agent . Instruction ) )
94+ {
95+ prompt += agentService . RenderedInstruction ( agent ) ;
96+ }
97+
98+ var routing = _services . GetRequiredService < IRoutingService > ( ) ;
99+ var router = routing . Router ;
100+
101+ if ( agent . Functions != null && agent . Functions . Count > 0 )
102+ {
103+ prompt += "\r \n \r \n [Functions] defined in JSON Schema:\r \n " ;
104+ prompt += JsonSerializer . Serialize ( agent . Functions , new JsonSerializerOptions
105+ {
106+ PropertyNamingPolicy = JsonNamingPolicy . CamelCase ,
107+ WriteIndented = true
108+ } ) ;
109+
110+ prompt += "\r \n \r \n [Conversations]\r \n " ;
111+ foreach ( var dialog in conversations )
112+ {
113+ prompt += dialog . Role == AgentRole . Function ?
114+ $ "{ dialog . Role } : { dialog . FunctionName } => { dialog . Content } \r \n " :
115+ $ "{ dialog . Role } : { dialog . Content } \r \n ";
116+ }
117+
118+ prompt += "\r \n \r \n " + router . Templates . FirstOrDefault ( x => x . Name == "response_with_function" ) . Content ;
119+
120+ return ( prompt , null ) ;
121+ }
122+
123+ var messages = conversations . Select ( c => new PalmChatMessage ( c . Content , c . Role == AgentRole . User ? "user" : "AI" ) )
124+ . ToList ( ) ;
125+
126+ return ( prompt , messages ) ;
127+ }
128+
59129 public Task < bool > GetChatCompletionsAsync ( Agent agent , List < RoleDialogModel > conversations , Func < RoleDialogModel , Task > onMessageReceived , Func < RoleDialogModel , Task > onFunctionExecuting )
60130 {
61131 throw new NotImplementedException ( ) ;
0 commit comments