( messages: ChatCompletionMessageParam[], )
| 253 | * Convert array of ChatCompletionMessageParam to ChatHistoryItem array |
| 254 | */ |
| 255 | export function convertToUnifiedHistory( |
| 256 | messages: ChatCompletionMessageParam[], |
| 257 | ): ChatHistoryItem[] { |
| 258 | const historyItems: ChatHistoryItem[] = []; |
| 259 | const pendingToolCalls: Map<string, ToolCall> = new Map(); |
| 260 | |
| 261 | for (const message of messages) { |
| 262 | const unifiedMessage = convertToUnifiedMessage(message); |
| 263 | |
| 264 | if (unifiedMessage.role === "assistant" && unifiedMessage.toolCalls) { |
| 265 | // Store tool calls for matching with results |
| 266 | const toolCallStates: ToolCallState[] = unifiedMessage.toolCalls.map( |
| 267 | (tc: any) => { |
| 268 | const toolCall: ToolCall = { |
| 269 | id: tc.id || "", |
| 270 | type: "function", |
| 271 | function: { |
| 272 | name: tc.function?.name || "", |
| 273 | arguments: tc.function?.arguments || "", |
| 274 | }, |
| 275 | ...(tc.extra_content && { extra_content: tc.extra_content }), |
| 276 | }; |
| 277 | pendingToolCalls.set(toolCall.id, toolCall); |
| 278 | |
| 279 | return { |
| 280 | toolCallId: toolCall.id, |
| 281 | toolCall, |
| 282 | status: "done" as ToolStatus, // Historical calls are complete |
| 283 | parsedArgs: tryParseJson(toolCall.function.arguments), |
| 284 | }; |
| 285 | }, |
| 286 | ); |
| 287 | |
| 288 | historyItems.push(createHistoryItem(unifiedMessage, [], toolCallStates)); |
| 289 | } else if (unifiedMessage.role === "tool") { |
| 290 | // Tool result - handle separately to reduce nesting |
| 291 | handleToolResult(unifiedMessage, pendingToolCalls, historyItems); |
| 292 | // Don't add tool messages as separate history items |
| 293 | } else { |
| 294 | historyItems.push(createHistoryItem(unifiedMessage)); |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | return historyItems; |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Convert ChatHistoryItem array to ChatCompletionMessageParam array |
no test coverage detected