json-object-editor 0.10.625 → 0.10.633

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.
@@ -205,18 +205,13 @@ function ChatGPTAssistants() {
205
205
  resave = true;
206
206
  }
207
207
 
208
+ // Ensure we have a thread_id; create one if missing
208
209
  if (!convo.thread_id) {
209
210
  const thread = await openai.beta.threads.create();
210
211
  convo.thread_id = thread.id;
211
212
  resave = true;
212
- // await new Promise((resolve, reject) => {
213
- // JOE.Storage.save(convo, 'ai_conversation', function(err, saved) {
214
- // if (err) return reject(err);
215
- // resolve(saved);
216
- // });
217
- // });
218
213
  }
219
-
214
+
220
215
  if(resave){
221
216
  await new Promise((resolve, reject) => {
222
217
  JOE.Storage.save(convo, 'ai_conversation', function(err, saved) {
@@ -224,49 +219,89 @@ function ChatGPTAssistants() {
224
219
  resolve(saved);
225
220
  });
226
221
  });
222
+ }
227
223
 
224
+ /**
225
+ * Helper to start a run on the current thread for the correct assistant.
226
+ */
227
+ async function startRunForConversation(convo, data){
228
+ let runObj = null;
229
+ // Prefer assistants array if present
230
+ if (convo.assistants && convo.assistants.length > 0) {
231
+ const assistant_id = data.assistant_id || convo.assistants?.[0]?.openai_id || convo.assistants?.[0];
232
+ const assistant = JOE.Data.ai_assistant.find(a => a._id === assistant_id) || $J.get(assistant_id);
233
+ if (assistant && assistant.assistant_id) {
234
+ runObj = await openai.beta.threads.runs.create(convo.thread_id, {
235
+ assistant_id: assistant.assistant_id
236
+ });
237
+ coloredLog(`Assistant run started: ${runObj.id}`);
238
+ }
239
+ } else if (convo.assistant) {
240
+ const assistant = $J.get(convo.assistant);
241
+ if (assistant && assistant.assistant_id) {
242
+ runObj = await openai.beta.threads.runs.create(convo.thread_id, {
243
+ assistant_id: assistant.assistant_id
244
+ });
245
+ coloredLog(`Assistant run started: ${runObj.id}`);
246
+ }
247
+ }
248
+ return runObj;
228
249
  }
229
250
 
230
- await openai.beta.threads.messages.create(convo.thread_id, {
231
- role: "user",
232
- content: content
233
- });
234
- var runObj = null;
235
- // NOW ➔ trigger assistant reply if assistant is selected
236
- if (convo.assistants && convo.assistants.length > 0) {
237
- // const assistant_id = convo.assistants[0]; // Assuming you store OpenAI assistant ID here
238
- //get assistant object by id
239
- const assistant_id = data.assistant_id || convo.assistants?.[0]?.openai_id;
240
- const assistant = JOE.Data.ai_assistant.find(a => a._id === assistant_id);
241
- if (assistant.assistant_id) {
242
- runObj = await openai.beta.threads.runs.create(convo.thread_id, {
243
- assistant_id: assistant.assistant_id
251
+ let runObj = null;
252
+ try {
253
+ // Normal path: append user message to existing thread
254
+ await openai.beta.threads.messages.create(convo.thread_id, {
255
+ role: "user",
256
+ content: content
257
+ });
258
+ runObj = await startRunForConversation(convo, data);
259
+ } catch (err) {
260
+ // If a previous run is still active on this thread, OpenAI returns 400:
261
+ // "Can't add messages to <thread> while a run <run_x> is active."
262
+ const msg = err && err.message ? String(err.message) : '';
263
+ if (err && err.status === 400 && msg.indexOf("Can't add messages to") !== -1 && msg.indexOf("while a run") !== -1) {
264
+ coloredLog("⚠️ Active run detected for conversation " + convo._id + " on thread " + convo.thread_id);
265
+ return({
266
+ error: "active_run",
267
+ message: "This conversation has an active assistant run on its thread. Please wait for it to complete or start a new conversation.",
268
+ thread_id: convo.thread_id
244
269
  });
245
-
246
- console.log(`Assistant run started: ${runObj.id}`);
247
- // You could optionally poll for completion here
248
270
  }
249
- }else if(convo.assistant){
250
- const assistant = $J.get(convo.assistant);
251
- runObj = await openai.beta.threads.runs.create(convo.thread_id, {
252
- assistant_id: assistant.assistant_id // Assuming you store OpenAI assistant ID here
253
- });
254
-
255
- coloredLog(`Assistant run started: ${runObj.id}`);
271
+ // Unknown error – rethrow to outer catch
272
+ throw err;
256
273
  }
257
- return({ success: true,runObj });
274
+
275
+ return({
276
+ success: true,
277
+ runObj,
278
+ run_id: runObj && runObj.id,
279
+ thread_id: convo.thread_id
280
+ });
258
281
  } catch (err) {
259
282
  console.error('❌ addMessage error:', err);
260
- return({ error: "Failed to send message.", message: err.message });
283
+ const msg = err && err.message ? String(err.message) : 'Unknown error';
284
+ return({ error: "Failed to send message.", message: msg });
261
285
  }
262
286
  };
263
287
  this.getRunStatus = async function(data, req, res) {
264
288
  try {
289
+ // Debug: log raw data coming into getRunStatus to diagnose bad IDs
290
+ try {
291
+ coloredLog("🔍 getRunStatus called with data:", JSON.stringify(data));
292
+ } catch(_e) {
293
+ console.log("[chatgpt-assistants] getRunStatus data (fallback log):", data);
294
+ }
295
+
265
296
  const run_id = data.run_id;
266
297
  const thread_id = data.thread_id;
267
298
  var errors = [];
268
- if (!run_id) errors.push("Missing run ID.");
269
- if(!thread_id) errors.push("Missing thread ID.");
299
+ if (!run_id || run_id === 'undefined' || run_id === 'null') {
300
+ errors.push("Missing run ID.");
301
+ }
302
+ if (!thread_id || thread_id === 'undefined' || thread_id === 'null') {
303
+ errors.push("Missing thread ID.");
304
+ }
270
305
 
271
306
  if (errors.length) {
272
307
  return { error: errors.join(" ") };