@@ -31,12 +31,14 @@ function promiseWithResolvers<T>(): {
3131}
3232
3333/**
34- * A ToolRunner handles the automatic conversation loop between the assistant and tools.
34+ * A BetaToolRunner handles the automatic conversation loop between the assistant and tools.
3535 *
36- * A ToolRunner is an async iterable that yields either BetaMessage or BetaMessageStream objects
37- * depending on the streaming configuration.
36+ * A BetaToolRunner is an async iterable that yields either ChatCompletion or
37+ * ChatCompletionStream objects depending on the streaming configuration.
3838 */
39- export class BetaToolRunner < Stream extends boolean > {
39+ export class BetaToolRunner < Stream extends boolean >
40+ implements AsyncIterable < Stream extends true ? ChatCompletionStream : ChatCompletion >
41+ {
4042 /** Whether the async iterator has been consumed */
4143 #consumed = false ;
4244 /** Whether parameters have been mutated since the last API call */
@@ -72,8 +74,7 @@ export class BetaToolRunner<Stream extends boolean> {
7274 params : BetaToolRunnerParams ,
7375 options ?: BetaToolRunnerRequestOptions ,
7476 ) {
75- params . n ??= 1 ;
76- if ( params && params . n > 1 ) {
77+ if ( params . n && params . n > 1 ) {
7778 throw new Error ( 'BetaToolRunner does not support n > 1' ) ;
7879 }
7980
@@ -97,7 +98,7 @@ export class BetaToolRunner<Stream extends boolean> {
9798 async * [ Symbol . asyncIterator ] ( ) : AsyncIterator <
9899 Stream extends true ?
99100 ChatCompletionStream // TODO: for now!
100- : ChatCompletion | undefined
101+ : ChatCompletion
101102 > {
102103 if ( this . #consumed) {
103104 throw new OpenAIError ( 'Cannot iterate over a consumed stream' ) ;
@@ -123,26 +124,21 @@ export class BetaToolRunner<Stream extends boolean> {
123124 this . #toolResponse = undefined ;
124125 this . #iterationCount++ ;
125126
126- const { ...params } = this . #state. params ;
127- const apiParams = { ...params } ;
128- delete apiParams . max_iterations ; // our own param
127+ const { max_iterations, ...params } = this . #state. params ;
129128
130129 if ( params . stream ) {
131- stream = this . client . beta . chat . completions . stream ( { ...apiParams , stream : true } , this . #options) ;
130+ stream = this . client . chat . completions . stream ( { ...params , stream : true } , this . #options) ;
132131 this . #message = stream . finalMessage ( ) ;
133132
134133 // Make sure that this promise doesn't throw before we get the option to do something about it.
135134 // Error will be caught when we call await this.#message ultimately
136135 this . #message?. catch ( ( ) => { } ) ;
137136 yield stream as any ;
138137 } else {
139- this . #chatCompletion = this . client . beta . chat . completions . create (
138+ this . #chatCompletion = this . client . chat . completions . create (
140139 {
141- ...apiParams , // spread and explicit so we get better types
140+ ...params , // spread and explicit so we get better types
142141 stream : false ,
143- tools : params . tools ,
144- messages : params . messages ,
145- model : params . model ,
146142 } ,
147143 this . #options,
148144 ) ;
@@ -155,15 +151,8 @@ export class BetaToolRunner<Stream extends boolean> {
155151
156152 const prevMessage = await this . #message;
157153
158- if ( ! prevMessage ) {
159- throw new OpenAIError ( 'ToolRunner concluded without a message from the server' ) ;
160- }
161-
162154 if ( ! this . #mutated) {
163- // TODO: what if it is empty?
164- if ( prevMessage ) {
165- this . #state. params . messages . push ( prevMessage ) ;
166- }
155+ this . #state. params . messages . push ( prevMessage ) ;
167156 }
168157
169158 const toolMessages = await this . #generateToolResponse( prevMessage ) ;
@@ -173,7 +162,6 @@ export class BetaToolRunner<Stream extends boolean> {
173162 }
174163 }
175164
176- // TODO: make sure this is correct?
177165 if ( ! toolMessages && ! this . #mutated) {
178166 break ;
179167 }
@@ -206,21 +194,28 @@ export class BetaToolRunner<Stream extends boolean> {
206194 *
207195 * @example
208196 * // Direct parameter update
209- * runner.setMessagesParams ({
197+ * runner.setChatParams ({
210198 * model: 'gpt-4o',
211199 * max_tokens: 500,
212200 * });
213201 *
214202 * @example
215203 * // Using a mutator function
216- * runner.setMessagesParams ((params) => ({
204+ * runner.setChatParams ((params) => ({
217205 * ...params,
218206 * max_tokens: 100,
219207 * }));
208+ *
209+ * @example
210+ * // Appending a user message
211+ * runner.setChatParams((params) => ({
212+ * ...params,
213+ * messages: [...params.messages, { role: 'user', content: 'What colour is the sky?' }],
214+ * }));
220215 */
221- setMessagesParams ( params : BetaToolRunnerParams ) : void ;
222- setMessagesParams ( mutator : ( prevParams : BetaToolRunnerParams ) => BetaToolRunnerParams ) : void ;
223- setMessagesParams (
216+ setChatParams ( params : BetaToolRunnerParams ) : void ;
217+ setChatParams ( mutator : ( prevParams : BetaToolRunnerParams ) => BetaToolRunnerParams ) : void ;
218+ setChatParams (
224219 paramsOrMutator : BetaToolRunnerParams | ( ( prevParams : BetaToolRunnerParams ) => BetaToolRunnerParams ) ,
225220 ) {
226221 if ( typeof paramsOrMutator === 'function' ) {
@@ -343,7 +338,7 @@ export class BetaToolRunner<Stream extends boolean> {
343338 * );
344339 */
345340 pushMessages ( ...messages : ChatCompletionMessageParam [ ] ) {
346- this . setMessagesParams ( ( params ) => ( {
341+ this . setChatParams ( ( params ) => ( {
347342 ...params ,
348343 messages : [ ...params . messages , ...messages ] ,
349344 } ) ) ;
0 commit comments