@@ -30,13 +30,55 @@ export class OpenAIProvider implements LLMProviderInterface {
3030 }
3131 }
3232
33+ private formatMessages ( messages : Message [ ] ) : any [ ] {
34+ const result : any [ ] = [ ] ;
35+
36+ for ( const m of messages ) {
37+ if ( m . role === 'system' ) {
38+ result . push ( { role : 'system' , content : m . content } ) ;
39+ } else if ( m . role === 'user' ) {
40+ if ( m . toolResults && m . toolResults . length > 0 ) {
41+ // Each tool result becomes a separate 'tool' role message
42+ for ( const tr of m . toolResults ) {
43+ result . push ( {
44+ role : 'tool' ,
45+ tool_call_id : tr . toolCallId ,
46+ content : typeof tr . result === 'string'
47+ ? tr . result
48+ : JSON . stringify ( tr . result ) ,
49+ } ) ;
50+ }
51+ } else {
52+ result . push ( { role : 'user' , content : m . content } ) ;
53+ }
54+ } else if ( m . role === 'assistant' ) {
55+ const assistantMsg : any = {
56+ role : 'assistant' ,
57+ content : m . content || null ,
58+ } ;
59+ if ( m . toolCalls && m . toolCalls . length > 0 ) {
60+ assistantMsg . tool_calls = m . toolCalls . map ( tc => ( {
61+ id : tc . toolCallId ,
62+ type : 'function' ,
63+ function : {
64+ name : tc . toolName ,
65+ arguments : typeof tc . args === 'string'
66+ ? tc . args
67+ : JSON . stringify ( tc . args ) ,
68+ } ,
69+ } ) ) ;
70+ }
71+ result . push ( assistantMsg ) ;
72+ }
73+ }
74+
75+ return result ;
76+ }
77+
3378 async chat ( messages : Message [ ] , tools ?: MCPTool [ ] , executeTool ?: ToolExecutor , options ?: LLMProviderOptions ) : Promise < { content : string ; toolCalls ?: ToolCall [ ] } > {
3479 const openaiTools = tools ?. map ( mcpToolToOpenAIFunction ) ;
3580
36- const chatMessages = messages . map ( m => ( {
37- role : m . role as 'user' | 'assistant' | 'system' ,
38- content : m . content
39- } ) ) ;
81+ const chatMessages = this . formatMessages ( messages ) ;
4082
4183 const response = await this . client . chat . completions . create ( {
4284 model : options ?. model || this . model ,
@@ -60,10 +102,7 @@ export class OpenAIProvider implements LLMProviderInterface {
60102 async * streamChat ( messages : Message [ ] , tools ?: MCPTool [ ] , executeTool ?: ToolExecutor , options ?: LLMProviderOptions ) : AsyncIterable < StreamChunk > {
61103 const openaiTools = tools ?. map ( mcpToolToOpenAIFunction ) ;
62104
63- const chatMessages = messages . map ( m => ( {
64- role : m . role as 'user' | 'assistant' | 'system' ,
65- content : m . content
66- } ) ) ;
105+ const chatMessages = this . formatMessages ( messages ) ;
67106
68107 const stream = await this . client . chat . completions . create ( {
69108 model : options ?. model || this . model ,
0 commit comments