@miphamai/cli 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/engine.ts +1 -0
- package/src/providers/openai-compat.ts +85 -15
package/package.json
CHANGED
package/src/core/engine.ts
CHANGED
|
@@ -150,30 +150,100 @@ export class OpenAICompatProvider implements ProviderInstance {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
private convertMessages(
|
|
154
|
-
|
|
155
|
-
systemPrompt?: string,
|
|
156
|
-
): { role: string; content: string | unknown[] }[] {
|
|
157
|
-
const result: { role: string; content: string | unknown[] }[] = []
|
|
153
|
+
private convertMessages(messages: Message[], systemPrompt?: string): Record<string, unknown>[] {
|
|
154
|
+
const result: Record<string, unknown>[] = []
|
|
158
155
|
|
|
159
156
|
if (systemPrompt) {
|
|
160
157
|
result.push({ role: 'system', content: systemPrompt })
|
|
161
158
|
}
|
|
162
159
|
|
|
163
|
-
for (
|
|
160
|
+
for (let i = 0; i < messages.length; i++) {
|
|
161
|
+
const msg = messages[i]!
|
|
162
|
+
if (!msg) continue
|
|
163
|
+
|
|
164
|
+
// ── String content ──
|
|
164
165
|
if (typeof msg.content === 'string') {
|
|
166
|
+
// Combine: assistant text + next assistant message with tool_use blocks
|
|
167
|
+
const next: Message | undefined = messages[i + 1]
|
|
168
|
+
if (
|
|
169
|
+
msg.role === 'assistant' &&
|
|
170
|
+
msg.content.length > 0 &&
|
|
171
|
+
next &&
|
|
172
|
+
next.role === 'assistant' &&
|
|
173
|
+
typeof next.content !== 'string' &&
|
|
174
|
+
next.content.some((b) => b.type === 'tool_use')
|
|
175
|
+
) {
|
|
176
|
+
const toolUses = next.content.filter((b) => b.type === 'tool_use')
|
|
177
|
+
result.push({
|
|
178
|
+
role: 'assistant',
|
|
179
|
+
content: msg.content,
|
|
180
|
+
tool_calls: toolUses.map((tu) => ({
|
|
181
|
+
id: tu.id,
|
|
182
|
+
type: 'function',
|
|
183
|
+
function: {
|
|
184
|
+
name: tu.name,
|
|
185
|
+
arguments: JSON.stringify(tu.input),
|
|
186
|
+
},
|
|
187
|
+
})),
|
|
188
|
+
})
|
|
189
|
+
i++ // skip the next message (consumed)
|
|
190
|
+
continue
|
|
191
|
+
}
|
|
192
|
+
|
|
165
193
|
result.push({ role: msg.role, content: msg.content })
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ── ContentBlock[] ──
|
|
198
|
+
const blocks = msg.content
|
|
199
|
+
const toolUses = blocks.filter((b) => b.type === 'tool_use')
|
|
200
|
+
const toolResults = blocks.filter((b) => b.type === 'tool_result')
|
|
201
|
+
|
|
202
|
+
// ── Assistant tool_use → OpenAI tool_calls ──
|
|
203
|
+
if (toolUses.length > 0 && msg.role === 'assistant') {
|
|
204
|
+
const textContent =
|
|
205
|
+
blocks
|
|
206
|
+
.filter((b) => b.type === 'text')
|
|
207
|
+
.map((b) => (b.type === 'text' ? b.text : ''))
|
|
208
|
+
.join('') || null
|
|
209
|
+
|
|
210
|
+
result.push({
|
|
211
|
+
role: 'assistant',
|
|
212
|
+
content: textContent,
|
|
213
|
+
tool_calls: toolUses.map((tu) => ({
|
|
214
|
+
id: tu.id,
|
|
215
|
+
type: 'function',
|
|
216
|
+
function: {
|
|
217
|
+
name: tu.name,
|
|
218
|
+
arguments: JSON.stringify(tu.input),
|
|
219
|
+
},
|
|
220
|
+
})),
|
|
221
|
+
})
|
|
222
|
+
continue
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── Tool result → OpenAI tool role ──
|
|
226
|
+
if (toolResults.length > 0) {
|
|
227
|
+
for (const tr of toolResults) {
|
|
228
|
+
result.push({
|
|
229
|
+
role: 'tool',
|
|
230
|
+
tool_call_id: tr.tool_use_id,
|
|
231
|
+
content: tr.content,
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
continue
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ── Regular content blocks (text, image) ──
|
|
238
|
+
const parts: unknown[] = []
|
|
239
|
+
for (const block of blocks) {
|
|
240
|
+
if (block.type === 'text') {
|
|
241
|
+
parts.push({ type: 'text', text: block.text })
|
|
242
|
+
} else if (block.type === 'image_url') {
|
|
243
|
+
parts.push({ type: 'image_url', image_url: block.image_url })
|
|
174
244
|
}
|
|
175
|
-
result.push({ role: msg.role, content: parts })
|
|
176
245
|
}
|
|
246
|
+
result.push({ role: msg.role, content: parts })
|
|
177
247
|
}
|
|
178
248
|
|
|
179
249
|
return result
|