Skip to content

Commit 8ff0720

Browse files
CopilotGodzilla675
andauthored
Fix AI functions: proper OpenAI message formatting and build pipeline
Agent-Logs-Url: https://github.com/Godzilla675/clip-js-copilot/sessions/1bbe9aa4-7b2c-4a2c-ad8c-e0c90b0ba5a5 Co-authored-by: Godzilla675 <131464726+Godzilla675@users.noreply.github.com>
1 parent c547321 commit 8ff0720

3 files changed

Lines changed: 49 additions & 8 deletions

File tree

apps/backend/src/llm/providers/openai.ts

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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,

packages/shared-types/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"types": "./dist/index.d.ts",
66
"scripts": {
77
"build": "tsc",
8+
"dev": "tsc --watch",
89
"type-check": "tsc --noEmit"
910
},
1011
"devDependencies": {

turbo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
},
88
"lint": {},
99
"dev": {
10+
"dependsOn": ["^build"],
1011
"cache": false,
1112
"persistent": true
1213
}

0 commit comments

Comments
 (0)