@@ -30,12 +30,27 @@ impl OpenAIClient {
30
30
#[ async_trait]
31
31
impl LlmClient for OpenAIClient {
32
32
async fn create_session ( & self , config : SessionConfig ) -> Result < Box < dyn LlmSession > > {
33
+ let cached_tools = config
34
+ . tools
35
+ . iter ( )
36
+ . map ( |t| oai:: ChatCompletionTool {
37
+ r#type : oai:: ChatCompletionToolType :: Function ,
38
+ function : oai:: FunctionObject {
39
+ name : t. name . clone ( ) ,
40
+ description : Some ( t. description . clone ( ) ) ,
41
+ parameters : Some ( tool_definition_to_params_json ( t) ) ,
42
+ strict : Some ( true ) ,
43
+ } ,
44
+ } )
45
+ . collect :: < Vec < _ > > ( ) ;
46
+
33
47
Ok ( Box :: new ( OpenAISession {
34
48
client : self . client . clone ( ) ,
35
49
base_url : self . base_url . clone ( ) ,
36
50
api_key : self . api_key . clone ( ) ,
37
51
config,
38
52
messages : Vec :: new ( ) ,
53
+ cached_tools,
39
54
} ) )
40
55
}
41
56
}
@@ -45,6 +60,7 @@ struct OpenAISession {
45
60
base_url : String ,
46
61
api_key : String ,
47
62
config : SessionConfig ,
63
+ cached_tools : Vec < oai:: ChatCompletionTool > ,
48
64
messages : Vec < oai:: ChatCompletionRequestMessage > ,
49
65
}
50
66
@@ -72,6 +88,30 @@ fn tool_definition_to_params_json(tool: &ToolDefinition) -> serde_json::Value {
72
88
}
73
89
74
90
impl OpenAISession {
91
+ fn new ( client : Client , base_url : String , api_key : String , config : SessionConfig ) -> Self {
92
+ let cached_tools = config
93
+ . tools
94
+ . iter ( )
95
+ . map ( |t| oai:: ChatCompletionTool {
96
+ r#type : oai:: ChatCompletionToolType :: Function ,
97
+ function : oai:: FunctionObject {
98
+ name : t. name . clone ( ) ,
99
+ description : Some ( t. description . clone ( ) ) ,
100
+ parameters : Some ( tool_definition_to_params_json ( t) ) ,
101
+ strict : None ,
102
+ } ,
103
+ } )
104
+ . collect ( ) ;
105
+ Self {
106
+ client,
107
+ base_url,
108
+ api_key,
109
+ config,
110
+ messages : Vec :: new ( ) ,
111
+ cached_tools,
112
+ }
113
+ }
114
+
75
115
fn add_user_message ( & mut self , content : String ) {
76
116
// Add system prompt if this is the first message
77
117
if self . messages . is_empty ( ) && self . config . system_prompt . is_some ( ) {
@@ -109,25 +149,10 @@ impl OpenAISession {
109
149
async fn complete ( & mut self ) -> Result < CompletionResult > {
110
150
// Build request
111
151
112
- let tools = self
113
- . config
114
- . tools
115
- . iter ( )
116
- . map ( |t| oai:: ChatCompletionTool {
117
- r#type : oai:: ChatCompletionToolType :: Function ,
118
- function : oai:: FunctionObject {
119
- name : t. name . clone ( ) ,
120
- description : Some ( t. description . clone ( ) ) ,
121
- parameters : Some ( tool_definition_to_params_json ( & t) ) ,
122
- strict : None ,
123
- } ,
124
- } )
125
- . collect ( ) ;
126
-
127
152
let request = oai:: CreateChatCompletionRequest {
128
153
model : self . config . model . clone ( ) ,
129
154
messages : self . messages . clone ( ) ,
130
- tools : Some ( tools ) ,
155
+ tools : Some ( self . cached_tools . clone ( ) ) ,
131
156
parallel_tool_calls : Some ( true ) ,
132
157
..Default :: default ( )
133
158
} ;
@@ -157,57 +182,41 @@ impl OpenAISession {
157
182
158
183
let choice = completion
159
184
. choices
160
- . into_iter ( )
161
- . next ( )
185
+ . first ( )
162
186
. ok_or_else ( || anyhow ! ( "No choices in response" ) ) ?;
163
187
164
- let message = choice. message ;
188
+ let message = & choice. message ;
189
+
190
+ let message_content = message
191
+ . content
192
+ . clone ( )
193
+ . map ( ChatCompletionRequestAssistantMessageContent :: Text ) ;
194
+
195
+ self
196
+ . messages
197
+ . push ( oai:: ChatCompletionRequestMessage :: Assistant (
198
+ oai:: ChatCompletionRequestAssistantMessage {
199
+ content : message_content,
200
+ tool_calls : message. tool_calls . clone ( ) ,
201
+ ..Default :: default ( )
202
+ } ,
203
+ ) ) ;
165
204
166
205
let result = CompletionResult {
167
206
content : message. content . clone ( ) ,
168
207
tool_calls : message
169
208
. tool_calls
170
- . unwrap_or_default ( )
171
- . into_iter ( )
209
+ . as_ref ( )
210
+ . unwrap_or ( & Vec :: new ( ) )
211
+ . iter ( )
172
212
. map ( |tc| ToolCall {
173
- id : tc. id ,
174
- name : tc. function . name ,
213
+ id : tc. id . clone ( ) ,
214
+ name : tc. function . name . clone ( ) ,
175
215
arguments : serde_json:: from_str ( & tc. function . arguments ) . unwrap_or_default ( ) ,
176
216
} )
177
217
. collect ( ) ,
178
218
} ;
179
219
180
- // Add assistant message to history
181
- self
182
- . messages
183
- . push ( oai:: ChatCompletionRequestMessage :: Assistant (
184
- oai:: ChatCompletionRequestAssistantMessage {
185
- content : result
186
- . content
187
- . clone ( )
188
- . map ( ChatCompletionRequestAssistantMessageContent :: Text ) ,
189
- tool_calls : if result. tool_calls . is_empty ( ) {
190
- None
191
- } else {
192
- Some (
193
- result
194
- . tool_calls
195
- . iter ( )
196
- . map ( |tc| oai:: ChatCompletionMessageToolCall {
197
- id : tc. id . clone ( ) ,
198
- r#type : oai:: ChatCompletionToolType :: Function ,
199
- function : oai:: FunctionCall {
200
- name : tc. name . clone ( ) ,
201
- arguments : tc. arguments . to_string ( ) ,
202
- } ,
203
- } )
204
- . collect ( ) ,
205
- )
206
- } ,
207
- ..Default :: default ( )
208
- } ,
209
- ) ) ;
210
-
211
220
Ok ( result)
212
221
}
213
222
}
@@ -223,7 +232,7 @@ impl LlmSession for OpenAISession {
223
232
self . add_user_message ( content) ;
224
233
let result = self . complete ( ) . await ?;
225
234
226
- // Just emit the final completion event
235
+ // Just emit the final completion event for now
227
236
Ok ( Box :: new ( Box :: pin ( stream:: once ( async move {
228
237
Ok ( LlmEvent :: Completion ( result) )
229
238
} ) ) ) )
@@ -241,7 +250,7 @@ impl LlmSession for OpenAISession {
241
250
self . add_tool_results ( results) ;
242
251
let result = self . complete ( ) . await ?;
243
252
244
- // Just emit the final completion event
253
+ // Just emit the final completion event for now
245
254
Ok ( Box :: new ( Box :: pin ( stream:: once ( async move {
246
255
Ok ( LlmEvent :: Completion ( result) )
247
256
} ) ) ) )
0 commit comments