@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.
@@ -0,0 +1,1455 @@
1
+ import { z } from 'zod';
2
+ import fs from 'fs/promises';
3
+ import * as path from 'path';
4
+
5
+ global._conf = JSON.parse(await fs.readFile(path.join(process.env.XUDA_HOME, process.env.XUDA_CONFIG), 'utf-8'));
6
+
7
+ const module_path = path.join(process.env.XUDA_HOME, 'cpi') + (!_conf.is_debug ? '/node_modules/@xuda.io' : '');
8
+ const runtime_modules_path = path.join(process.env.XUDA_HOME, 'dist', 'runtime', 'js', 'modules');
9
+
10
+ import { Agent, Runner, tool, setDefaultOpenAIKey, RunContext, fileSearchTool } from '@openai/agents';
11
+ import OpenAI from 'openai';
12
+
13
+ setDefaultOpenAIKey(_conf.OPENAI_API_KEY);
14
+
15
+ import _ from 'lodash';
16
+ import JSON5 from 'json5';
17
+ import UglifyJS from 'uglify-js';
18
+
19
+ const { get_xuda_couch } = await import(`${module_path}/db_module/index.es.mjs`);
20
+ const { createDoc, valid_menuType } = await import(`${runtime_modules_path}/xuda-studio-doc-utils.mjs`);
21
+ const { init, check, check_structure } = await import(`${runtime_modules_path}/xuda-studio-checker.mjs`);
22
+
23
+ var studio_units = {};
24
+
25
+ const init_studio_units = async function () {
26
+ try {
27
+ const db = get_xuda_couch('xuda_website');
28
+ const ret = await db.find({ selector: { type: 'app_builder' } });
29
+ for (const doc of ret.docs) {
30
+ studio_units[doc._id] = doc;
31
+ }
32
+ } catch (err) {
33
+ console.error(err);
34
+ }
35
+ };
36
+
37
+ await init_studio_units();
38
+
39
+ const get_user_name_tool = tool({
40
+ name: 'get_user_name_tool',
41
+ description: 'Get the user name by uid',
42
+ parameters: z.object({
43
+ uid: z.string(),
44
+ }),
45
+ async execute(e, RunContext) {
46
+ try {
47
+ const db = get_xuda_couch('xuda_accounts');
48
+ const doc = await db.get(e.uid);
49
+ let username = 'unknown';
50
+ if (doc?.account_info) {
51
+ username = doc.account_info.first_name + ' ' + doc.account_info.last_name;
52
+
53
+ if (!username) {
54
+ username = +doc.account_info.email;
55
+ }
56
+ }
57
+
58
+ return username;
59
+ } catch (err) {
60
+ return 'unknown';
61
+ }
62
+ },
63
+ });
64
+
65
+ const create_initial_studio_doc_tool = tool({
66
+ name: 'Create initial studio doc tool',
67
+ description: 'I am responsible to create initial doc for the studio',
68
+ parameters: z.object({
69
+ uid: z.string().describe('the user id'),
70
+ app_id: z.string().describe('the app id'),
71
+ menuType: z.enum(valid_menuType).describe('the studio doc type'),
72
+ checkedInUserName: z.string().describe('the name of check-in user'),
73
+ parentId: z.string().describe('the doc id of the parent doc'),
74
+ }),
75
+ async execute(e, RunContext) {
76
+ // console.log('create_initial_studio_doc_tool >>>> ', e);
77
+ const { uid, menuType, checkedInUserName, app_id, parentId } = e;
78
+ try {
79
+ const doc = createDoc({ uid, menuType, checkedInUserName, app_id, parentId });
80
+
81
+ return doc;
82
+ } catch (err) {
83
+ return 'unknown';
84
+ }
85
+ },
86
+ });
87
+
88
+ const check_studio_doc_tool = tool({
89
+ name: 'Check studio doc',
90
+ description: 'I am responsible to check and validate studio doc',
91
+ parameters: z.object({
92
+ app_id: z.string().describe('the app id'),
93
+ doc: z.string().describe('the studio doc to validate for table,globals,components and more'),
94
+ }),
95
+ async execute(e, RunContext) {
96
+ try {
97
+ const doc = JSON5.parse(e.doc);
98
+ let progs = {};
99
+
100
+ const db = get_xuda_couch('xuda_master');
101
+ const app_obj = await db.get(e.app_id);
102
+ const project_db = get_xuda_couch(app_obj.app_db_name);
103
+ let studio_nodes = await project_db.view('xuda', 'studio_nodes', {});
104
+ for (const doc of studio_nodes.rows) {
105
+ progs[doc.value._id] = {}; //doc.value;
106
+ }
107
+
108
+ init(app_obj, progs, _, true, null, null, UglifyJS, JSON5, _conf, true);
109
+ let result = check(doc);
110
+ console.log('check_studio_doc_tool >>>> ', result.check_errors, e.doc);
111
+ delete result.doc;
112
+ return result;
113
+ } catch (err) {
114
+ console.error(err, e.doc);
115
+ return err.message;
116
+ }
117
+ },
118
+ });
119
+
120
+ const get_plugins = tool({
121
+ name: 'Get plugins',
122
+ description: 'I am responsible to return all available plugins',
123
+ parameters: z.object({}),
124
+ async execute(e, RunContext) {
125
+ try {
126
+ const db = get_xuda_couch('xuda_plugins');
127
+ const plugins_res = await db.view('xuda', 'all-active-plugins', {});
128
+ let data = [];
129
+ if (!_.isEmpty(plugins_res.rows)) {
130
+ for (val of plugins_res.rows) {
131
+ if (!['library', 'widget', 'ui'].includes(val.plugin_type)) continue;
132
+ var plugin = _.clone(val.value);
133
+ delete plugin.account_id;
134
+ delete plugin.manifest;
135
+ delete plugin.plugin_name;
136
+ delete plugin.setup;
137
+ delete plugin.stat;
138
+ delete plugin.updated_date;
139
+ plugin._id = plugin._id.replace('@xuda.io/', '');
140
+
141
+ data.push(plugin);
142
+ }
143
+ }
144
+
145
+ console.log('get_plugins >>>> ', data);
146
+ return data;
147
+ } catch (err) {
148
+ console.error(err);
149
+ return err.message;
150
+ }
151
+ },
152
+ });
153
+
154
+ const create_app_doc_tool = tool({
155
+ name: 'save project doc tool',
156
+ description: 'Save doc (such as table,component,set_data,get_data,alert,batch,globals,route,database) to the project to db',
157
+ parameters: z.object({
158
+ app_id: z.string(),
159
+ doc: z.string(), // z.object({}), // _id
160
+ }),
161
+ async execute(e, RunContext) {
162
+ try {
163
+ const doc = JSON5.parse(e.doc);
164
+
165
+ const db = get_xuda_couch('xuda_master');
166
+ const app_obj = await db.get(e.app_id);
167
+ const project_db = get_xuda_couch(app_obj.app_db_name);
168
+
169
+ const result = await project_db.insert(doc);
170
+ console.log('create_app_doc_tool >>>> ', result);
171
+ return result;
172
+ } catch (err) {
173
+ console.error(err);
174
+ return err.message;
175
+ }
176
+ },
177
+ });
178
+
179
+ const update_app_doc_tool = tool({
180
+ name: 'update app doc tool',
181
+ description: 'update any app doc query by _id and _rev and save to the app db',
182
+ parameters: z.object({
183
+ app_id: z.string(),
184
+ doc: z.object({ _id: z.string(), _rev: z.string() }),
185
+ }),
186
+ async execute(e, RunContext) {
187
+ console.log(`SAVED ${e.app_id}`);
188
+ return `OK`;
189
+ },
190
+ });
191
+
192
+ const get_app_doc_tool = tool({
193
+ name: 'get app doc tool',
194
+ description: 'get any doc by id from the app db',
195
+ parameters: z.object({
196
+ app_id: z.string(),
197
+ }),
198
+ async execute(e, RunContext) {
199
+ console.log(`SAVED ${e.app_id}`);
200
+ return `OK`;
201
+ },
202
+ });
203
+
204
+ const get_additional_information_tool = tool({
205
+ name: 'get additional information tool',
206
+ description: 'get additional information for object unit tool',
207
+ parameters: z.object({
208
+ object_unit: z.enum(['table']),
209
+ }),
210
+ async execute(e, RunContext) {
211
+ let obj = { table: ['studio_table'] };
212
+ const db = get_xuda_couch('xuda_website');
213
+ try {
214
+ if (!obj[e.object_unit]) throw new Error(`${e.object_unit} not found`);
215
+ const doc = await db.get(obj[e.object_unit]);
216
+ // console.log(`INFO ${doc}`);
217
+ return doc.md || doc;
218
+ } catch (err) {
219
+ console.error(err);
220
+ return err.message;
221
+ }
222
+ },
223
+ });
224
+
225
+ /// todos
226
+
227
+ // plugins tool
228
+ // md tool
229
+ // examples
230
+
231
+ // export const submit_agentic_studio_chat_gpt_prompt_old = async function (req) {
232
+ // try {
233
+ // const { user_prompt, object_unit, uid, app_id } = req;
234
+ // const db = get_xuda_couch('xuda_master');
235
+
236
+ // const app_obj = await db.get(app_id);
237
+ // const project_db = get_xuda_couch(app_obj.app_db_name);
238
+
239
+ // // let check_results = {};
240
+
241
+ // const auth = async function () {
242
+ // if (app_obj.app_uId !== uid) {
243
+ // const db_team = get_xuda_couch('xuda_team');
244
+ // let master_auth_users = await db_team.view('xuda', 'user_active_shares', {
245
+ // key: [uid, app_id],
246
+ // });
247
+ // if (!master_auth_users.rows.includes(uid)) {
248
+ // throw new Error('user unauthorized');
249
+ // }
250
+ // }
251
+ // };
252
+
253
+ // await auth();
254
+
255
+ // const get_app_instructions = function () {
256
+ // return `
257
+ // ### context ###
258
+ // uid=${uid}
259
+ // app_id=${app_id}
260
+
261
+ // ### Persona & Role ###
262
+ // - You are a helpful and professional technical assistant named ${object_unit} builder.
263
+
264
+ // ### Tasks ###
265
+
266
+ // Your job is to assist the user with creating a ${user_prompt} that includes all tasks needed.
267
+
268
+ // *** step 1: list all the tables needed for the task
269
+ // *** step 2: iterate the table list and build tables array using the Table builder tool
270
+
271
+ // ### Additional information ###
272
+
273
+ // ### Output ###
274
+ // return Array of objects, each object represents a table structure, only the valid JSON array of objects. Do not add comments, explanation, or formatting. No markdown blocks.
275
+
276
+ // ### Examples ###
277
+
278
+ // `;
279
+ // };
280
+
281
+ // const get_table_instructions = function () {
282
+ // return `
283
+ // ### context ###
284
+ // uid=${uid}
285
+ // app_id=${app_id}
286
+
287
+ // ### Persona & Role ###
288
+ // - You are a helpful and professional technical assistant named ${object_unit} builder.
289
+
290
+ // ### Tasks ###
291
+
292
+ // Your job is to assist the user with creating a ${user_prompt} that includes a full set of fields according to the provided table structure.
293
+
294
+ // - You must include all relevant fields a typical ${user_prompt} would require
295
+ // - Add **multiple entries** in the "tableFields" array as needed to fully represent the structure.
296
+ // - Follow the format and conventions shown in the table structure example.
297
+ // - use uid for "createdByUid" and "checkedInUserId"
298
+
299
+ // - always create_initial_studio_doc_tool to create the initial doc
300
+ // - always get get_additional_information_tool for table structure example
301
+ // - always validate against this code ${JSON.stringify(check_structure)}
302
+
303
+ // ### Output ###
304
+ // return Array of objects, each object represents a table structure, only the valid JSON array of objects. Do not add comments, explanation, or formatting. No markdown blocks.
305
+
306
+ // ### Examples ###
307
+
308
+ // `;
309
+ // };
310
+
311
+ // const get_agents_as_a_tool = function (agent_list = []) {
312
+ // let _tools = [];
313
+ // for (const agent of agent_list) {
314
+ // const _agent = new Agent(studio_agents_obj[agent]);
315
+ // const tool = _agent.asTool({
316
+ // toolName: studio_agents_obj[agent].name,
317
+ // toolDescription: `Generate a ${agent} of the supplied text.`,
318
+ // });
319
+
320
+ // _tools.push(tool);
321
+ // }
322
+
323
+ // return _tools;
324
+ // };
325
+
326
+ // let studio_agents_obj = {
327
+ // app: {
328
+ // name: 'App builder',
329
+ // instructions: get_app_instructions(),
330
+ // tools: [get_user_name_tool],
331
+ // model: 'gpt-4o',
332
+ // modelSettings: {
333
+ // toolChoice: 'required', // ← this enables tool use
334
+ // responseFormat: {
335
+ // text: {
336
+ // format: {
337
+ // type: 'array', // or "markdown" if needed
338
+ // },
339
+ // },
340
+ // },
341
+ // outputType: z.array(z.object()),
342
+ // },
343
+ // },
344
+ // table: {
345
+ // name: 'Table builder',
346
+ // instructions: get_table_instructions(),
347
+ // tools: [get_user_name_tool, create_initial_studio_doc_tool, get_additional_information_tool],
348
+ // model: 'gpt-4o',
349
+ // modelSettings: {
350
+ // toolChoice: 'required', // ← this enables tool use
351
+ // responseFormat: {
352
+ // text: {
353
+ // format: {
354
+ // type: 'array', // or "markdown" if needed
355
+ // },
356
+ // },
357
+ // },
358
+ // outputType: z.array(
359
+ // z.object({
360
+ // _id: z.string(),
361
+ // stat: z.number(),
362
+ // docType: z.string(),
363
+ // docDate: z.number(),
364
+ // ts: z.number(),
365
+ // order_ts: z.number(),
366
+ // studio_meta: z.object({
367
+ // created: z.number(),
368
+ // createdByUid: z.string(),
369
+ // checkedInUserId: z.string(),
370
+ // savedByUid: z.string(),
371
+ // checkedInUserName: z.string(),
372
+ // parentId: z.string(),
373
+ // source: z.string(),
374
+ // }),
375
+ // properties: z.object({
376
+ // menuName: z.string(),
377
+ // menuType: z.string(),
378
+ // databaseSocket: z.string(),
379
+ // }),
380
+ // tableIndexes: z.array(
381
+ // z.object({
382
+ // id: z.string(),
383
+ // data: z.object({
384
+ // name: z.string(),
385
+ // unique: z.boolean(),
386
+ // keys: z.array(z.string()),
387
+ // }),
388
+ // }),
389
+ // ),
390
+ // tableFields: z.array(
391
+ // z.object({
392
+ // id: z.string(),
393
+ // data: z.object({
394
+ // field_id: z.string(),
395
+ // }),
396
+ // props: z.object({
397
+ // fieldType: z.string(),
398
+ // }),
399
+ // }),
400
+ // ),
401
+ // }),
402
+ // ),
403
+ // },
404
+ // },
405
+ // };
406
+
407
+ // if (object_unit === 'app') {
408
+ // const agents_as_a_tool_arr = get_agents_as_a_tool(['table']);
409
+ // studio_agents_obj.app.tools = [...studio_agents_obj.app.tools, ...agents_as_a_tool_arr];
410
+ // }
411
+ // let attempts = 0;
412
+ // const run = async function (user_prompt, object_unit) {
413
+ // attempts++;
414
+ // console.log('AI Attempts >>>', attempts);
415
+ // if (attempts > 10) throw new Error('too many attempts');
416
+
417
+ // const _agent = new Agent(studio_agents_obj[object_unit]);
418
+
419
+ // const runner = new Runner();
420
+
421
+ // const result = await runner.run(_agent, user_prompt, {
422
+ // context: { uid, app_id },
423
+ // });
424
+
425
+ // const parse_results = async function (result) {
426
+ // let docs = [];
427
+ // try {
428
+ // docs = JSON5.parse(result.finalOutput);
429
+ // } catch (err) {
430
+ // console.error(err);
431
+ // // await run(user_prompt + ' ' + err.message + ' ### OUTPUT: Array of objects, each object represents a table structure, only the valid JSON array of objects. Do not add comments, explanation, or formatting. No markdown blocks.'); //+ result.finalOutput
432
+ // throw new Error('result parse error', { cause: err });
433
+ // }
434
+ // return docs;
435
+ // };
436
+ // let docs = await parse_results(result);
437
+
438
+ // // /////////////////////////////
439
+ // // // check results
440
+ // // /////////////////////////////
441
+ // // const check_results = async function () {
442
+ // // let progs = {};
443
+ // // // for (const doc of docs) {
444
+ // // // progs[doc._id] = doc;
445
+ // // // }
446
+ // // let studio_nodes = await project_db.view('xuda', 'studio_nodes', {});
447
+ // // for (const doc of studio_nodes.rows) {
448
+ // // progs[doc.value._id] = doc.value;
449
+ // // }
450
+
451
+ // // init(app_obj, progs, _, true, null, null, UglifyJS, JSON5, _conf, true);
452
+ // // for (const doc of docs) {
453
+ // // const d = Date.now();
454
+ // // if (doc.studio_meta) {
455
+ // // doc.studio_meta.source = 'studio ai';
456
+ // // }
457
+ // // doc.stat = 3;
458
+ // // doc.docType = 'studio';
459
+ // // doc.docDate = d;
460
+ // // doc.ts = d;
461
+ // // doc.order_ts = d;
462
+ // // doc.app_id = app_id;
463
+ // // // progs[doc._id] = doc;
464
+
465
+ // // const check_result = check(doc);
466
+ // // progs[doc._id] = doc;
467
+ // // check_results[doc._id] = { check_result, doc };
468
+ // // if (check_result.check_errors.length) {
469
+ // // console.error(check_result.check_errors);
470
+ // // // result = await run(user_prompt + ' ' + JSON.stringify(check_result.check_errors) + ' ' + result.finalOutput);
471
+ // // // throw new Error(`check errors`, { cause: { check_result: check_result.check_errors, result: result.finalOutput } });
472
+ // // }
473
+ // // // console.log('check_studio_doc_tool >>>> ', check_result);
474
+ // // }
475
+
476
+ // // //////////////////////////////////
477
+ // // let node_promises = [];
478
+ // // for (const [key, val] of Object.entries(nodeP.children)) {
479
+ // // node_promises.push(
480
+ // // new Promise(async (resolve, reject) => {
481
+ // // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $divP, nodeP.children[key], parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, nodeP, null, $root_container);
482
+
483
+ // // resolve();
484
+ // // }),
485
+ // // );
486
+ // // }
487
+ // // let check_promises = [];
488
+ // // for (const doc of docs) {
489
+ // // check_promises.push(
490
+ // // new Promise(async (resolve, reject) => {
491
+ // // const d = Date.now();
492
+ // // if (doc.studio_meta) {
493
+ // // doc.studio_meta.source = 'studio ai';
494
+ // // }
495
+ // // doc.stat = 3;
496
+ // // doc.docType = 'studio';
497
+ // // doc.docDate = d;
498
+ // // doc.ts = d;
499
+ // // doc.order_ts = d;
500
+ // // doc.app_id = app_id;
501
+ // // // progs[doc._id] = doc;
502
+
503
+ // // const check_result = check(doc);
504
+ // // progs[doc._id] = doc;
505
+ // // // check_results[doc._id] = { check_result, doc };
506
+ // // if (!check_result.check_errors.length) resolve();
507
+
508
+ // // console.error(check_result.check_errors);
509
+ // // // result = await run(user_prompt + ' ' + JSON.stringify(check_result.check_errors) + ' ' + result.finalOutput);
510
+ // // // throw new Error(`check errors`, { cause: { check_result: check_result.check_errors, result: result.finalOutput } });
511
+ // // }),
512
+ // // );
513
+ // // // console.log('check_studio_doc_tool >>>> ', check_result);
514
+ // // }
515
+
516
+ // // await Promise.all(check_promises);
517
+ // // };
518
+
519
+ // // await check_results();
520
+
521
+ // return docs;
522
+ // };
523
+ // let docs = [];
524
+
525
+ // /////////////////////////////
526
+ // // check results
527
+ // /////////////////////////////
528
+ // const recheck_results = async function (doc, check_result) {
529
+ // return new Promise(async (resolve, reject) => {
530
+ // if (!doc?.properties?.docType) reject();
531
+
532
+ // const docs = await run(`fix error:${JSON.stringify(check_result.check_errors)} for:${JSON.stringify(doc)}`, doc.properties.docType);
533
+
534
+ // let progs = {};
535
+
536
+ // let studio_nodes = await project_db.view('xuda', 'studio_nodes', {});
537
+ // for (const doc of studio_nodes.rows) {
538
+ // progs[doc.value._id] = doc.value;
539
+ // }
540
+
541
+ // for (const doc of docs) {
542
+ // const check_result = check(doc);
543
+ // progs[doc._id] = doc;
544
+
545
+ // if (!check_result.check_errors.length) resolve(doc);
546
+ // }
547
+ // });
548
+ // };
549
+ // const check_results = async function (docs) {
550
+ // let progs = {};
551
+
552
+ // let studio_nodes = await project_db.view('xuda', 'studio_nodes', {});
553
+ // for (const doc of studio_nodes.rows) {
554
+ // progs[doc.value._id] = doc.value;
555
+ // }
556
+
557
+ // init(app_obj, progs, _, true, null, null, UglifyJS, JSON5, _conf, true);
558
+
559
+ // let check_promises = [];
560
+ // for (const doc of docs) {
561
+ // check_promises.push(
562
+ // new Promise(async (resolve, reject) => {
563
+ // const d = Date.now();
564
+ // if (doc.studio_meta) {
565
+ // doc.studio_meta.source = 'studio ai';
566
+ // }
567
+ // doc.stat = 3;
568
+ // doc.docType = 'studio';
569
+ // doc.docDate = d;
570
+ // doc.ts = d;
571
+ // doc.order_ts = d;
572
+ // doc.app_id = app_id;
573
+ // // progs[doc._id] = doc;
574
+
575
+ // const check_result = check(doc);
576
+ // progs[doc._id] = doc;
577
+ // // check_results[doc._id] = { check_result, doc };
578
+ // if (!check_result.check_errors.length) resolve();
579
+
580
+ // console.error(check_result.check_errors);
581
+ // doc = await recheck_results(doc, check_result);
582
+ // resolve();
583
+ // // doc = await run(`fix error:${JSON.stringify(check_result.check_errors)} for:${JSON.stringify(doc)}`);
584
+ // // result = await run(user_prompt + ' ' + JSON.stringify(check_result.check_errors) + ' ' + result.finalOutput);
585
+ // // throw new Error(`check errors`, { cause: { check_result: check_result.check_errors, result: result.finalOutput } });
586
+ // }),
587
+ // );
588
+ // // console.log('check_studio_doc_tool >>>> ', check_result);
589
+ // }
590
+
591
+ // await Promise.all(check_promises);
592
+ // };
593
+
594
+ // try {
595
+ // docs = await run(user_prompt, object_unit);
596
+ // await check_results(docs);
597
+ // } catch (err) {
598
+ // switch (err.message) {
599
+ // case 'result parse error': {
600
+ // docs = await run(user_prompt + ' ' + err.message + ' ### OUTPUT: Array of objects, each object represents a table structure, only the valid JSON array of objects. Do not add comments, explanation, or formatting. No markdown blocks.', object_unit);
601
+ // break;
602
+ // }
603
+ // case 'check errors': {
604
+ // docs = await run(user_prompt + ' ### FIX ERRORS' + JSON.stringify(err.cause.check_result) + ' ' + err.cause.result);
605
+ // break;
606
+ // }
607
+ // default:
608
+ // throw new Error(err.message);
609
+ // break;
610
+ // }
611
+ // }
612
+ // // console.log('>>>>> AI:', result.finalOutput);
613
+
614
+ // /////////////////////////////
615
+ // // save results
616
+ // /////////////////////////////
617
+ // try {
618
+ // for (const doc of docs) {
619
+ // const res = await project_db.insert(doc);
620
+ // console.log('saved:', res);
621
+ // }
622
+ // } catch (err) {
623
+ // throw new Error('save result error', { cause: err });
624
+ // }
625
+
626
+ // // for (const [id, prog] of Object.entries(progs)) {
627
+ // // const check_result = check(prog);
628
+ // // console.log('check_studio_doc_tool >>>> ', check_result);
629
+ // // }
630
+
631
+ // // console.log('>>>>> AI:', result.history);
632
+
633
+ // return { code: 1, data: docs };
634
+ // } catch (err) {
635
+ // console.error('>>>>> AI:', err);
636
+ // console.error('Cause:', err?.cause?.message);
637
+ // return { code: -1, data: err.message };
638
+ // }
639
+ // };
640
+
641
+ export const submit_agentic_studio_chat_gpt_prompt = async function (req) {
642
+ try {
643
+ const { user_prompt, object_unit, uid, app_id } = req;
644
+ const model = 'gpt-4o'; //'gpt-4.1'; //
645
+ const db = get_xuda_couch('xuda_master');
646
+
647
+ const app_obj = await db.get(app_id);
648
+ const project_db = get_xuda_couch(app_obj.app_db_name);
649
+
650
+ // let check_results = {};
651
+ const auth = async function () {
652
+ if (app_obj.app_uId !== uid) {
653
+ const db_team = get_xuda_couch('xuda_team');
654
+ let master_auth_users = await db_team.view('xuda', 'user_active_shares', {
655
+ key: [uid, app_id],
656
+ });
657
+ if (!master_auth_users.rows.includes(uid)) {
658
+ throw new Error('user unauthorized');
659
+ }
660
+ }
661
+ };
662
+
663
+ await auth();
664
+
665
+ const get_app_instructions = function () {
666
+ return `
667
+ ### context ###
668
+ uid=${uid}
669
+ app_id=${app_id}
670
+
671
+ ### Persona & Role ###
672
+ - You are a helpful and professional technical assistant named ${object_unit} builder.
673
+
674
+ ### Tasks ###
675
+
676
+ Your job is to assist the user with creating a ${user_prompt} that includes all tasks needed.
677
+
678
+
679
+ ### workflow ###
680
+
681
+ Steps:
682
+ 1. list all the tables needed for the task.
683
+ 2. prefix each table with the subject of the ${user_prompt} (e.g: CRM - Tasks).
684
+ 3. iterate the table list and build tables array using the Table builder tool, add the Table builder tool results and the table name in array RESULTS_ARR.
685
+
686
+
687
+ ### Additional information ###
688
+
689
+
690
+
691
+ ### Output ###
692
+ return the RESULTS_ARR Array.
693
+
694
+ ### Examples ###
695
+
696
+ `;
697
+ };
698
+
699
+ const get_table_instructions = function () {
700
+ return `
701
+ ### context ###
702
+ uid=${uid}
703
+ app_id=${app_id}
704
+
705
+ ### Persona & Role ###
706
+ - You are a helpful and professional technical assistant named ${object_unit} builder.
707
+
708
+ ### Tasks ###
709
+
710
+ Your job is to assist the user with creating a ${user_prompt} that includes a full set of fields according to the provided ${object_unit} structure.
711
+
712
+ - You must include all relevant fields a typical ${user_prompt} would require
713
+ - Add **multiple entries** in the "tableFields" array as needed to fully represent the structure.
714
+ - Follow the format and conventions shown in the ${object_unit} structure example.
715
+ - use uid for "createdByUid" and "checkedInUserId"
716
+
717
+ ### workflow ###
718
+
719
+ Steps:
720
+ 1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
721
+ 2. Get the ${object_unit} structure example from ### Structure and Examples ### section.
722
+ 3. Build the ${object_unit} and validate against vs_68af4c84631c81919709268c2d0f1687
723
+ 4. Use check_studio_doc_tool to check the ${object_unit} send the ${object_unit} as the doc, fix the issues if needed. if the check fail for 3 times the throw error, skip create_app_doc_tool if errors exist
724
+ 5. Use create_app_doc_tool to save the ${object_unit} doc and update the result in save_result variable,NEVER save if errors exist after check_studio_doc_tool
725
+
726
+
727
+ ### Additional information ###
728
+ ${studio_units[`studio_${object_unit}`].short}
729
+
730
+
731
+
732
+
733
+ ### Output ###
734
+ if success: {code:1,data:save_result}
735
+ if fail: {code:-1,data:error}
736
+ `;
737
+ };
738
+
739
+ const get_folder_instructions = function () {
740
+ return `
741
+ ### context ###
742
+ uid=${uid}
743
+ app_id=${app_id}
744
+
745
+ ### Persona & Role ###
746
+ - You are a helpful and professional technical assistant named ${object_unit} builder.
747
+
748
+ ### Tasks ###
749
+
750
+ Your job is to assist the user with creating a ${user_prompt}.
751
+
752
+ - Follow the format and conventions shown in the ${object_unit} structure example.
753
+ - use uid for "createdByUid" and "checkedInUserId"
754
+
755
+ ### workflow ###
756
+
757
+ Steps:
758
+ 1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
759
+ 2. Get the ${object_unit} structure example from ### Structure and Examples ### section.
760
+ 3. Build the ${object_unit} and validate against vs_68af4c84631c81919709268c2d0f1687
761
+ 4. Use check_studio_doc_tool to check the ${object_unit} send the ${object_unit} as the doc, fix the issues if needed. if the check fail for 3 times the throw error, skip create_app_doc_tool if errors exist
762
+ 5. Use create_app_doc_tool to save the ${object_unit} doc and update the result in save_result variable,NEVER save if errors exist after check_studio_doc_tool
763
+
764
+
765
+ ### Additional information ###
766
+ ${studio_units[`studio_${object_unit}`].short}
767
+
768
+
769
+ ### Output ###
770
+ if success: {code:1,data:save_result}
771
+ if fail: {code:-1,data:error}
772
+ `;
773
+ };
774
+
775
+ const get_component_instructions = function () {
776
+ return `
777
+ ### context ###
778
+ uid=${uid}
779
+ app_id=${app_id}
780
+
781
+ ### Persona & Role ###
782
+ - You are a helpful and professional technical assistant named ${object_unit} builder.
783
+
784
+ ### Tasks ###
785
+
786
+ Your job is to assist the user with creating a ${user_prompt} that includes modern ui using Tailwind
787
+
788
+ - You must include all relevant fields a typical ${user_prompt} would require
789
+
790
+ - Follow the format and conventions shown in the ${object_unit} structure example.
791
+ - use uid for "createdByUid" and "checkedInUserId"
792
+
793
+ ### workflow ###
794
+
795
+ Steps:
796
+ 1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
797
+
798
+ 2. use ### Structure and Examples ### section to build the object
799
+ 3. Use check_studio_doc_tool to check the ${object_unit} send the ${object_unit} as the doc, fix the issues if needed. if the check fail for 10 times the throw error, skip create_app_doc_tool if errors exist
800
+ 4. Use create_app_doc_tool to save the ${object_unit} doc and update the result in save_result variable,NEVER save if errors exist after check_studio_doc_tool
801
+
802
+
803
+ ### Additional information ###
804
+ ${studio_units[`studio_${object_unit}`].short}
805
+
806
+ ### Structure and Examples ###
807
+
808
+ {
809
+ // ------------------------------------------------------------------
810
+ // ## Top-Level Fields
811
+ // _id: Unique identifier for the component object.
812
+ // app_id: Reference to the associated application.
813
+ // stat: Status code: 1 = draft, 2 = pending, 3 = active, 4 = archived.
814
+ // docType: Always "studio". Indicates Studio-authored object.
815
+ // docDate: Timestamp of creation.
816
+ // ts: Timestamp of last modification.
817
+ // order_ts: Timestamp for ordering in the Studio interface.
818
+ // ------------------------------------------------------------------
819
+ "_id": "5b1_cmp_fa6170154ac9",
820
+ "app_id": "prj4937fb6f9a31c8c7dea25055bba845b1",
821
+ "stat": 3,
822
+ "docType": "studio",
823
+ "docDate": 1737616129888,
824
+ "ts": 1744009716099,
825
+ "order_ts": 1737616129888,
826
+
827
+ // ------------------------------------------------------------------
828
+ // ## studio_meta Object
829
+ // created: Creation timestamp.
830
+ // createdByUid: User ID of the creator.
831
+ // checkedInUserId: Last user who checked in the component.
832
+ // checkedInUserName: Username of the last person who modified.
833
+ // savedByUid: User who last saved the object.
834
+ // parentId: Default is "programs", but can be any parent container.
835
+ // ui_preview_sizes: Optional UI preview layout hints for visual editors.
836
+ // ------------------------------------------------------------------
837
+ "studio_meta": {
838
+ "created": 1737616129888,
839
+ "createdByUid": "acc_341cf2d32991a68e4d8aaba6c16e1",
840
+ "checkedInUserId": "acc_341cf2d32991a68e4d8aaba6c16e1",
841
+ "checkedInUserName": "Ioshka Media",
842
+ "savedByUid": "acc_341cf2d32991a68e4d8aaba6c16e1",
843
+ "parentId": "programs",
844
+ "ui_preview_sizes": {
845
+ "w": 881,
846
+ "h": 306,
847
+ "l": 84.5,
848
+ "t": 100
849
+ }
850
+ },
851
+
852
+ // ------------------------------------------------------------------
853
+ // ## properties Object
854
+ // menuType: Always "component". Defines object category.
855
+ // menuName: Internal name shown in the Studio UI.
856
+ // menuTitle: Title for Studio display or routing usage.
857
+ // renderType: Describes the component layout type ("form", "grid", etc).
858
+ // rwMode: Access mode: R, W, or RW.
859
+ // uiFramework: Selected UI framework plugin.
860
+ // progParams: Parameter interface (input/output declarations).
861
+ // frameworkProperties: Framework-specific rendering extensions.
862
+ // ------------------------------------------------------------------
863
+ "properties": {
864
+ "menuType": "component",
865
+ "menuName": "Student Classes",
866
+ "renderType": "form",
867
+ "rwMode": "R",
868
+ "uiFramework": "@xuda.io/xuda-framework-plugin-tailwind",
869
+ "menuTitle": "Student Classes",
870
+ "progParams": [
871
+ {
872
+ "data": {
873
+ "dir": "out",
874
+ "parameter": "selected_school_out",
875
+ "type": "string"
876
+ },
877
+ "id": 1733734768640,
878
+ "props": {}
879
+ },
880
+ {
881
+ "data": {
882
+ "dir": "in",
883
+ "parameter": "school_id_in",
884
+ "type": "string"
885
+ },
886
+ "id": 1734366389484,
887
+ "props": {}
888
+ }
889
+ ],
890
+ "frameworkProperties": {}
891
+ },
892
+
893
+ // ------------------------------------------------------------------
894
+ // ## progFields Array
895
+ // Defines internal fields used by the component.
896
+ // Each entry includes:
897
+ // - field_id: The unique field name.
898
+ // - type: Either virtual or physical.
899
+ // - props.fieldType: The type of data held.
900
+ // - workflow: Workflow triggers associated with field changes.
901
+ // ------------------------------------------------------------------
902
+ "progFields": [
903
+ {
904
+ "id": "0f427e15-ced7-487d-a0c4-393781cbecca",
905
+ "data": { "type": "virtual", "field_id": "selected_class_v" },
906
+ "props": { "fieldType": "string", "propExpressions": {} },
907
+ "workflow": []
908
+ },
909
+ {
910
+ "id": "2e74a767-bdbb-4cbd-b6e0-2fd7130c2cf0",
911
+ "data": { "type": "virtual", "field_id": "show_assignment_modal_v" },
912
+ "props": { "fieldType": "boolean", "propExpressions": {} },
913
+ "workflow": []
914
+ },
915
+ {
916
+ "id": "abb16f0f-9054-4f9b-bb61-a0fb91d8b1f9",
917
+ "data": { "type": "virtual", "field_id": "SELECTED_ASSIGNMENT_V" },
918
+ "props": { "fieldType": "object", "propExpressions": {} },
919
+ "workflow": []
920
+ }
921
+ ],
922
+
923
+ // ------------------------------------------------------------------
924
+ // ## progEvents Array
925
+ // Functional hooks and logic tied to component lifecycle and user actions.
926
+ // Event types: on_load, on_exit, before_record, after_record,
927
+ // record_not_found, locate_not_found, screen_ready, client_interval, user_defined.
928
+ //
929
+ // Each event supports:
930
+ // - event_name: Reference name
931
+ // - condition: Optional logic to determine when to fire
932
+ // - parameters: Virtual field mapping
933
+ // - workflow: One or more actions (update, raise_event, call_modal, etc.)
934
+ // ------------------------------------------------------------------
935
+ "progEvents": [
936
+ {
937
+ "id": "38f62791-73f7-473b-9e4e-1a58c8100b4e",
938
+ "data": {
939
+ "type": "on_load",
940
+ "event_name": "Event1734435208626",
941
+ "properties": "",
942
+ "condition": "",
943
+ "parameters": []
944
+ },
945
+ "props": { "propExpressions": {} },
946
+ "workflow": [
947
+ {
948
+ "id": "1737480488134",
949
+ "data": {
950
+ "action": "raise_event",
951
+ "name": {
952
+ "properties": {},
953
+ "event": "LOAD_STUDENT_CLASSES_EVENT",
954
+ "parameters": {}
955
+ },
956
+ "enabled": true
957
+ },
958
+ "props": {}
959
+ }
960
+ ]
961
+ }
962
+ ],
963
+
964
+ // ------------------------------------------------------------------
965
+ // ## progUi Array
966
+ // The progUi property holds an array of JSON objects representing the UI,
967
+ // based on the Himalaya.js structure.
968
+ //
969
+ // Himalaya.js Base Structure Example:
970
+ // {
971
+ // "id": "root",
972
+ // "type": "element",
973
+ // "tagName": "div",
974
+ // "attributes": { "class": "container" },
975
+ // "children": [ { "type": "text", "content": "Hello World" } ]
976
+ // }
977
+ // important note for building progUi:
978
+ // 1. generate unique id using crypto for every item of the progUi (except the root node, leave the root node as is)
979
+ // 2. never use "comment" or "text" type
980
+ // 3. convert "text" type to "element" and add text property instead
981
+ // ------------------------------------------------------------------
982
+ "progUi": [
983
+ {
984
+ "id": "node-bf66ce62-b5a1-478a-a48e-61a340a1fd7d",
985
+ "type": "element",
986
+ "tagName": "xu-single-view",
987
+ "attributes": {},
988
+ "children": [
989
+ {
990
+ "type": "element",
991
+ "tagName": "select",
992
+ "attributes": {
993
+ "class": "block w-full shadow-sm sm:text-sm focus:ring-yellow-900 focus:border-yellow-900 border-gray-300 rounded-md pr-3 pl-8",
994
+ "xu-bind": "selected_school_out",
995
+ "xu-on:change": [
996
+ {
997
+ "handler": "custom",
998
+ "props": {},
999
+ "workflow": [
1000
+ {
1001
+ "id": "node-71ba0406-bdcf-4bda-be3b-de74134r417b6",
1002
+ "data": {
1003
+ "action": "raise_event",
1004
+ "name": {
1005
+ "properties": {},
1006
+ "event": "LOAD_SCHOOL_UNITS_EVENT",
1007
+ "parameters": {}
1008
+ },
1009
+ "enabled": true
1010
+ },
1011
+ "props": {}
1012
+ },
1013
+ {
1014
+ "id": "node-71ba0406-qw34-4bda-be3b-de7411a41711",
1015
+ "data": {
1016
+ "action": "raise_event",
1017
+ "name": {
1018
+ "properties": {},
1019
+ "event": "LOAD_SCHOOL_INFO_EVENT",
1020
+ "parameters": {}
1021
+ },
1022
+ "enabled": true
1023
+ },
1024
+ "props": {}
1025
+ }
1026
+ ]
1027
+ }
1028
+ ]
1029
+ },
1030
+ "children": [
1031
+ {
1032
+ "content": "בחר",
1033
+ "type": "element",
1034
+ "tagName": "option",
1035
+ "attributes": {
1036
+ "disabled": true,
1037
+ "selected": true,
1038
+ "value": ""
1039
+ },
1040
+ "children": [],
1041
+ "id": "node-43a9730d-c2b2-4b95-a386-622fe9aff8cd",
1042
+ "code": "<option disabled=\"true\" selected=\"true\" value>בחר</option>",
1043
+ "editCode": false,
1044
+ "path": [
1045
+ 0,
1046
+ 0,
1047
+ 0
1048
+ ]
1049
+ },
1050
+ {
1051
+ "type": "element",
1052
+ "tagName": "option",
1053
+ "attributes": {
1054
+ "xu-exp:xu-for": "SESSION_OBJ[@SYS_GLOBAL_STR_SESSION_ID].DS_GLB[@SYS_STR_PROG_DS_SESSION].data_feed.rows",
1055
+ "xu-exp:value": "(@_FOR_VAL).SC_Id",
1056
+ "xu-exp:xu-text": "(@_FOR_VAL).SC_Name"
1057
+ },
1058
+ "children": [],
1059
+ "id": "node-71ba0406-bdcf-4bda-be3b-de7411a417b6",
1060
+ "path": [
1061
+ 0,
1062
+ 0,
1063
+ 1
1064
+ ]
1065
+ }
1066
+ ],
1067
+ "id": "node-2e00a223-6a8c-44e5-951a-67182523d45f",
1068
+ "path": [
1069
+ 0,
1070
+ 0
1071
+ ],
1072
+ "code": "<select class=\"block w-full shadow-sm sm:text-sm focus:ring-yellow-900 focus:border-yellow-900 border-gray-300 rounded-md pr-3 pl-8\" xu-bind=\"selected_school_out\"><option xu-exp:xu-for=\"SESSION_OBJ[@SYS_GLOBAL_STR_SESSION_ID].DS_GLB[@SYS_STR_PROG_DS_SESSION].data_feed.rows\" xu-for-val xu-exp:xu-content=\"(@_FOR_VAL).SC_Name\" xu-exp:value=\"(@_FOR_VAL).SC_Id\"></option></select>",
1073
+ "editCode": false,
1074
+ "$folded": false
1075
+ }
1076
+ ],
1077
+ "path": [
1078
+ 0
1079
+ ],
1080
+ "code": "<xu-single-view><select id=\"location\" name=\"location\" class=\"block bg-transparent w-full pr-2 pl-10 py-2 text-base border-gray-300 focus:outline-none sm:text-sm rounded-md border-none focus:shadow-none focus:ring-0\" xu-bind=\"CL_Grade\"><option xu-exp:xu-for=\"@grades_v\" xu-for-val xu-exp:xu-content=\"@_FOR_VAL\"></option></select></xu-single-view>",
1081
+ "editCode": false,
1082
+ "$folded": false
1083
+ }
1084
+ ],
1085
+
1086
+ "progDataSource": {
1087
+ "dataSourceType": ""
1088
+ }
1089
+ }
1090
+
1091
+
1092
+ ### Output ###
1093
+ if success: {code:1,data:save_result}
1094
+ if fail: {code:-1,data:error}
1095
+ `;
1096
+ };
1097
+ const get_get_data_instructions = function () {
1098
+ return `
1099
+ ### context ###
1100
+ uid=${uid}
1101
+ app_id=${app_id}
1102
+
1103
+ ### Persona & Role ###
1104
+ - You are a helpful and professional technical assistant named ${object_unit} builder.
1105
+
1106
+ ### Tasks ###
1107
+
1108
+ Your job is to assist the user with creating a ${user_prompt}.
1109
+
1110
+ - You must include all relevant fields a typical ${user_prompt} would require
1111
+
1112
+ - Follow the format and conventions shown in the ${object_unit} structure example.
1113
+ - use uid for "createdByUid" and "checkedInUserId"
1114
+
1115
+ ### workflow ###
1116
+
1117
+ Steps:
1118
+ 1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
1119
+ 2. Get the ${object_unit} structure example from ### Structure and Examples ### section.
1120
+ 3. Build the ${object_unit} and validate against vs_68af4c84631c81919709268c2d0f1687
1121
+ 4. Use check_studio_doc_tool to check the ${object_unit} send the ${object_unit} as the doc, fix the issues if needed. if the check fail for 10 times the throw error, skip create_app_doc_tool if errors exist
1122
+ 5. Use create_app_doc_tool to save the ${object_unit} doc and update the result in save_result variable,NEVER save if errors exist after check_studio_doc_tool
1123
+
1124
+
1125
+ ### Additional information ###
1126
+ ${studio_units[`studio_${object_unit}`].short}
1127
+
1128
+ ### Output ###
1129
+ if success: {code:1,data:save_result}
1130
+ if fail: {code:-1,data:error}
1131
+ `;
1132
+ };
1133
+
1134
+ const get_agents_as_a_tool = function (agent_list = []) {
1135
+ let _tools = [];
1136
+ for (const agent of agent_list) {
1137
+ const _agent = new Agent(studio_agents_obj[agent]);
1138
+ const tool = _agent.asTool({
1139
+ toolName: studio_agents_obj[agent].name,
1140
+ toolDescription: `Generate a ${agent} of the supplied text.`,
1141
+ });
1142
+
1143
+ _tools.push(tool);
1144
+ }
1145
+
1146
+ return _tools;
1147
+ };
1148
+
1149
+ let studio_agents_obj = {
1150
+ app: {
1151
+ name: 'App builder',
1152
+ instructions: get_app_instructions(),
1153
+ tools: [get_user_name_tool],
1154
+ model,
1155
+ modelSettings: {
1156
+ toolChoice: 'required', // ← this enables tool use
1157
+ responseFormat: {
1158
+ text: {
1159
+ format: {
1160
+ type: 'array', // or "markdown" if needed
1161
+ },
1162
+ },
1163
+ },
1164
+ outputType: z.array(z.object()),
1165
+ },
1166
+ },
1167
+ table: {
1168
+ name: 'Table builder',
1169
+ instructions: get_table_instructions(),
1170
+ tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af473196a88191afc6610fddfe4a62')],
1171
+ model,
1172
+ modelSettings: {
1173
+ toolChoice: 'required', // ← this enables tool use
1174
+ responseFormat: {
1175
+ text: {
1176
+ format: {
1177
+ type: 'array', // or "markdown" if needed
1178
+ },
1179
+ },
1180
+ },
1181
+ outputType: z.array(
1182
+ z.object({
1183
+ _id: z.string(),
1184
+ stat: z.number(),
1185
+ docType: z.string(),
1186
+ docDate: z.number(),
1187
+ ts: z.number(),
1188
+ order_ts: z.number(),
1189
+ studio_meta: z.object({
1190
+ created: z.number(),
1191
+ createdByUid: z.string(),
1192
+ checkedInUserId: z.string(),
1193
+ savedByUid: z.string(),
1194
+ checkedInUserName: z.string(),
1195
+ parentId: z.string(),
1196
+ source: z.string(),
1197
+ }),
1198
+ properties: z.object({
1199
+ menuName: z.string(),
1200
+ menuType: z.string(),
1201
+ databaseSocket: z.string(),
1202
+ }),
1203
+ tableIndexes: z.array(
1204
+ z.object({
1205
+ id: z.string(),
1206
+ data: z.object({
1207
+ name: z.string(),
1208
+ unique: z.boolean(),
1209
+ keys: z.array(z.string()),
1210
+ }),
1211
+ }),
1212
+ ),
1213
+ tableFields: z.array(
1214
+ z.object({
1215
+ id: z.string(),
1216
+ data: z.object({
1217
+ field_id: z.string(),
1218
+ }),
1219
+ props: z.object({
1220
+ fieldType: z.string(),
1221
+ }),
1222
+ }),
1223
+ ),
1224
+ }),
1225
+ ),
1226
+ },
1227
+ },
1228
+ folder: {
1229
+ name: 'Folder builder',
1230
+ instructions: get_folder_instructions(),
1231
+ tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af44989e4881918fc8bf8e84c6ce03')],
1232
+ model: 'gpt-4o',
1233
+ modelSettings: {
1234
+ toolChoice: 'required', // ← this enables tool use
1235
+ responseFormat: {
1236
+ text: {
1237
+ format: {
1238
+ type: 'array', // or "markdown" if needed
1239
+ },
1240
+ },
1241
+ },
1242
+ outputType: z.array(
1243
+ z.object({
1244
+ _id: z.string(),
1245
+ stat: z.number(),
1246
+ docType: z.string(),
1247
+ docDate: z.number(),
1248
+ ts: z.number(),
1249
+ order_ts: z.number(),
1250
+ studio_meta: z.object({
1251
+ created: z.number(),
1252
+ createdByUid: z.string(),
1253
+ checkedInUserId: z.string(),
1254
+ savedByUid: z.string(),
1255
+ checkedInUserName: z.string(),
1256
+ parentId: z.string(),
1257
+ source: z.string(),
1258
+ }),
1259
+ properties: z.object({
1260
+ menuName: z.string(),
1261
+ menuType: z.string(),
1262
+ databaseSocket: z.string(),
1263
+ }),
1264
+ }),
1265
+ ),
1266
+ },
1267
+ },
1268
+ component: {
1269
+ name: 'Component builder',
1270
+ instructions: get_component_instructions(),
1271
+ tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool], //, fileSearchTool('vs_68af48a65cf88191a48a0f530d7e3919')
1272
+ model,
1273
+ modelSettings: {
1274
+ toolChoice: 'required', // ← this enables tool use
1275
+ responseFormat: {
1276
+ text: {
1277
+ format: {
1278
+ type: 'array', // or "markdown" if needed
1279
+ },
1280
+ },
1281
+ },
1282
+ outputType: z.array(
1283
+ z.object({
1284
+ _id: z.string(),
1285
+ stat: z.number(),
1286
+ docType: z.string(),
1287
+ docDate: z.number(),
1288
+ ts: z.number(),
1289
+ order_ts: z.number(),
1290
+ studio_meta: z.object({
1291
+ created: z.number(),
1292
+ createdByUid: z.string(),
1293
+ checkedInUserId: z.string(),
1294
+ savedByUid: z.string(),
1295
+ checkedInUserName: z.string(),
1296
+ parentId: z.string(),
1297
+ source: z.string(),
1298
+ }),
1299
+ properties: z.object({
1300
+ menuName: z.string(),
1301
+ menuType: z.string(),
1302
+ databaseSocket: z.string(),
1303
+ }),
1304
+ progDataSource: z.object({}),
1305
+ progFields: z.array(z.object({})),
1306
+ progEvents: z.array(z.object({})),
1307
+ progUi: z.array(z.object({})),
1308
+ }),
1309
+ ),
1310
+ },
1311
+ },
1312
+ get_data: {
1313
+ name: 'Get data builder',
1314
+ instructions: get_get_data_instructions(),
1315
+ tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af530d4ba081919ca57eabb5ae117a')],
1316
+ model,
1317
+ modelSettings: {
1318
+ toolChoice: 'required', // ← this enables tool use
1319
+ responseFormat: {
1320
+ text: {
1321
+ format: {
1322
+ type: 'array', // or "markdown" if needed
1323
+ },
1324
+ },
1325
+ },
1326
+ outputType: z.array(
1327
+ z.object({
1328
+ _id: z.string(),
1329
+ stat: z.number(),
1330
+ docType: z.string(),
1331
+ docDate: z.number(),
1332
+ ts: z.number(),
1333
+ order_ts: z.number(),
1334
+ studio_meta: z.object({
1335
+ created: z.number(),
1336
+ createdByUid: z.string(),
1337
+ checkedInUserId: z.string(),
1338
+ savedByUid: z.string(),
1339
+ checkedInUserName: z.string(),
1340
+ parentId: z.string(),
1341
+ source: z.string(),
1342
+ }),
1343
+ properties: z.object({
1344
+ menuName: z.string(),
1345
+ menuType: z.string(),
1346
+ databaseSocket: z.string(),
1347
+ }),
1348
+ progDataSource: z.object({}),
1349
+ progFields: z.array(z.object({})),
1350
+ progEvents: z.array(z.object({})),
1351
+ }),
1352
+ ),
1353
+ },
1354
+ },
1355
+ };
1356
+
1357
+ if (object_unit === 'app') {
1358
+ const agents_as_a_tool_arr = get_agents_as_a_tool(['table', 'folder', 'component', 'get_data']);
1359
+ studio_agents_obj.app.tools = [...studio_agents_obj.app.tools, ...agents_as_a_tool_arr];
1360
+ }
1361
+
1362
+ const run = async function (user_prompt, object_unit) {
1363
+ const _agent = new Agent(studio_agents_obj[object_unit]);
1364
+ const runner = new Runner();
1365
+
1366
+ const result = await runner.run(_agent, user_prompt, {
1367
+ context: { uid, app_id },
1368
+ });
1369
+
1370
+ return result;
1371
+ };
1372
+
1373
+ const result = await run(user_prompt, object_unit);
1374
+
1375
+ return { code: 1, data: result.finalOutput };
1376
+ } catch (err) {
1377
+ console.error('>>>>> AI:', err);
1378
+ console.error('Cause:', err?.cause?.message);
1379
+ return { code: -1, data: err.message };
1380
+ }
1381
+ };
1382
+
1383
+ export const submit_chat_gpt_prompt = async function (req) {
1384
+ try {
1385
+ const client = new OpenAI({
1386
+ apiKey: _conf.OPENAI_API_KEY,
1387
+ });
1388
+
1389
+ const response = await client.responses.create({
1390
+ model: 'gpt-5',
1391
+ input: req.prompt,
1392
+ });
1393
+
1394
+ return { code: 1, data: response.output_text };
1395
+ } catch (err) {
1396
+ return { code: -1, data: err.message };
1397
+ }
1398
+ };
1399
+
1400
+ export const create_studio_app = async function (subject) {
1401
+ try {
1402
+ let prompt = `
1403
+
1404
+ 1. list all tables and screens to build an ${subject} app.
1405
+ 2. return object array for each item (name,type,description)
1406
+
1407
+
1408
+ `;
1409
+
1410
+ const data = await submit_chat_gpt_prompt({ prompt });
1411
+
1412
+ return { code: 1, data };
1413
+ } catch (err) {
1414
+ return { code: -1, data: err.message };
1415
+ }
1416
+ };
1417
+
1418
+ setTimeout(async () => {
1419
+ // await init_studio_units();
1420
+ let ret;
1421
+ // const ret = await create_studio_app('crm');
1422
+ // ret = await submit_chat_gpt_prompt({ prompt: `hi` });
1423
+ // const ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'crm app', object_unit: 'app', uid: 'd39126e0e2c51ffbd1aad10709fc8335', app_id: 'prjac771215b7a70d86bc3a8435bb18c885' });
1424
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'products', object_unit: 'table', uid: 'd39126e0e2c51ffbd1aad10709fc8335', app_id: 'prjac771215b7a70d86bc3a8435bb18c885' });
1425
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'test3', object_unit: 'folder', uid: 'd39126e0e2c51ffbd1aad10709fc8335', app_id: 'prjac771215b7a70d86bc3a8435bb18c885' });
1426
+ ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'contact form', object_unit: 'component', uid: 'd39126e0e2c51ffbd1aad10709fc8335', app_id: 'prjac771215b7a70d86bc3a8435bb18c885' });
1427
+ // ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'get data from tasks by task id', object_unit: 'get_data', uid: 'd39126e0e2c51ffbd1aad10709fc8335', app_id: 'prjac771215b7a70d86bc3a8435bb18c885' });
1428
+ console.log(ret);
1429
+ // console.log(
1430
+ // check(
1431
+ // createDoc({
1432
+ // uid: '11',
1433
+ // app_id: 'prj-444',
1434
+ // menuType: 'folder',
1435
+ // checkedInUserName: 'boaz',
1436
+ // parentId: '',
1437
+ // }),
1438
+ // ),
1439
+ // );
1440
+ }, 1000);
1441
+
1442
+ // PROMPT OBJECT UNIT OUTPUT
1443
+ //================================================================== ==================== =====================
1444
+ // create customer table
1445
+ // fill 5 rows to customer table
1446
+ // describe the customer table
1447
+ // create router for the app
1448
+ // create form program and save the data in the customer table
1449
+ // generate 10 buttons using tailwind
1450
+ // describe the program
1451
+ // create crm app
1452
+ // change text color
1453
+ // fetch only new customers using mongo query
1454
+ // create dashboard program for crm app
1455
+ // find diffs between two objects