@xuda.io/ai_module 1.1.5617 → 1.1.5618

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/un-used.mjs ADDED
@@ -0,0 +1,1437 @@
1
+ // const add_data_to_table_tool = tool({
2
+ // name: 'Add data to table tool',
3
+ // description: 'Add data to a table by receiving a table_id and a data object containing key–value pairs representing the fields and their values.',
4
+ // parameters: z.object({
5
+ // table_id: z.string(),
6
+ // }),
7
+ // async execute(e, RunContext) {
8
+ // const { table_id } = e;
9
+ // const { app_id, uid } = RunContext.context;
10
+
11
+ // if (!table_id) throw new Error('got null in the table_id parameter');
12
+
13
+ // try {
14
+ // const project_db = await get_project_db(app_id);
15
+
16
+ // let response = '';
17
+
18
+ // try {
19
+ // response = await project_db.get(table_id);
20
+ // } catch (error) {
21
+ // throw new Error(`table doc ${table_id} not found`);
22
+ // }
23
+
24
+ // if (_.isEmpty(response)) {
25
+ // throw new Error(`table with table_id ${table_id} not found`);
26
+ // }
27
+
28
+ // return response;
29
+ // } catch (err) {
30
+ // return err.message;
31
+ // }
32
+ // },
33
+ // });
34
+
35
+ // let table_tools = {};
36
+ // const build_studio_table_tools = async function (app_id) {
37
+ // try {
38
+ // if (!table_tools[app_id]) {
39
+ // table_tools[app_id] = {};
40
+ // }
41
+
42
+ // const project_db = await get_project_db(app_id);
43
+ // let tables = await project_db.view('xuda', 'studio_docs_by_type', { key: 'table' });
44
+
45
+ // for (const table_header_doc of tables.rows) {
46
+ // try {
47
+ // const doc = await project_db.get(table_header_doc.id);
48
+
49
+ // let data_parameters = {};
50
+
51
+ // for (const field of doc.tableFields || []) {
52
+ // const fieldId = field.data.field_id;
53
+ // const fieldType = field.props.fieldType;
54
+ // const mandatory = field.props.mandatory;
55
+ // const comment = field.props.fieldComment;
56
+
57
+ // let zodType;
58
+ // switch (fieldType) {
59
+ // case 'string':
60
+ // zodType = z.string();
61
+ // break;
62
+ // case 'number':
63
+ // zodType = z.number();
64
+ // break;
65
+ // case 'array':
66
+ // zodType = z.array(z.any());
67
+ // break;
68
+ // case 'object':
69
+ // zodType = z.object({});
70
+ // break;
71
+ // default:
72
+ // zodType = z.any();
73
+ // }
74
+
75
+ // // Add description if comment exists
76
+ // if (comment) {
77
+ // zodType = zodType.describe(comment);
78
+ // }
79
+
80
+ // // Make optional if not mandatory
81
+ // if (!mandatory) {
82
+ // zodType = zodType.optional();
83
+ // }
84
+
85
+ // data_parameters[fieldId] = zodType;
86
+ // }
87
+
88
+ // const _tool = {
89
+ // name: `add data to table tool`,
90
+ // description: `Add data to ${doc.properties.menuName} table by receiving key–value pairs representing the fields and their values.`,
91
+ // parameters: z.object(data_parameters),
92
+ // // parameters: z.object({ ...{ table_id: z.string() }, ...data_parameters }),
93
+ // // parameters: z.object({
94
+ // // table_id: z.string(),
95
+ // // data: z.object(data_parameters),
96
+ // // }),
97
+ // async execute(e, RunContext) {
98
+ // debugger;
99
+ // const {} = e;
100
+ // const { app_id, uid, table_id } = RunContext.context;
101
+ // let response = '';
102
+ // try {
103
+ // if (!table_id) throw new Error('got null in the table_id parameter');
104
+
105
+ // const FlexibleDatabaseSchema = z.object({
106
+ // _id: z.string(),
107
+ // _rev: z.string(),
108
+ // docType: z.literal('database'),
109
+ // stat: z.number(),
110
+ // udfData: z.object({
111
+ // udffileid: z.string(),
112
+ // data: z.record(z.union([z.string(), z.number()])), // Any key-value pairs
113
+ // error: z.object({}).optional(),
114
+ // }),
115
+ // ts: z.number(),
116
+ // date: z.number(),
117
+ // udfIndex: z.array(
118
+ // z.object({
119
+ // fileId: z.string(),
120
+ // indexId: z.string(),
121
+ // keySegments: z.array(z.any()),
122
+ // keyValue: z.array(z.any()),
123
+ // }),
124
+ // ),
125
+ // });
126
+
127
+ // // for (const [key, val] of Object.entities(data || {})) {
128
+ // // }
129
+
130
+ // let udfIndex = [];
131
+
132
+ // for (const [key, val] of Object.entities(doc.tableIndexes || [])) {
133
+ // let keyValue = [];
134
+ // for (const key_val of val?.data?.keys || []) {
135
+ // keyValue.push(data[key_val]);
136
+ // }
137
+
138
+ // udfIndex.push({
139
+ // fileId: table_id,
140
+ // indexId: val.id,
141
+ // keySegments: val?.data?.keys || [],
142
+ // keyValue,
143
+ // });
144
+ // }
145
+ // const t = Date.now();
146
+ // let table_obj = {
147
+ // _id: 'dbs-' + crypto.randomUUID(),
148
+
149
+ // docType: 'database',
150
+ // stat: 3,
151
+ // udfData: {
152
+ // udffileid: table_id,
153
+ // data: e,
154
+ // error: {},
155
+ // },
156
+ // ts: t,
157
+ // date: t,
158
+ // udfIndex,
159
+ // };
160
+
161
+ // return response;
162
+ // } catch (err) {
163
+ // return err.message;
164
+ // }
165
+ // },
166
+ // };
167
+
168
+ // // const jsonSchema = zodToJsonSchema(_tool.parameters, 'UserSchema');
169
+
170
+ // // console.log(JSON.stringify(jsonSchema, null, 2));
171
+
172
+ // table_tools[app_id][doc._id] = tool(_tool);
173
+ // } catch (error) {
174
+ // throw new Error(`table doc ${doc.id} not found`);
175
+ // }
176
+ // }
177
+ // // console.log(studio_units);
178
+ // } catch (err) {
179
+ // console.error(err);
180
+ // }
181
+
182
+ // return table_tools[app_id];
183
+ // };
184
+
185
+ const get_mock_data_generator_agent = function (app_id, table_id) {
186
+ return new Agent({
187
+ name: `Mock Data Generator Agent`,
188
+ instructions: `You are a Mock Data Generator Assistant for table id ${table_id}. Help the user populate data for table id ${table_id} with sample data. First, retrieve the table field definitions using get_studio_table_info_by_table_id_tool. Then generate five realistic mock data samples based on the table structure and insert each one individually using add data to table tool.`,
189
+ // instructions: `You are a Mock Data Generator Assistant.
190
+ // 1. First, get table info using the get_studio_table_info_by_table_id tool with table_id: ${table_id}
191
+ // 2. Analyze the table structure and field types
192
+ // 3. Generate 5 realistic mock data samples based on the fields
193
+ // 4. Return the generated data in a structured format`,
194
+ model,
195
+ tools: [get_studio_table_info_by_table_id_tool, table_tools[app_id][table_id]], //, table_tools[app_id][table_id]
196
+ // modelSettings: { toolChoice: 'required' },
197
+ });
198
+ };
199
+
200
+ // const get_add_data_to_table_agent = function (app_id, table_id) {
201
+ // return new Agent({
202
+ // name: `Add Data to Table Agent`,
203
+ // instructions: `You are an Add Data Assistant for table ID ${table_id}. Your job is to help the user provide valid data for this table. First, retrieve the table field definitions using get_studio_table_info_by_table_id_tool. Then prepare the data as key–value pairs (e.g., { first_name: "John", last_name: "Smith" }) and submit it using the add_data_to_table_tool. Generate UUID values for required unique fields when necessary. Ignore extra fields from the user prompt, and skip optional fields if not provided.`,
204
+ // model,
205
+ // tools: [get_studio_table_info_by_table_id_tool, table_tools[app_id][table_id]],
206
+ // modelSettings: { toolChoice: 'required' },
207
+ // });
208
+ // };
209
+
210
+ // const add_data_to_table = tool({
211
+ // name: 'Create table agent',
212
+ // description: 'crete agent that handles table tools by providing table_id',
213
+ // parameters: z.object({
214
+ // table_id: z.string(),
215
+ // }),
216
+ // async execute(e, RunContext) {
217
+ // const { table_id } = e;
218
+ // const { app_id, uid } = RunContext.context;
219
+ // let response = '';
220
+ // try {
221
+ // if (!table_id) throw new Error('got null in the table_id parameter');
222
+ // let table_doc = {};
223
+ // const project_db = await get_project_db(app_id);
224
+ // try {
225
+ // table_doc = await project_db.get(table_id);
226
+ // } catch (error) {
227
+ // throw new Error(`table doc ${table_id} not found`);
228
+ // }
229
+
230
+ // const agent_name = `${table_doc.properties.menuName} table AI Agent`;
231
+
232
+ // try {
233
+ // const ai_agents_ret = await get_ai_agents({ uid });
234
+ // for (const doc of ai_agents_ret?.data?.docs || []) {
235
+ // if (doc.properties.menuName === table_doc.properties.menuName) {
236
+ // throw new Error(`ai agent for ${table_id} already exist with name ${agent_name}`);
237
+ // }
238
+ // }
239
+ // } catch (err) {
240
+ // debugger;
241
+ // console.error(err);
242
+ // // throw new Error(err.message);
243
+ // }
244
+
245
+ // const agentConfig = {
246
+ // agent_name,
247
+ // agent_tools: [
248
+ // {
249
+ // type: 'table',
250
+ // prog_id: table_id,
251
+ // },
252
+ // ],
253
+ // agent_instructions: 'You are a Table Data Assistant. Your role is to query, analyze, and modify data within tables as requested. You can retrieve specific information, perform calculations, filter or sort records, and apply updates or structural changes to the data when necessary.',
254
+ // };
255
+
256
+ // response = await create_ai_agent({
257
+ // uid,
258
+ // agentConfig,
259
+ // });
260
+
261
+ // return { response, agentConfig };
262
+ // } catch (err) {
263
+ // return err.message;
264
+ // }
265
+ // },
266
+ // });
267
+
268
+ // const get_studio_tables = tool({
269
+ // name: 'Get studio tables',
270
+ // description: 'fetch all studio tables',
271
+ // parameters: z.object({
272
+ // app_id: z.string(),
273
+ // }),
274
+ // async execute(e, RunContext) {
275
+ // const { app_id } = e;
276
+ // try {
277
+ // const project_db = await get_project_db(app_id);
278
+ // let tables = await project_db.view('xuda', 'studio_docs_by_type', { key: 'table', include_docs: true });
279
+
280
+ // return tables;
281
+ // } catch (err) {
282
+ // return 'unknown';
283
+ // }
284
+ // },
285
+ // });
286
+
287
+ const get_plugins = tool({
288
+ name: 'Get plugins',
289
+ description: 'I am responsible to return all available plugins',
290
+ parameters: z.object({}),
291
+ async execute(e, RunContext) {
292
+ try {
293
+ const db = get_xuda_couch('xuda_plugins');
294
+ const plugins_res = await db.view('xuda', 'all-active-plugins', {});
295
+ let data = [];
296
+ if (!_.isEmpty(plugins_res.rows)) {
297
+ for (val of plugins_res.rows) {
298
+ if (!['library', 'widget', 'ui'].includes(val.plugin_type)) continue;
299
+ var plugin = _.clone(val.value);
300
+ delete plugin.account_id;
301
+ delete plugin.manifest;
302
+ delete plugin.plugin_name;
303
+ delete plugin.setup;
304
+ delete plugin.stat;
305
+ delete plugin.updated_date;
306
+ plugin._id = plugin._id.replace('@xuda.io/', '');
307
+
308
+ data.push(plugin);
309
+ }
310
+ }
311
+
312
+ console.log('get_plugins >>>> ', data);
313
+ return data;
314
+ } catch (err) {
315
+ console.error(err);
316
+ return err.message;
317
+ }
318
+ },
319
+ });
320
+
321
+ const update_app_doc_tool = tool({
322
+ name: 'update app doc tool',
323
+ description: 'update any app doc query by _id and _rev and save to the app db',
324
+ parameters: z.object({
325
+ app_id: z.string(),
326
+ doc: z.object({ _id: z.string(), _rev: z.string() }),
327
+ }),
328
+ async execute(e, RunContext) {
329
+ console.log(`SAVED ${e.app_id}`);
330
+ return `OK`;
331
+ },
332
+ });
333
+
334
+ const get_app_doc_tool = tool({
335
+ name: 'get app doc tool',
336
+ description: 'get any doc by id from the app db',
337
+ parameters: z.object({
338
+ app_id: z.string(),
339
+ _id: z.string(),
340
+ }),
341
+ async execute(e, RunContext) {
342
+ try {
343
+ const project_db = await get_project_db(e.app_id);
344
+
345
+ const result = await project_db.get(_id);
346
+ console.log('get_app_doc_tool >>>> ', result);
347
+ return result;
348
+ } catch (err) {
349
+ console.error(err);
350
+ return err.message;
351
+ }
352
+ },
353
+ });
354
+
355
+ const get_additional_information_tool = tool({
356
+ name: 'get additional information tool',
357
+ description: 'get additional information for object unit tool',
358
+ parameters: z.object({
359
+ object_unit: z.enum(['table']),
360
+ }),
361
+ async execute(e, RunContext) {
362
+ let obj = { table: ['studio_table'] };
363
+ const db = get_xuda_couch('xuda_website');
364
+ try {
365
+ if (!obj[e.object_unit]) throw new Error(`${e.object_unit} not found`);
366
+ const doc = await db.get(obj[e.object_unit]);
367
+ // console.log(`INFO ${doc}`);
368
+ return doc.md || doc;
369
+ } catch (err) {
370
+ console.error(err);
371
+ return err.message;
372
+ }
373
+ },
374
+ });
375
+
376
+ async function fineTuneWithMultipleFiles(datasetPaths, baseModel = 'gpt-4o-mini') {
377
+ try {
378
+ console.log('📤 Uploading datasets...');
379
+
380
+ // Step 1. Upload all JSONL files in parallel
381
+ const uploadedFiles = await Promise.all(
382
+ datasetPaths.map(async (filePath) => {
383
+ const file = await openai.files.create({
384
+ file: fs.createReadStream(path.resolve(filePath)),
385
+ purpose: 'fine-tune',
386
+ });
387
+ console.log(`✅ Uploaded: ${file.filename} → ID: ${file.id}`);
388
+ return file.id;
389
+ }),
390
+ );
391
+
392
+ // Step 2. Create fine-tuning job with multiple training files
393
+ console.log(`🚀 Creating fine-tuning job for ${baseModel}...`);
394
+ const fineTuneJob = await openai.fineTuning.jobs.create({
395
+ training_files: uploadedFiles.map((id) => ({ file_id: id })), // <-- multiple files here
396
+ model: baseModel,
397
+ });
398
+
399
+ console.log(`📌 Fine-tuning job created: ${fineTuneJob.id}`);
400
+
401
+ // Step 3. Poll job status until training completes
402
+ let status = fineTuneJob.status;
403
+ while (status === 'pending' || status === 'running') {
404
+ console.log(`⏳ Job status: ${status}...`);
405
+ await new Promise((resolve) => setTimeout(resolve, 10000));
406
+
407
+ const updatedJob = await openai.fineTuning.jobs.retrieve(fineTuneJob.id);
408
+ status = updatedJob.status;
409
+ }
410
+
411
+ // Step 4. Check final status
412
+ if (status === 'succeeded') {
413
+ console.log('🎉 Fine-tuning completed successfully!');
414
+ console.log(`🆕 Fine-tuned model: ${fineTuneJob.fine_tuned_model}`);
415
+ return fineTuneJob.fine_tuned_model;
416
+ } else {
417
+ throw new Error(`❌ Fine-tuning failed: ${status}`);
418
+ }
419
+ } catch (error) {
420
+ console.error('⚠️ Fine-tuning error:', error);
421
+ throw error;
422
+ }
423
+ }
424
+
425
+ const upload_file_to_openai_storage = async function (file_path) {
426
+ try {
427
+ const stream = await get_drive_file_stream(file_path);
428
+
429
+ const uploadedFile = await client.files.create({
430
+ file: stream,
431
+ purpose: 'assistants',
432
+ });
433
+
434
+ console.log('📂 Uploaded file:', uploadedFile.id);
435
+ unlink(tmp_file);
436
+ return uploadedFile.id;
437
+ } catch (err) {
438
+ console.error(err);
439
+ }
440
+ };
441
+
442
+ const get_account_object = async function (uid) {
443
+ const db = get_xuda_couch('xuda_accounts');
444
+ const account_obj = await db.get(uid);
445
+ return account_obj;
446
+ };
447
+
448
+ const get_account_project_id = async function (uid) {
449
+ const account_obj = await account_module.get_account_default_project_obj(uid);
450
+ return account_obj.account_project_id;
451
+ };
452
+
453
+ const getExtension = function (filename) {
454
+ return path.extname(filename).toLowerCase();
455
+ };
456
+
457
+ setTimeout(async () => {
458
+ const app_id = 'prj712ffdf5aa8adce6cedef988f9c12392'; //'prj3937cb6f9a31c8c7dea25055bba845b1'; //
459
+ const uid = 'd39126e0e2c51ffbd1aad10709fc8335';
460
+
461
+ // await init_studio_units();
462
+ let ret;
463
+ // await build_studio_table_tools(app_id);
464
+ // testTool(app_id, uid);
465
+ // ret = await download_yt_audio('https://www.youtube.com/watch?v=uSt5yLOWiNo');
466
+ // ret = await update_ai_agent({
467
+ // uid: 'd39126e0e2c51ffbd1aad10709fc8335',
468
+ // agent_id: '392_agn_ddbca7c25455',
469
+ // agentConfig: {
470
+ // agent_instructions: 'use app builder to build tables and programs',
471
+ // agent_tools: [
472
+ // {
473
+ // type: 'app_builder',
474
+ // name: 'app_builder',
475
+ // },
476
+ // ],
477
+ // agent_name: 'Xuda App Builder',
478
+ // },
479
+ // });
480
+ // ret = await client.vectorStores.files.create(_conf.OPENAI_VECTOR_STORE_ID, {
481
+ // file_id: 'file-Rf9UzT1f7NVhTELypnbsBU',
482
+ // });
483
+ // ret = upload_file_to_openai_storage('/docxsite-bp.xlsx.pdf');
484
+ // ret = await transcribe('/AAA.mp3');
485
+ // ret = await transcribe('/B.mp4');
486
+ // ret = await upload_file_to_openai_storage('/AAA.mp3');
487
+ // ret = await create_image("'Generate an image of gray tabby cat hugging an otter with an orange scarf'");
488
+ // ret = await submit_chat_conversation({ uid, prompt: 'use xuda.io agent to require info about xuda.io', ai_agents: [] });
489
+ // ret = await submit_chat_conversation({ prompt: 'what is my name', conversation_id: ret.data.conversation_doc._id });
490
+ // const ret = await create_studio_app('crm');
491
+ // ret = await submit_chat_gpt_prompt({
492
+ // prompt: `Use the formatting rules from the Xuda fine-tuned model.
493
+ // Generate a new Table Object JSON with the same schema learned in training.
494
+ // Don't modify _rev. Preserve screenshots array structure.`,
495
+ // model: 'ft:gpt-4o-2024-08-06:xuda-io:xuda-table:CdYWfx0l', //'ft:gpt-4.1-nano-2025-04-14:xuda-io:xuda-table:CdXWxgir'
496
+ // });
497
+ // const ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'crm app', object_unit: 'app', uid, app_id });
498
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'products', object_unit: 'table', uid, app_id });
499
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'test3', object_unit: 'folder', uid, app_id });
500
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'contact contact form', object_unit: 'component', uid, app_id });
501
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'get data from tasks by task id', object_unit: 'get_data', uid, app_id });
502
+
503
+ // ret = await test_plugin(app_id, uid, '@xuda.io/xuda-library-plugin-studio-ai-app-builder', 'table_builder', { prompt: 'build items table', save: true, parentId: 'programs' });
504
+ // ret = await test_plugin(app_id, uid, '@xuda.io/xuda-library-plugin-studio-ai-app-builder', 'folder_builder', { prompt: 'build boaz folder', save: true, parentId: 'programs' });
505
+
506
+ console.log(ret);
507
+
508
+ // init({}, {}, _, true, null, null, UglifyJS, JSON5, _conf, false, z);
509
+ // const schema = get_zod_schema('component');
510
+
511
+ // const db = get_xuda_couch('xuda_master');
512
+ // const app_obj = await db.get(app_id);
513
+ // const project_db = get_xuda_couch(app_obj.app_db_name);
514
+ // const doc = await project_db.get('5b1_cmp_313d53e56c2d');
515
+
516
+ ////////////////////
517
+ // let err_ret = [];
518
+ // const addValidationError = (code, data) => {
519
+ // err_ret.push({
520
+ // code,
521
+ // data,
522
+ // type: 'E',
523
+ // category: 'document',
524
+ // structure_error: true,
525
+ // });
526
+ // };
527
+ //////////////////
528
+
529
+ // const result = schema.safeParse({});
530
+ // if (!result.success) {
531
+ // console.log(result.error.errors); // Array of error objects
532
+ // result.error.errors.forEach((error) => {
533
+ // // console.log(`Path: ${error.path}, Message: ${error.message}`);
534
+ // const msg = `${error.message}: ${error.path}(${error.expected})`;
535
+ // addValidationError('CHK_MSG_OBJ_GEN_000', msg);
536
+ // });
537
+ // console.log(err_ret);
538
+ // } else {
539
+ // console.log('Validation succeeded:', result.data);
540
+ // }
541
+
542
+ // const jsonSchema = zodToJsonSchema(schema);
543
+ // // console.log(jsonSchema);
544
+ // console.log(JSON.stringify(jsonSchema, null, 2));
545
+
546
+ // console.log(
547
+ // check(
548
+ // createDoc({
549
+ // uid: '11',
550
+ // app_id: 'prj-444',
551
+ // menuType: 'folder',
552
+ // checkedInUserName: 'boaz',
553
+ // parentId: '',
554
+ // }),
555
+ // ),
556
+ // );
557
+
558
+ // const vectorStore = await client.beta.vector_stores.create({
559
+ // name: 'Xuda Docs Vector Store',
560
+ // });
561
+ // console.log('Vector Store ID:', vectorStore.id);
562
+ // console.log('OpenAI version:', (await import('openai/package.json')).version);
563
+ // console.log('has beta?', !!client.beta);
564
+ // console.log('has vector_stores?', !!client.beta?.vector_stores);
565
+ // console.log('keys on vector_stores:', Object.keys(client.beta?.vector_stores || {}));
566
+
567
+ // const vectorStore = await client.vectorStores.create({
568
+ // name: 'Xuda Docs Vector Store',
569
+ // });
570
+ // console.log(vectorStore);
571
+ }, 1000);
572
+
573
+ async function testTool(app_id, uid) {
574
+ console.log('Testing tool with:', { app_id, uid, table_id: '392_tbl_47f0ac6059ca' });
575
+
576
+ try {
577
+ const input = { table_id: '392_tbl_47f0ac6059ca' };
578
+ const runContext = { context: { app_id, uid } };
579
+ const details = {};
580
+
581
+ console.log('Input:', JSON.stringify(input, null, 2));
582
+ console.log('RunContext:', JSON.stringify(runContext, null, 2));
583
+ debugger;
584
+ // CORRECT ORDER: input first, then runContext
585
+ const result = await get_studio_table_info_by_table_id_tool.invoke(
586
+ runContext, // 1st: context
587
+ input, // 2nd: parameters
588
+ details, // 3rd: optional
589
+ );
590
+
591
+ console.log('Tool test successful:', result);
592
+ return result;
593
+ } catch (error) {
594
+ console.error('Tool test failed:');
595
+ console.error('Error:', error.message);
596
+ throw error;
597
+ }
598
+ }
599
+
600
+ // export const submit_chat_conversation = async function (req, job_id, headers) {
601
+ // const { uid, gtp_token } = req;
602
+ // let { prompt, conversation_id, reference_type, reference_id, attachments = [], ai_agents, output_format = 'md', stream = true, with_context = true } = req;
603
+
604
+ // const app_id = await account_module.get_account_default_project_id(uid);
605
+ // const app_obj = await get_app_obj(app_id);
606
+ // const userName = await account_module.get_user_name(uid);
607
+ // const account_info = (await account_module.get_account_name({ uid })).data;
608
+ // let context = { ...{ app_id, uid, userName, account_info, app_obj, account_id: uid }, ...extractClientInfo(headers) };
609
+ // const d = new Intl.DateTimeFormat('en-US').format(new Date());
610
+ // if (!visitors[d]) {
611
+ // visitors[d] = {};
612
+ // }
613
+
614
+ // let conversation_doc = {
615
+ // docType: 'chat_conversation',
616
+ // title: prompt.substr(0, 40),
617
+ // date_created_ts: Date.now(),
618
+ // ts: Date.now(),
619
+ // stat: 3,
620
+ // uid,
621
+ // messages: [],
622
+ // reference_type,
623
+ // reference_id,
624
+ // };
625
+
626
+ // //////////////////////
627
+
628
+ // const emitToDashboard = (type, content) => {
629
+ // global[`_ai_module_ch`].sendToQueue(
630
+ // 'ws_dashboard_module',
631
+ // Buffer.from(
632
+ // JSON.stringify({
633
+ // method: 'emit_message_to_dashboard',
634
+ // data: {
635
+ // service: type,
636
+ // to: uid,
637
+ // data: {
638
+ // conversation_id: conversation_id,
639
+ // job_id,
640
+ // delta: content,
641
+ // },
642
+ // },
643
+ // }),
644
+ // ),
645
+ // );
646
+ // };
647
+ // let emitToDashboard_interval;
648
+ // const update_job = async function (current_step_name) {
649
+ // if (emitToDashboard_interval) {
650
+ // clearInterval(emitToDashboard_interval);
651
+ // emitToDashboard('stream_delta', '<br><br>');
652
+ // }
653
+ // emitToDashboard('stream_delta', _.capitalize(current_step_name) + ' ... ');
654
+ // // emitToDashboard_interval = setInterval(() => {
655
+ // // emitToDashboard('stream_delta', '.');
656
+ // // }, 500);
657
+ // await jobs_module.update_job(
658
+ // {
659
+ // job_id,
660
+ // current_step_name: current_step_name,
661
+ // },
662
+ // global[`_ai_module_ch`],
663
+ // );
664
+ // };
665
+
666
+ // //////////////////////
667
+ // // emitToDashboard('stream_start');
668
+
669
+ // // await update_job('initiating conversation');
670
+ // // await _utils.delay(500);
671
+
672
+ // // 1. Ensure we have a conversation doc in Couch
673
+ // let conversation_exist;
674
+ // try {
675
+ // if (!conversation_id) throw new Error('no id');
676
+ // conversation_doc = await db_module.get_app_couch_doc_native(app_id, conversation_id);
677
+ // reference_type = conversation_doc.reference_type;
678
+ // reference_id = conversation_doc.reference_id;
679
+ // conversation_exist = true;
680
+ // // ai_agents = conversation_doc.ai_agents || [];
681
+ // } catch (err) {
682
+ // // new conversation
683
+ // const conversation_obj = await client.conversations.create();
684
+ // conversation_id = conversation_obj.id;
685
+ // conversation_doc.conversation_obj = conversation_obj;
686
+ // conversation_doc._id = conversation_id;
687
+ // // conversation_doc.ai_agents = ai_agents;
688
+ // await db_module.save_app_couch_doc_native(app_id, conversation_doc);
689
+ // }
690
+ // emitToDashboard('stream_start');
691
+ // await update_job('analyzing request');
692
+
693
+ // const init_agent_hooks = function (agent) {
694
+ // agent.on('agent_start', (context, agent) => {
695
+ // // emitToDashboard('stream_start');
696
+ // });
697
+
698
+ // agent.on('agent_end', (context, output) => {
699
+ // emitToDashboard('stream_end');
700
+ // });
701
+
702
+ // agent.on('agent_handoff', (context, nextAgent) => {
703
+ // emitToDashboard('agent_handoff', nextAgent.name);
704
+ // });
705
+
706
+ // agent.on('agent_tool_start', (context, tool, details) => {
707
+ // emitToDashboard('agent_tool_start', tool.name);
708
+ // });
709
+
710
+ // agent.on('agent_tool_end', (context, tool, result, details) => {
711
+ // emitToDashboard('agent_tool_end', tool.name);
712
+ // });
713
+ // };
714
+ // const get_agent_instructions = function (is_agent) {
715
+ // const get_output_format = function () {
716
+ // let ret = '';
717
+ // switch (output_format) {
718
+ // case 'md':
719
+ // ret = 'Include mark down (MD) tags where necessary in the response.';
720
+ // break;
721
+
722
+ // default:
723
+ // break;
724
+ // }
725
+
726
+ // return ret;
727
+ // };
728
+
729
+ // let new_visit = true;
730
+ // if (visitors?.[d]?.[uid]) {
731
+ // new_visit = false;
732
+ // } else {
733
+ // visitors[d][uid] = prompt;
734
+ // }
735
+
736
+ // const triage_assistant = `
737
+
738
+ // You are Nissim AI Xuda assistant — a smart triage router.
739
+ // Your job is to instantly decide who should handle the user's request:
740
+ // - If the question is general or can be answered directly, respond yourself.
741
+ // - If it requires a specific specialist, route it to them.
742
+ // Only fall back to web search as an absolute last resort — never use it unless strictly necessary.
743
+
744
+ // ${new_visit ? 'Always start your reply with a friendly greeting using their actual name based on the context.' : ''}
745
+ // ${get_output_format()}
746
+
747
+ // `;
748
+
749
+ // const identity = `
750
+
751
+ // SPECIAL IDENTITY RULE (overrides everything else):
752
+ // When the user asks any variation of:
753
+ // - "who am I"
754
+ // - "what is my name"
755
+ // - "do you know who I am"
756
+ // - "tell me about myself"
757
+ // - or any similar identity question
758
+
759
+ // You MUST:
760
+
761
+ // 1. answer directly and personally using the real user context provided below.
762
+ // 2. Never say you don’t know or can’t determine their identity.
763
+ // 3. Show thinking process step by step before providing the final answer.
764
+
765
+ // Current user context (use this every time also for any location base prompts):
766
+ // ${JSON.stringify(context)}
767
+
768
+ // Example response (adapt naturally):
769
+ // "Hi Sarah! You're Sarah Cohen, our VIP client from Tel Aviv, account #89231. You've been with us since 2022 and usually reach out about trading or portfolio updates. How can I help you today?"
770
+ // `.trim();
771
+
772
+ // return is_agent ? identity : triage_assistant + identity;
773
+ // };
774
+ // const get_agents = async function () {
775
+ // if (typeof ai_agents === 'undefined') {
776
+ // // no agents
777
+ // ai_agents = [];
778
+ // } else if (!ai_agents.length) {
779
+ // // auto agent mode
780
+ // const ai_agents_ret = await get_ai_agents({ uid });
781
+ // for (const doc of ai_agents_ret.data.docs) {
782
+ // ai_agents.push(doc.id);
783
+ // }
784
+ // }
785
+
786
+ // const list = [];
787
+
788
+ // let modelSettings = {};
789
+
790
+ // if (reference_type === 'ai_agents') {
791
+ // ai_agents.push(reference_id);
792
+ // }
793
+
794
+ // for (const agent_id of ai_agents) {
795
+ // let ai_agent_doc;
796
+ // try {
797
+ // ai_agent_doc = await db_module.get_app_couch_doc_native(app_id, agent_id);
798
+ // } catch (err) {
799
+ // throw new Error(err.message);
800
+ // }
801
+
802
+ // if (ai_agent_doc.use_tools_only) {
803
+ // modelSettings.toolChoice = 'required';
804
+ // }
805
+
806
+ // let tools = [];
807
+ // let tool_resources = {};
808
+
809
+ // for (const [key, val] of Object.entries(ai_agent_doc?.agentConfig?.agent_tools || [])) {
810
+ // const { name, description } = val;
811
+ // switch (val.type) {
812
+ // case 'web_search': {
813
+ // //hosted_web_search
814
+ // tools.push(webSearchTool());
815
+ // break;
816
+ // }
817
+
818
+ // case 'mcp': {
819
+ // tools.push(
820
+ // hostedMcpTool({
821
+ // serverLabel: 'mcp_' + (val?.name?.replaceAll(' ', '_') || key), //ai_agent_doc.properties.menuName,
822
+ // serverUrl: val.url,
823
+ // headers: {
824
+ // Authorization: `Bearer ${val.authentication_key || gtp_token}`,
825
+ // 'X-gtp-token': 'true',
826
+ // 'Content-Type': 'application/json',
827
+ // },
828
+ // require_approval: 'never',
829
+ // }),
830
+ // );
831
+ // break;
832
+ // }
833
+
834
+ // case 'cpi': {
835
+ // try {
836
+ // debugger;
837
+ // const api_allow_methods = Object.keys(_conf.cpi_methods);
838
+ // for (const method_name of api_allow_methods || []) {
839
+ // const method_prop = _conf.cpi_methods[method_name];
840
+
841
+ // if (!method_prop) continue;
842
+ // if (method_prop.private) continue;
843
+ // if (!method_prop.description) continue;
844
+
845
+ // let inputSchema = {};
846
+
847
+ // const get_z_item = function (key, val) {
848
+ // let prop = {};
849
+ // if (val.type === 'object' && val.items) {
850
+ // for (const [item_key, item_val] of Object.entries(val.items.properties)) {
851
+ // prop[item_key] = get_z_item(item_key, item_val);
852
+ // if (!val?.items?.required?.includes(item_key)) {
853
+ // prop[item_key] = prop[item_key].optional();
854
+ // }
855
+ // }
856
+ // }
857
+
858
+ // if (val.type === 'array') {
859
+ // prop = get_z_item('', val.items);
860
+ // }
861
+
862
+ // let _z = z[val.type](prop);
863
+
864
+ // if (!val.mandatory) {
865
+ // _z = _z.optional();
866
+ // }
867
+
868
+ // if (val.enum) {
869
+ // _z = z.enum(val.enum);
870
+ // }
871
+
872
+ // let valid_values = '';
873
+ // if (val.options) {
874
+ // valid_values = val.options.join(', ');
875
+ // }
876
+ // if (val.description) {
877
+ // const desc = val.name || key.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase());
878
+ // _z = _z.describe((desc ? desc + ' - ' : '') + val.description + (valid_values ? ' Valid values: ' + valid_values : ''));
879
+ // }
880
+
881
+ // return _z;
882
+ // };
883
+
884
+ // if (method_prop.fields) {
885
+ // try {
886
+ // for (const [key, val] of Object.entries(method_prop.fields)) {
887
+ // inputSchema[key] = get_z_item(key, val);
888
+ // }
889
+ // } catch (error) {
890
+ // debugger;
891
+ // }
892
+ // }
893
+ // try {
894
+ // tools.push(
895
+ // tool({
896
+ // name: method_name.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase()),
897
+ // description: method_prop.description,
898
+ // parameters: z.object(inputSchema),
899
+ // async execute(e, RunContext) {
900
+ // const params = e;
901
+ // try {
902
+ // const response = await fetch(`http://localhost:3007/cpi/${method_name}`, {
903
+ // method: 'POST',
904
+ // headers: {
905
+ // Accept: 'application/json',
906
+ // 'Content-Type': 'application/json',
907
+ // },
908
+ // body: JSON.stringify({ ...params, ...{ gtp_token } }),
909
+ // });
910
+ // const ret = await response.json();
911
+ // return {
912
+ // content: [{ type: 'text', text: JSON.stringify(ret || '', null, 2) }],
913
+ // };
914
+ // } catch (err) {
915
+ // return 'unknown';
916
+ // }
917
+ // },
918
+ // }),
919
+ // );
920
+ // } catch (error) {
921
+ // debugger;
922
+ // }
923
+ // }
924
+ // } catch (error) {
925
+ // debugger;
926
+ // }
927
+ // break;
928
+ // }
929
+
930
+ // // case 'web_search': {
931
+ // // tools.push(
932
+ // // tool({
933
+ // // name: name || val.type,
934
+ // // description: description || val.type,
935
+ // // parameters: z.object({
936
+ // // query: z.string().describe('The search query text.'),
937
+ // // numResults: z.number().int().describe('Number of top search results to return.').default(3),
938
+ // // }),
939
+ // // async execute(e, RunContext) {
940
+ // // const { query, numResults } = e;
941
+ // // try {
942
+ // // const searchUrl = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_redirect=1`;
943
+ // // const response = await fetch(searchUrl);
944
+ // // const data = await response.json();
945
+
946
+ // // // Simplify results
947
+ // // const results = (data.RelatedTopics || []).slice(0, numResults).map((item) => ({
948
+ // // title: item.Text,
949
+ // // url: item.FirstURL,
950
+ // // }));
951
+
952
+ // // return JSON.stringify(results, null, 2);
953
+ // // } catch (err) {
954
+ // // return 'unknown';
955
+ // // }
956
+ // // },
957
+ // // }),
958
+ // // );
959
+ // // break;
960
+ // // }
961
+
962
+ // // case 'image_generate': {
963
+ // // tools.push(
964
+ // // tool({
965
+ // // name,
966
+ // // description,
967
+ // // parameters: z.object({
968
+ // // prompt: z.string().describe('The prompt for the image.'),
969
+ // // numGenerations: z.number().int().describe('Number generations to image create.').default(3),
970
+ // // }),
971
+ // // async execute(e, RunContext) {
972
+ // // const { prompt, numGenerations = val?.image_generations } = e;
973
+ // // try {
974
+ // // const base64 = await create_image(prompt, undefined, undefined, numGenerations);
975
+ // // // console.log(base64);
976
+
977
+ // // // return `<img src="data:image/jpg;base64,${base64}">`;
978
+ // // return `![Generated Image](data:image/jpeg;base64,${base64})`;
979
+ // // } catch (err) {
980
+ // // return 'unknown';
981
+ // // }
982
+ // // },
983
+ // // }),
984
+ // // );
985
+ // // break;
986
+ // // }
987
+
988
+ // case 'image_generate': {
989
+ // tools.push(
990
+ // tool({
991
+ // name,
992
+ // description,
993
+ // parameters: z.object({
994
+ // prompt: z.string().describe('The prompt for the image.'),
995
+ // numGenerations: z.number().int().describe('Number generations to image create.').default(3),
996
+ // }),
997
+ // async execute(e, RunContext) {
998
+ // const { prompt, numGenerations } = e;
999
+ // try {
1000
+ // let imgTags = '';
1001
+ // const images_arr = await create_and_upload_image_to_drive('workspace', 'Chat Images', prompt, numGenerations, uid, app_id, job_id, headers);
1002
+ // for (const img_obj of images_arr) {
1003
+ // imgTags += `<img src="${img_obj.file_url}" alt="${prompt}" style="max-width: 100%; border-radius: 8px;" />`;
1004
+ // }
1005
+
1006
+ // return imgTags;
1007
+ // } catch (err) {
1008
+ // console.error('Image Tool Error:', err);
1009
+ // return `Error generating image: ${err.message}`;
1010
+ // }
1011
+ // },
1012
+ // }),
1013
+ // );
1014
+ // break;
1015
+ // }
1016
+
1017
+ // case 'table': {
1018
+ // const table_id = val.prog_id;
1019
+ // // prompt += ` for table_id: ${table_id}`;
1020
+ // context.table_id = table_id;
1021
+ // tools.push(get_studio_table_info_by_table_id_tool);
1022
+ // //======== mock data ==========
1023
+ // // const mock_data_generator_agent = get_mock_data_generator_agent(app_id, table_id);
1024
+ // // tools.push(
1025
+ // // mock_data_generator_agent.asTool({
1026
+ // // toolName: 'Mock Data Generator',
1027
+ // // toolDescription: `generate Mock Data to a table`,
1028
+ // // }),
1029
+ // // );
1030
+ // // tools.push(get_studio_table_info_by_table_id_tool);
1031
+
1032
+ // //======== add data ==========
1033
+ // tools.push(
1034
+ // add_data_to_table_agent.asTool({
1035
+ // toolName: 'add data to table',
1036
+ // toolDescription: `add data to table`,
1037
+ // }),
1038
+ // );
1039
+
1040
+ // //======== fetch data ==========
1041
+ // tools.push(
1042
+ // fetch_table_data_agent.asTool({
1043
+ // toolName: 'Fetch Table Data Agent',
1044
+ // toolDescription: `fetch data from a table`,
1045
+ // }),
1046
+ // );
1047
+
1048
+ // //======== delete data ==========
1049
+ // tools.push(
1050
+ // delete_table_doc.asTool({
1051
+ // toolName: 'Delete Table Doc',
1052
+ // toolDescription: `The tool delete document from the database, need to ask for table`,
1053
+ // }),
1054
+ // );
1055
+
1056
+ // // tools.push(create_table_management_tool);
1057
+
1058
+ // // tools.push(create_landing_page_tool);
1059
+
1060
+ // // const add_data_to_table_agent = get_add_data_to_table_agent(app_id, table_id);
1061
+ // // tools.push(
1062
+ // // add_data_to_table_agent.asTool({
1063
+ // // toolName: 'add data to table',
1064
+ // // toolDescription: `add data to table`,
1065
+ // // }),
1066
+ // // );
1067
+
1068
+ // break;
1069
+ // }
1070
+
1071
+ // case 'file_search': {
1072
+ // if (val?.file?.vector_store_id) {
1073
+ // tools.push(fileSearchTool(val.file.vector_store_id));
1074
+ // }
1075
+
1076
+ // if (val?.youtube?.vector_store_id) {
1077
+ // tools.push(fileSearchTool(val.youtube.vector_store_id));
1078
+ // }
1079
+
1080
+ // break;
1081
+ // }
1082
+
1083
+ // case 'ai_agent': {
1084
+ // let opt = {};
1085
+ // // add all agents if no agent id
1086
+ // if (val.ai_agent_id) {
1087
+ // opt = {
1088
+ // _id: val.ai_agent_id,
1089
+ // };
1090
+ // }
1091
+ // const agent_ret = await get_ai_agents(opt);
1092
+ // if (agent_ret.code > -1) {
1093
+ // const agent_doc = agent_ret.data;
1094
+
1095
+ // const agent = new Agent({
1096
+ // name: agent_doc.agent_name,
1097
+ // instructions: agent_doc.agent_instructions,
1098
+ // });
1099
+
1100
+ // tools.push(
1101
+ // agent.asTool({
1102
+ // toolName: agent_doc.agent_name,
1103
+ // toolDescription: agent_doc.agent_instructions,
1104
+ // }),
1105
+ // );
1106
+ // }
1107
+ // // }
1108
+ // break;
1109
+ // }
1110
+ // case 'plugin': {
1111
+ // if (!val.plugin_id) {
1112
+ // throw new Error('undefined plugin_id');
1113
+ // }
1114
+ // if (!val.method) {
1115
+ // throw new Error('undefined method');
1116
+ // }
1117
+ // const tool = await get_plugin_tool(app_id, uid, val.plugin_id, val.method, {});
1118
+ // tools.push(tool);
1119
+ // break;
1120
+ // }
1121
+ // default:
1122
+ // break;
1123
+ // }
1124
+ // }
1125
+ // // if (!tools.length) continue;
1126
+ // const agent = new Agent({
1127
+ // name: ai_agent_doc._id,
1128
+ // instructions: ai_agent_doc.agentConfig.agent_instructions + get_agent_instructions(),
1129
+ // model,
1130
+ // tools,
1131
+ // metadata: {
1132
+ // agent_id: ai_agent_doc._id,
1133
+ // ts: Date.now(),
1134
+ // },
1135
+ // tool_resources,
1136
+ // modelSettings,
1137
+ // });
1138
+
1139
+ // init_agent_hooks(agent);
1140
+
1141
+ // list.push(agent);
1142
+ // }
1143
+ // //tell me more on xuda
1144
+ // // debugger;
1145
+
1146
+ // return list;
1147
+ // };
1148
+
1149
+ // // const get_attachment_agent = async function () {
1150
+ // // if (!attachments?.length) return;
1151
+ // // let tools = [];
1152
+ // // let file_names = [];
1153
+ // // let system_message_items = [];
1154
+ // // for (const file of attachments) {
1155
+ // // tools.push(fileSearchTool(file.id));
1156
+ // // file_names.push(file.file_name);
1157
+
1158
+ // // const file_info = await client.files.retrieve(file.id);
1159
+ // // // const file_content = await client.files.content(file.id);
1160
+ // // system_message_items.push({
1161
+ // // type: 'message',
1162
+ // // role: 'system',
1163
+ // // content: [{ type: 'input_text', text: `the user attached file name: ${file_info.filename} with content: ${file_content}` }],
1164
+ // // });
1165
+ // // }
1166
+
1167
+ // // const items = await client.conversations.items.create(conversation_id, {
1168
+ // // items: system_message_items,
1169
+ // // });
1170
+ // // console.log(items.data);
1171
+
1172
+ // // return new Agent({
1173
+ // // name: 'attachments agent',
1174
+ // // instructions: `You can see and analyze any files the user attaches:${JSON.stringify(file_names)} `,
1175
+ // // model,
1176
+ // // tools,
1177
+ // // });
1178
+ // // };
1179
+
1180
+ // const generate_XU_markdown = async function (type, data) {
1181
+ // return `XU>${job_id}{type:"${type}",data:${JSON.stringify(data)}}${job_id}<XU`;
1182
+ // };
1183
+
1184
+ // const attachment_handler = async function () {
1185
+ // if (!attachments?.length) return;
1186
+
1187
+ // const get_transcript = async function (filename) {
1188
+ // async function streamToBuffer(fileStream) {
1189
+ // const chunks = [];
1190
+ // for await (const chunk of fileStream) {
1191
+ // chunks.push(chunk);
1192
+ // }
1193
+ // return Buffer.concat(chunks);
1194
+ // }
1195
+
1196
+ // const validation_ret = file_upload_validator(filename);
1197
+ // if (!validation_ret.valid) {
1198
+ // throw new Error(validation_ret.error);
1199
+ // }
1200
+
1201
+ // const fileStream = await get_drive_file_stream(filename);
1202
+
1203
+ // let transcript;
1204
+ // switch (validation_ret.category) {
1205
+ // case 'audio':
1206
+ // case 'video': {
1207
+ // transcript = await transcribe(fileStream);
1208
+
1209
+ // break;
1210
+ // }
1211
+
1212
+ // case 'image': {
1213
+ // const fileBuffer = await streamToBuffer(fileStream);
1214
+ // const base64 = fileBuffer.toString('base64');
1215
+
1216
+ // const ret = await submit_chat_gpt_prompt({
1217
+ // prompt: [
1218
+ // {
1219
+ // role: 'user',
1220
+ // content: [
1221
+ // {
1222
+ // type: 'input_text',
1223
+ // text: `1. describe the image in detail. 2. Extract the text from this image into a clean markdown format `,
1224
+ // },
1225
+ // {
1226
+ // type: 'input_image',
1227
+ // image_url: `data:${validation_ret.mime};base64,${base64}`,
1228
+ // },
1229
+ // ],
1230
+ // },
1231
+ // ],
1232
+ // });
1233
+ // if (ret.code < 0) {
1234
+ // throw new Error('something went wrong try again later');
1235
+ // }
1236
+ // transcript = ret.data;
1237
+
1238
+ // break;
1239
+ // }
1240
+
1241
+ // case 'document':
1242
+ // case 'text': {
1243
+ // async function transcript_file(fileBuffer, fileName, mimeType) {
1244
+ // try {
1245
+ // const base64 = fileBuffer.toString('base64');
1246
+
1247
+ // const ret = await submit_chat_gpt_prompt({
1248
+ // prompt: [
1249
+ // {
1250
+ // role: 'user',
1251
+ // content: [
1252
+ // {
1253
+ // type: 'input_text',
1254
+ // text: 'Please extract all text from this document. Maintain the structure and formatting as much as possible.',
1255
+ // },
1256
+ // {
1257
+ // type: 'input_file',
1258
+ // filename: fileName || 'document.pdf',
1259
+
1260
+ // file_data: `data:${mimeType || 'application/pdf'};base64,${base64}`,
1261
+ // },
1262
+ // ],
1263
+ // },
1264
+ // ],
1265
+ // });
1266
+
1267
+ // return ret;
1268
+ // } catch (error) {
1269
+ // console.error('Error transcribing PDF:', error);
1270
+ // throw error;
1271
+ // }
1272
+ // }
1273
+ // const buffer = await streamToBuffer(fileStream);
1274
+ // transcript = await transcript_file(buffer, filename, validation_ret.mime);
1275
+
1276
+ // break;
1277
+ // }
1278
+
1279
+ // default:
1280
+ // break;
1281
+ // }
1282
+
1283
+ // return transcript;
1284
+ // };
1285
+
1286
+ // let file_names = [];
1287
+ // let system_message_items = [];
1288
+ // for (const file of attachments) {
1289
+ // file_names.push(file.filename);
1290
+ // const transcript = await get_transcript(file.filename);
1291
+
1292
+ // system_message_items.push({
1293
+ // type: 'message',
1294
+ // role: 'system',
1295
+ // content: [{ type: 'input_text', text: `the user attached file name: ${file.filename} with content: ${transcript.data || transcript}` }],
1296
+ // });
1297
+
1298
+ // prompt += generate_XU_markdown('attachment', file); //`[![Alt Text](${file.file_url})]`;
1299
+ // }
1300
+
1301
+ // const items = await client.conversations.items.create(conversation_id, {
1302
+ // items: system_message_items,
1303
+ // });
1304
+ // console.log(items.data);
1305
+ // };
1306
+
1307
+ // const set_ts_to_agent = async function () {
1308
+ // try {
1309
+ // let agent_doc = await db_module.get_app_couch_doc_native(app_id, reference_id);
1310
+ // agent_doc.ts = Date.now();
1311
+ // await db_module.save_app_couch_doc_native(app_id, agent_doc);
1312
+ // } catch (err) {}
1313
+ // };
1314
+
1315
+ // try {
1316
+ // const runner = new Runner();
1317
+ // let _agent = [];
1318
+
1319
+ // await update_job('preparing tools');
1320
+ // const agents = await get_agents();
1321
+
1322
+ // /////////////
1323
+ // if (attachments?.length) {
1324
+ // await update_job('analyzing attachments');
1325
+ // await attachment_handler();
1326
+ // }
1327
+ // ////////////
1328
+
1329
+ // if (reference_type === 'ai_agents') {
1330
+ // _agent = agents[0];
1331
+
1332
+ // set_ts_to_agent();
1333
+ // } else {
1334
+ // // 3. Build triage agent that can hand off
1335
+ // _agent = new Agent({
1336
+ // name: 'Triage Agent',
1337
+ // instructions: get_agent_instructions(),
1338
+ // model,
1339
+ // handoffs: agents, // this lets triageAgent forward to other agents
1340
+ // });
1341
+ // }
1342
+
1343
+ // let opt = {
1344
+ // conversationId: conversation_id,
1345
+ // context,
1346
+ // stream,
1347
+ // };
1348
+
1349
+ // await update_job('submitting chat');
1350
+ // init_agent_hooks(_agent);
1351
+ // const output = await runner.run(_agent, prompt, opt);
1352
+ // const done = async function (output) {
1353
+ // try {
1354
+ // const obj = { id: output?.output?.[0]?.id, ts: Date.now(), usage: { inputTokens: output.state._context.usage.inputTokens, outputTokens: output.state._context.usage.outputTokens }, ai_agent_id: output.state._currentAgent.name, attachments };
1355
+ // conversation_doc = await db_module.get_app_couch_doc_native(app_id, conversation_id);
1356
+
1357
+ // conversation_doc.ts = Date.now();
1358
+ // conversation_doc.messages.push(obj);
1359
+ // await db_module.save_app_couch_doc_native(app_id, conversation_doc);
1360
+
1361
+ // if (!conversation_exist) {
1362
+ // setTimeout(async () => {
1363
+ // // Ask GPT for title
1364
+ // const title = await submit_chat_gpt_prompt({
1365
+ // prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`,
1366
+ // model: 'gpt-5-nano',
1367
+ // });
1368
+
1369
+ // conversation_doc = await db_module.get_app_couch_doc_native(app_id, conversation_id);
1370
+ // conversation_doc.title = title.data;
1371
+
1372
+ // await db_module.save_app_couch_doc_native(app_id, conversation_doc);
1373
+ // update_thumbnail('conversation', conversation_doc, app_id, uid, job_id, headers);
1374
+ // }, 5000);
1375
+ // } else {
1376
+ // if (!conversation_doc.chat_image && (!conversation_doc.thumbnail_request_ts || Date.now() - conversation_doc.thumbnail_request_ts > 120000)) {
1377
+ // update_thumbnail('conversation', conversation_doc, app_id, uid, job_id, headers);
1378
+ // }
1379
+ // }
1380
+ // } catch (error) {
1381
+ // debugger;
1382
+ // }
1383
+ // // }
1384
+
1385
+ // // return {
1386
+ // // code: 4,
1387
+ // // data: {
1388
+ // // conversation_doc,
1389
+ // // response: output.output, // output.finalOutput ?? output.output ?? output, // depends on SDK shape
1390
+ // // },
1391
+ // // };
1392
+ // };
1393
+
1394
+ // if (stream) {
1395
+ // const output_stream = output.toTextStream({
1396
+ // compatibleWithNodeStreams: true,
1397
+ // });
1398
+ // let buffer = '';
1399
+
1400
+ // let response_start;
1401
+
1402
+ // // 1. Consume the stream exactly once
1403
+ // let string_debug = '';
1404
+
1405
+ // for await (const chunk of output_stream) {
1406
+ // if (!response_start) {
1407
+ // response_start = true;
1408
+
1409
+ // await update_job('streaming results');
1410
+ // emitToDashboard('response_start');
1411
+ // }
1412
+ // const text = chunk.toString();
1413
+ // // console.log('[CHUNK]', text);
1414
+ // emitToDashboard('stream_delta', text);
1415
+ // string_debug += text;
1416
+ // // Accumulate it
1417
+ // buffer += chunk;
1418
+ // }
1419
+ // // console.log('string_debug', string_debug);
1420
+ // }
1421
+ // // else {
1422
+ // await update_job('finalizing');
1423
+ // await done(output);
1424
+ // return {
1425
+ // code: 4,
1426
+ // data: {
1427
+ // conversation_doc,
1428
+ // response: output.output, // output.finalOutput ?? output.output ?? output, // depends on SDK shape
1429
+ // },
1430
+ // };
1431
+ // // }
1432
+ // } catch (err) {
1433
+ // debugger;
1434
+ // emitToDashboard('stream_end');
1435
+ // return { code: -4, data: err.message || String(err) };
1436
+ // }
1437
+ // };