@5minds/node-red-dashboard-2-processcube-chat 0.1.1-add-functionality-483501-mdqg8xpt → 0.1.1-add-functionality-94845a-me8hect9
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.
|
@@ -147,7 +147,12 @@ export default {
|
|
|
147
147
|
const reader = new FileReader();
|
|
148
148
|
reader.onload = (e) => {
|
|
149
149
|
try {
|
|
150
|
-
const
|
|
150
|
+
const result = e.target.result;
|
|
151
|
+
const commaIndex = result.indexOf(',');
|
|
152
|
+
if (commaIndex === -1) {
|
|
153
|
+
throw new Error('Invalid data URL format: missing comma separator');
|
|
154
|
+
}
|
|
155
|
+
const base64Data = result.split(',')[1]; // Remove data URL prefix
|
|
151
156
|
|
|
152
157
|
resolve({
|
|
153
158
|
name: file.name,
|
|
@@ -187,55 +192,108 @@ export default {
|
|
|
187
192
|
},
|
|
188
193
|
|
|
189
194
|
formatForChatGPT(conversation, textOnly = false) {
|
|
190
|
-
|
|
191
|
-
messages: conversation.map((msg) =>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
role: msg.role === 'ai' ? 'assistant' : 'user',
|
|
195
|
-
content: msg.text,
|
|
196
|
-
};
|
|
197
|
-
} else if (msg.files && msg.files.length > 0) {
|
|
198
|
-
const content = [{ type: 'text', text: msg.text || '' }];
|
|
199
|
-
|
|
200
|
-
msg.files.forEach((file) => {
|
|
201
|
-
if (file.type && file.type.startsWith('image/') && file.src) {
|
|
202
|
-
content.push({
|
|
203
|
-
type: 'image_url',
|
|
204
|
-
image_url: { url: file.src },
|
|
205
|
-
});
|
|
206
|
-
} else if (!textOnly && file.type && file.type.startsWith('audio/') && file.base64Data) {
|
|
207
|
-
const format = this.getAudioFormat(file.type);
|
|
208
|
-
content.push({
|
|
209
|
-
type: 'input_audio',
|
|
210
|
-
input_audio: {
|
|
211
|
-
data: file.base64Data,
|
|
212
|
-
format: format,
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
} else if (!textOnly && file.fileData) {
|
|
216
|
-
content.push({
|
|
217
|
-
type: 'file',
|
|
218
|
-
file: {
|
|
219
|
-
filename: file.name,
|
|
220
|
-
file_data: file.fileData,
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
});
|
|
195
|
+
const payload = {
|
|
196
|
+
messages: conversation.map((msg) => this.formatMessage(msg, textOnly)),
|
|
197
|
+
model: this.props.model,
|
|
198
|
+
};
|
|
225
199
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
200
|
+
// Add ChatGPT API extensions
|
|
201
|
+
if (this.props.tools) {
|
|
202
|
+
payload.tools = this.props.tools;
|
|
203
|
+
}
|
|
231
204
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
205
|
+
if (this.props.tool_choice) {
|
|
206
|
+
payload.tool_choice = this.props.tool_choice;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (this.props.temperature !== undefined) {
|
|
210
|
+
payload.temperature = this.props.temperature;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (this.props.max_tokens) {
|
|
214
|
+
payload.max_tokens = this.props.max_tokens;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (this.props.top_p !== undefined) {
|
|
218
|
+
payload.top_p = this.props.top_p;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (this.props.frequency_penalty !== undefined) {
|
|
222
|
+
payload.frequency_penalty = this.props.frequency_penalty;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (this.props.presence_penalty !== undefined) {
|
|
226
|
+
payload.presence_penalty = this.props.presence_penalty;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (this.props.response_format) {
|
|
230
|
+
payload.response_format = this.props.response_format;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return payload;
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
formatMessage(msg, textOnly = false) {
|
|
237
|
+
const message = {
|
|
238
|
+
role: msg.role === 'ai' ? 'assistant' : 'user',
|
|
238
239
|
};
|
|
240
|
+
|
|
241
|
+
// Handle tool calls (for assistant messages)
|
|
242
|
+
if (msg.tool_calls) {
|
|
243
|
+
message.tool_calls = msg.tool_calls;
|
|
244
|
+
message.content = msg.content || null;
|
|
245
|
+
return message;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Handle tool responses (for tool messages)
|
|
249
|
+
if (msg.role === 'tool') {
|
|
250
|
+
message.role = 'tool';
|
|
251
|
+
message.content = msg.content;
|
|
252
|
+
message.tool_call_id = msg.tool_call_id;
|
|
253
|
+
return message;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Handle messages with files
|
|
257
|
+
if (msg.files && msg.files.length > 0) {
|
|
258
|
+
message.content = this.buildContentArray(msg, textOnly);
|
|
259
|
+
return message;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Handle text-only messages
|
|
263
|
+
message.content = msg.text || msg.content || '';
|
|
264
|
+
return message;
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
buildContentArray(msg, textOnly) {
|
|
268
|
+
const content = [{ type: 'text', text: msg.text || '' }];
|
|
269
|
+
|
|
270
|
+
msg.files.forEach((file) => {
|
|
271
|
+
if (file.type && file.type.startsWith('image/') && file.src) {
|
|
272
|
+
content.push({
|
|
273
|
+
type: 'image_url',
|
|
274
|
+
image_url: { url: file.src },
|
|
275
|
+
});
|
|
276
|
+
} else if (!textOnly && file.type && file.type.startsWith('audio/') && file.base64Data) {
|
|
277
|
+
const format = this.getAudioFormat(file.type);
|
|
278
|
+
content.push({
|
|
279
|
+
type: 'input_audio',
|
|
280
|
+
input_audio: {
|
|
281
|
+
data: file.base64Data,
|
|
282
|
+
format: format,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
} else if (!textOnly && file.fileData) {
|
|
286
|
+
content.push({
|
|
287
|
+
type: 'file',
|
|
288
|
+
file: {
|
|
289
|
+
filename: file.name,
|
|
290
|
+
file_data: file.fileData,
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
return content;
|
|
239
297
|
},
|
|
240
298
|
|
|
241
299
|
getAudioFormat(mimeType) {
|
|
@@ -256,16 +314,36 @@ export default {
|
|
|
256
314
|
|
|
257
315
|
handleNodeREDResponse(msg, signals) {
|
|
258
316
|
try {
|
|
317
|
+
// Store the complete ChatGPT response in conversation
|
|
318
|
+
const fullResponse = msg.payload;
|
|
319
|
+
|
|
320
|
+
// Create AI message with complete response data
|
|
259
321
|
const aiMessage = {
|
|
260
|
-
text: msg.payload.text || msg.payload.content,
|
|
261
322
|
role: 'ai',
|
|
323
|
+
content: fullResponse.message?.content || fullResponse.content,
|
|
324
|
+
text: fullResponse.message?.content || fullResponse.content,
|
|
325
|
+
fullResponse: fullResponse,
|
|
262
326
|
};
|
|
263
327
|
|
|
328
|
+
// Handle tool calls if present
|
|
329
|
+
if (fullResponse.message?.tool_calls) {
|
|
330
|
+
aiMessage.tool_calls = fullResponse.message.tool_calls;
|
|
331
|
+
aiMessage.content = fullResponse.message.content || null;
|
|
332
|
+
}
|
|
333
|
+
|
|
264
334
|
this.conversation.push(aiMessage);
|
|
265
335
|
|
|
266
|
-
|
|
336
|
+
// For the chat display, show appropriate response
|
|
337
|
+
if (fullResponse.message?.tool_calls) {
|
|
338
|
+
// If ChatGPT wants to call tools, show a message
|
|
339
|
+
signals.onResponse({
|
|
340
|
+
text: 'Function call requested...',
|
|
341
|
+
role: 'ai',
|
|
342
|
+
});
|
|
343
|
+
} else if (fullResponse.message?.content || fullResponse.content) {
|
|
344
|
+
// Normal text response
|
|
267
345
|
signals.onResponse({
|
|
268
|
-
text:
|
|
346
|
+
text: fullResponse.message?.content || fullResponse.content,
|
|
269
347
|
role: 'ai',
|
|
270
348
|
});
|
|
271
349
|
}
|