incognitolm commited on
Commit ·
cfae871
1
Parent(s): 6a9c39c
Update chatStream.js
Browse files- server/chatStream.js +35 -4
server/chatStream.js
CHANGED
|
@@ -123,17 +123,35 @@ export async function streamChat(ws, {
|
|
| 123 |
const client = makeClient(accessToken, clientId);
|
| 124 |
const enabledTools = buildToolList(tools);
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
const messages = [
|
| 127 |
{ role: "system", content: SYSTEM_PROMPT },
|
| 128 |
...history.map(normalizeMessage).filter(Boolean),
|
| 129 |
-
{ role: "user", content: userMessage },
|
| 130 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
// Validate messages before API call
|
| 133 |
for (let i = 0; i < messages.length; i++) {
|
| 134 |
const msg = messages[i];
|
| 135 |
if (msg.role !== "assistant" || !msg.tool_calls) {
|
| 136 |
-
if (typeof msg.content !== "string") {
|
| 137 |
console.error(`Message ${i} has invalid content:`, msg);
|
| 138 |
throw new Error(`Message ${i} missing or invalid content property`);
|
| 139 |
}
|
|
@@ -158,10 +176,17 @@ export async function streamChat(ws, {
|
|
| 158 |
const followUpMessages = [
|
| 159 |
{ role: "system", content: SYSTEM_PROMPT },
|
| 160 |
...history.map(normalizeMessage).filter(Boolean),
|
| 161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
{ role: "assistant", content: assistantText || "", tool_calls: toolCalls },
|
| 163 |
...toolResults,
|
| 164 |
-
|
| 165 |
|
| 166 |
const followUpStream = await client.chat.completions.create({
|
| 167 |
model: model || "lightning",
|
|
@@ -195,6 +220,12 @@ function normalizeMessage(msg) {
|
|
| 195 |
return { role: "assistant", content: "", tool_calls: msg.tool_calls };
|
| 196 |
}
|
| 197 |
if (Array.isArray(msg.content)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
const textOnly = msg.content
|
| 199 |
.filter(b => b.type === "text")
|
| 200 |
.map(b => b.text)
|
|
|
|
| 123 |
const client = makeClient(accessToken, clientId);
|
| 124 |
const enabledTools = buildToolList(tools);
|
| 125 |
|
| 126 |
+
// Normalize userMessage: convert array content to string or keep as-is for image support
|
| 127 |
+
let normalizedUserMessage = userMessage;
|
| 128 |
+
if (Array.isArray(userMessage)) {
|
| 129 |
+
// If it has images, keep the array format for OpenAI to process images
|
| 130 |
+
// Otherwise extract text
|
| 131 |
+
const hasImages = userMessage.some(item => item.type === 'image_url');
|
| 132 |
+
if (hasImages) {
|
| 133 |
+
normalizedUserMessage = userMessage;
|
| 134 |
+
} else {
|
| 135 |
+
normalizedUserMessage = userMessage.filter(b => b.type === "text").map(b => b.text).join("\n") || "";
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
// Build messages array: only include user message if it's provided
|
| 140 |
const messages = [
|
| 141 |
{ role: "system", content: SYSTEM_PROMPT },
|
| 142 |
...history.map(normalizeMessage).filter(Boolean),
|
|
|
|
| 143 |
];
|
| 144 |
+
|
| 145 |
+
// Add user message only if content was provided (not for edit-only requests)
|
| 146 |
+
if (userMessage !== undefined && userMessage !== null && userMessage !== '') {
|
| 147 |
+
messages.push({ role: "user", content: normalizedUserMessage });
|
| 148 |
+
}
|
| 149 |
|
| 150 |
// Validate messages before API call
|
| 151 |
for (let i = 0; i < messages.length; i++) {
|
| 152 |
const msg = messages[i];
|
| 153 |
if (msg.role !== "assistant" || !msg.tool_calls) {
|
| 154 |
+
if (typeof msg.content !== "string" && !Array.isArray(msg.content)) {
|
| 155 |
console.error(`Message ${i} has invalid content:`, msg);
|
| 156 |
throw new Error(`Message ${i} missing or invalid content property`);
|
| 157 |
}
|
|
|
|
| 176 |
const followUpMessages = [
|
| 177 |
{ role: "system", content: SYSTEM_PROMPT },
|
| 178 |
...history.map(normalizeMessage).filter(Boolean),
|
| 179 |
+
];
|
| 180 |
+
|
| 181 |
+
// Include user message in follow-up only if it was in the original request
|
| 182 |
+
if (userMessage !== undefined && userMessage !== null && userMessage !== '') {
|
| 183 |
+
followUpMessages.push({ role: "user", content: normalizedUserMessage });
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
followUpMessages.push(
|
| 187 |
{ role: "assistant", content: assistantText || "", tool_calls: toolCalls },
|
| 188 |
...toolResults,
|
| 189 |
+
);
|
| 190 |
|
| 191 |
const followUpStream = await client.chat.completions.create({
|
| 192 |
model: model || "lightning",
|
|
|
|
| 220 |
return { role: "assistant", content: "", tool_calls: msg.tool_calls };
|
| 221 |
}
|
| 222 |
if (Array.isArray(msg.content)) {
|
| 223 |
+
// If the array contains images, preserve the full array format
|
| 224 |
+
const hasImages = msg.content.some(item => item.type === 'image_url');
|
| 225 |
+
if (hasImages) {
|
| 226 |
+
return { role: msg.role, content: msg.content };
|
| 227 |
+
}
|
| 228 |
+
// Otherwise extract text only
|
| 229 |
const textOnly = msg.content
|
| 230 |
.filter(b => b.type === "text")
|
| 231 |
.map(b => b.text)
|