@xuda.io/ai_module 1.1.5617 → 1.1.5619
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/.env +1 -0
- package/.sitework/boaz-wiki/assets/boaz-avrahami.png +0 -0
- package/.sitework/boaz-wiki/assets/favicon-180.png +0 -0
- package/.sitework/boaz-wiki/assets/favicon-32.png +0 -0
- package/.sitework/boaz-wiki/assets/favicon.ico +0 -0
- package/.sitework/boaz-wiki/assets/site.js +47 -0
- package/.sitework/boaz-wiki/assets/styles.css +563 -0
- package/.sitework/boaz-wiki/index.html +847 -0
- package/.tmp_boaz_site/assets/boaz-avrahami.png +0 -0
- package/.tmp_boaz_site/assets/site.js +47 -0
- package/.tmp_boaz_site/assets/styles.css +278 -0
- package/.tmp_boaz_site/index.html +845 -0
- package/build_boaz_wiki.py +601 -0
- package/globals.mjs +6 -0
- package/gpt.mjs +155 -0
- package/index copy 2.js +2129 -0
- package/index copy.js +1455 -0
- package/index old.mjs +423 -0
- package/index.js +3751 -0
- package/index_ms.mjs +8 -8
- package/index_msa.mjs +12 -8
- package/package.json +1 -1
- package/test.mjs +2 -0
- package/un-used.mjs +1437 -0
package/index copy 2.js
ADDED
|
@@ -0,0 +1,2129 @@
|
|
|
1
|
+
console.log('AI Module loaded...');
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
7
|
+
import sharp from 'sharp';
|
|
8
|
+
|
|
9
|
+
const { readFile, unlink, writeFile } = fs.promises;
|
|
10
|
+
|
|
11
|
+
// global._common = JSON.parse(await fs.readFile(path.join(process.env.XUDA_HOME, 'common', 'xuda_node_common.mjs'), 'utf-8'));
|
|
12
|
+
global._conf = JSON.parse(await readFile(path.join(process.env.XUDA_HOME, process.env.XUDA_CONFIG), 'utf-8'));
|
|
13
|
+
|
|
14
|
+
const module_path = path.join(process.env.XUDA_HOME, 'cpi') + (!_conf.is_debug ? '/node_modules/@xuda.io' : '');
|
|
15
|
+
const runtime_modules_path = path.join(process.env.XUDA_HOME, 'dist', 'runtime', 'js', 'modules');
|
|
16
|
+
|
|
17
|
+
import { Agent, Runner, tool, setDefaultOpenAIKey, RunContext, fileSearchTool, webSearchTool } from '@openai/agents';
|
|
18
|
+
import OpenAI, { toFile } from 'openai';
|
|
19
|
+
|
|
20
|
+
setDefaultOpenAIKey(_conf.OPENAI_API_KEY);
|
|
21
|
+
|
|
22
|
+
import _ from 'lodash';
|
|
23
|
+
import JSON5 from 'json5';
|
|
24
|
+
import UglifyJS from 'uglify-js';
|
|
25
|
+
|
|
26
|
+
const { get_xuda_couch } = await import(`${module_path}/db_module/index.es.mjs`);
|
|
27
|
+
const { createDoc, valid_menuType } = await import(`${runtime_modules_path}/xuda-studio-doc-utils.mjs`);
|
|
28
|
+
const { init, check, check_structure, get_zod_schema } = await import(`${runtime_modules_path}/xuda-studio-checker.mjs`);
|
|
29
|
+
|
|
30
|
+
let client;
|
|
31
|
+
try {
|
|
32
|
+
client = new OpenAI({
|
|
33
|
+
apiKey: _conf.OPENAI_API_KEY,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('chat-gpt client initiated..OK');
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
}
|
|
40
|
+
const model = 'ft:gpt-4o-2024-08-06:xuda-io:xuda:CC4aHCsz';
|
|
41
|
+
|
|
42
|
+
var studio_units = {};
|
|
43
|
+
|
|
44
|
+
const init_studio_units = async function () {
|
|
45
|
+
try {
|
|
46
|
+
const db = get_xuda_couch('xuda_website');
|
|
47
|
+
const ret = await db.find({ selector: { type: 'app_builder' } });
|
|
48
|
+
for (const doc of ret.docs) {
|
|
49
|
+
studio_units[doc._id] = doc;
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.error(err);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
await init_studio_units();
|
|
57
|
+
|
|
58
|
+
const get_user_name_tool = tool({
|
|
59
|
+
name: 'get_user_name_tool',
|
|
60
|
+
description: 'Get the user name by uid',
|
|
61
|
+
parameters: z.object({
|
|
62
|
+
uid: z.string(),
|
|
63
|
+
}),
|
|
64
|
+
async execute(e, RunContext) {
|
|
65
|
+
try {
|
|
66
|
+
const db = get_xuda_couch('xuda_accounts');
|
|
67
|
+
const doc = await db.get(e.uid);
|
|
68
|
+
let username = 'unknown';
|
|
69
|
+
if (doc?.account_info) {
|
|
70
|
+
username = doc.account_info.first_name + ' ' + doc.account_info.last_name;
|
|
71
|
+
|
|
72
|
+
if (!username) {
|
|
73
|
+
username = +doc.account_info.email;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return username;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
return 'unknown';
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const create_initial_studio_doc_tool = tool({
|
|
85
|
+
name: 'Create initial studio doc tool',
|
|
86
|
+
description: 'I am responsible to create initial doc for the studio',
|
|
87
|
+
parameters: z.object({
|
|
88
|
+
uid: z.string().describe('the user id'),
|
|
89
|
+
app_id: z.string().describe('the app id'),
|
|
90
|
+
menuType: z.enum(valid_menuType).describe('the studio doc type'),
|
|
91
|
+
checkedInUserName: z.string().describe('the name of check-in user'),
|
|
92
|
+
parentId: z.string().describe('the doc id of the parent doc'),
|
|
93
|
+
}),
|
|
94
|
+
async execute(e, RunContext) {
|
|
95
|
+
// console.log('create_initial_studio_doc_tool >>>> ', e);
|
|
96
|
+
const { uid, menuType, checkedInUserName, app_id, parentId } = e;
|
|
97
|
+
try {
|
|
98
|
+
const doc = createDoc({ uid, properties: { menuType }, checkedInUserName, app_id, parentId });
|
|
99
|
+
|
|
100
|
+
return doc;
|
|
101
|
+
} catch (err) {
|
|
102
|
+
return 'unknown';
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const check_studio_doc_tool = tool({
|
|
108
|
+
name: 'Check studio doc',
|
|
109
|
+
description: 'I am responsible to check and validate studio doc',
|
|
110
|
+
parameters: z.object({
|
|
111
|
+
app_id: z.string().describe('the app id'),
|
|
112
|
+
doc: z.string().describe('the studio doc to validate for table,globals,components and more'),
|
|
113
|
+
}),
|
|
114
|
+
async execute(e, RunContext) {
|
|
115
|
+
try {
|
|
116
|
+
const doc = JSON5.parse(e.doc);
|
|
117
|
+
let progs = {};
|
|
118
|
+
|
|
119
|
+
const db = get_xuda_couch('xuda_master');
|
|
120
|
+
const app_obj = await db.get(e.app_id);
|
|
121
|
+
const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
122
|
+
let studio_nodes = await project_db.view('xuda', 'studio_nodes', {});
|
|
123
|
+
for (const doc of studio_nodes.rows) {
|
|
124
|
+
progs[doc.value._id] = doc.value;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
init(app_obj, progs, _, true, null, null, UglifyJS, JSON5, _conf, true, z);
|
|
128
|
+
let result = check(doc);
|
|
129
|
+
console.log('check_studio_doc_tool >>>> ', result.check_errors, e.doc);
|
|
130
|
+
delete result.doc;
|
|
131
|
+
return result;
|
|
132
|
+
} catch (err) {
|
|
133
|
+
console.error(err);
|
|
134
|
+
return err.message;
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const get_plugins = tool({
|
|
140
|
+
name: 'Get plugins',
|
|
141
|
+
description: 'I am responsible to return all available plugins',
|
|
142
|
+
parameters: z.object({}),
|
|
143
|
+
async execute(e, RunContext) {
|
|
144
|
+
try {
|
|
145
|
+
const db = get_xuda_couch('xuda_plugins');
|
|
146
|
+
const plugins_res = await db.view('xuda', 'all-active-plugins', {});
|
|
147
|
+
let data = [];
|
|
148
|
+
if (!_.isEmpty(plugins_res.rows)) {
|
|
149
|
+
for (val of plugins_res.rows) {
|
|
150
|
+
if (!['library', 'widget', 'ui'].includes(val.plugin_type)) continue;
|
|
151
|
+
var plugin = _.clone(val.value);
|
|
152
|
+
delete plugin.account_id;
|
|
153
|
+
delete plugin.manifest;
|
|
154
|
+
delete plugin.plugin_name;
|
|
155
|
+
delete plugin.setup;
|
|
156
|
+
delete plugin.stat;
|
|
157
|
+
delete plugin.updated_date;
|
|
158
|
+
plugin._id = plugin._id.replace('@xuda.io/', '');
|
|
159
|
+
|
|
160
|
+
data.push(plugin);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log('get_plugins >>>> ', data);
|
|
165
|
+
return data;
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error(err);
|
|
168
|
+
return err.message;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const create_app_doc_tool = tool({
|
|
174
|
+
name: 'save project doc tool',
|
|
175
|
+
description: 'Save doc (such as table,component,set_data,get_data,alert,batch,globals,route,database) to the project to db',
|
|
176
|
+
parameters: z.object({
|
|
177
|
+
app_id: z.string(),
|
|
178
|
+
doc: z.string(), // z.object({}), // _id
|
|
179
|
+
}),
|
|
180
|
+
async execute(e, RunContext) {
|
|
181
|
+
try {
|
|
182
|
+
const doc = JSON5.parse(e.doc);
|
|
183
|
+
|
|
184
|
+
const db = get_xuda_couch('xuda_master');
|
|
185
|
+
const app_obj = await db.get(e.app_id);
|
|
186
|
+
const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
187
|
+
|
|
188
|
+
const result = await project_db.insert(doc);
|
|
189
|
+
console.log('create_app_doc_tool >>>> ', result);
|
|
190
|
+
return result;
|
|
191
|
+
} catch (err) {
|
|
192
|
+
console.error(err);
|
|
193
|
+
return err.message;
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const update_app_doc_tool = tool({
|
|
199
|
+
name: 'update app doc tool',
|
|
200
|
+
description: 'update any app doc query by _id and _rev and save to the app db',
|
|
201
|
+
parameters: z.object({
|
|
202
|
+
app_id: z.string(),
|
|
203
|
+
doc: z.object({ _id: z.string(), _rev: z.string() }),
|
|
204
|
+
}),
|
|
205
|
+
async execute(e, RunContext) {
|
|
206
|
+
console.log(`SAVED ${e.app_id}`);
|
|
207
|
+
return `OK`;
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const get_app_doc_tool = tool({
|
|
212
|
+
name: 'get app doc tool',
|
|
213
|
+
description: 'get any doc by id from the app db',
|
|
214
|
+
parameters: z.object({
|
|
215
|
+
app_id: z.string(),
|
|
216
|
+
_id: z.string(),
|
|
217
|
+
}),
|
|
218
|
+
async execute(e, RunContext) {
|
|
219
|
+
try {
|
|
220
|
+
const db = get_xuda_couch('xuda_master');
|
|
221
|
+
const app_obj = await db.get(e.app_id);
|
|
222
|
+
const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
223
|
+
|
|
224
|
+
const result = await project_db.get(_id);
|
|
225
|
+
console.log('get_app_doc_tool >>>> ', result);
|
|
226
|
+
return result;
|
|
227
|
+
} catch (err) {
|
|
228
|
+
console.error(err);
|
|
229
|
+
return err.message;
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const get_additional_information_tool = tool({
|
|
235
|
+
name: 'get additional information tool',
|
|
236
|
+
description: 'get additional information for object unit tool',
|
|
237
|
+
parameters: z.object({
|
|
238
|
+
object_unit: z.enum(['table']),
|
|
239
|
+
}),
|
|
240
|
+
async execute(e, RunContext) {
|
|
241
|
+
let obj = { table: ['studio_table'] };
|
|
242
|
+
const db = get_xuda_couch('xuda_website');
|
|
243
|
+
try {
|
|
244
|
+
if (!obj[e.object_unit]) throw new Error(`${e.object_unit} not found`);
|
|
245
|
+
const doc = await db.get(obj[e.object_unit]);
|
|
246
|
+
// console.log(`INFO ${doc}`);
|
|
247
|
+
return doc.md || doc;
|
|
248
|
+
} catch (err) {
|
|
249
|
+
console.error(err);
|
|
250
|
+
return err.message;
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
export const submit_agentic_studio_chat_gpt_prompt = async function (req) {
|
|
256
|
+
try {
|
|
257
|
+
const { user_prompt, object_unit, uid, app_id } = req;
|
|
258
|
+
const model = 'ft:gpt-4o-2024-08-06:personal:xuda:CAbDtO0p'; // 'gpt-4o'; //'gpt-4.1'; //
|
|
259
|
+
const db = get_xuda_couch('xuda_master');
|
|
260
|
+
|
|
261
|
+
const app_obj = await db.get(app_id);
|
|
262
|
+
const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
263
|
+
|
|
264
|
+
// let check_results = {};
|
|
265
|
+
const auth = async function () {
|
|
266
|
+
if (app_obj.app_uId !== uid) {
|
|
267
|
+
const db_team = get_xuda_couch('xuda_team');
|
|
268
|
+
let master_auth_users = await db_team.view('xuda', 'user_active_shares', {
|
|
269
|
+
key: [uid, app_id],
|
|
270
|
+
});
|
|
271
|
+
if (!master_auth_users.rows.includes(uid)) {
|
|
272
|
+
throw new Error('user unauthorized');
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
await auth();
|
|
278
|
+
|
|
279
|
+
const get_zod_unit_schema = function (type) {
|
|
280
|
+
init(app_obj, {}, _, true, null, null, UglifyJS, JSON5, _conf, false, z);
|
|
281
|
+
const schema = get_zod_schema(type);
|
|
282
|
+
const jsonSchema = zodToJsonSchema(schema);
|
|
283
|
+
return JSON.stringify(jsonSchema, null, 2);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const get_app_instructions = function () {
|
|
287
|
+
return `
|
|
288
|
+
### context ###
|
|
289
|
+
uid=${uid}
|
|
290
|
+
app_id=${app_id}
|
|
291
|
+
|
|
292
|
+
### Persona & Role ###
|
|
293
|
+
- You are a helpful and professional technical assistant named ${object_unit} builder.
|
|
294
|
+
|
|
295
|
+
### Tasks ###
|
|
296
|
+
|
|
297
|
+
Your job is to assist the user with creating a ${user_prompt} that includes all tasks needed.
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
### workflow ###
|
|
301
|
+
|
|
302
|
+
Steps:
|
|
303
|
+
1. list all the tables needed for the task.
|
|
304
|
+
2. prefix each table with the subject of the ${user_prompt} (e.g: CRM - Tasks).
|
|
305
|
+
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.
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
### Additional information ###
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
### Output ###
|
|
313
|
+
return the RESULTS_ARR Array.
|
|
314
|
+
|
|
315
|
+
### Examples ###
|
|
316
|
+
|
|
317
|
+
`;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const get_table_instructions = function () {
|
|
321
|
+
return `
|
|
322
|
+
### context ###
|
|
323
|
+
uid=${uid}
|
|
324
|
+
app_id=${app_id}
|
|
325
|
+
|
|
326
|
+
### Persona & Role ###
|
|
327
|
+
- You are a helpful and professional technical assistant named ${object_unit} builder.
|
|
328
|
+
|
|
329
|
+
### Tasks ###
|
|
330
|
+
|
|
331
|
+
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.
|
|
332
|
+
|
|
333
|
+
- You must include all relevant fields a typical ${user_prompt} would require
|
|
334
|
+
- Add **multiple entries** in the "tableFields" array as needed to fully represent the structure.
|
|
335
|
+
- Follow the format and conventions shown in the ${object_unit} structure example.
|
|
336
|
+
- use uid for "createdByUid" and "checkedInUserId"
|
|
337
|
+
|
|
338
|
+
### workflow ###
|
|
339
|
+
|
|
340
|
+
Steps:
|
|
341
|
+
1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
|
|
342
|
+
|
|
343
|
+
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 3 times the throw error, skip create_app_doc_tool if errors exist
|
|
344
|
+
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
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
### Output ###
|
|
351
|
+
if success: {code:1,data:save_result}
|
|
352
|
+
if fail: {code:-1,data:error}
|
|
353
|
+
`;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
const get_folder_instructions = function () {
|
|
357
|
+
return `
|
|
358
|
+
### context ###
|
|
359
|
+
uid=${uid}
|
|
360
|
+
app_id=${app_id}
|
|
361
|
+
|
|
362
|
+
### Persona & Role ###
|
|
363
|
+
- You are a helpful and professional technical assistant named ${object_unit} builder.
|
|
364
|
+
|
|
365
|
+
### Tasks ###
|
|
366
|
+
|
|
367
|
+
Your job is to assist the user with creating a ${user_prompt}.
|
|
368
|
+
|
|
369
|
+
- Follow the format and conventions shown in the ${object_unit} structure example.
|
|
370
|
+
- use uid for "createdByUid" and "checkedInUserId"
|
|
371
|
+
|
|
372
|
+
### workflow ###
|
|
373
|
+
|
|
374
|
+
Steps:
|
|
375
|
+
1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
|
|
376
|
+
2. Get the ${object_unit} structure example from ### Structure and Examples ### section.
|
|
377
|
+
3. Build the ${object_unit} and validate against vs_68af4c84631c81919709268c2d0f1687
|
|
378
|
+
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
|
|
379
|
+
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
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
### Additional information ###
|
|
383
|
+
${studio_units[`studio_${object_unit}`].short}
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
### Output ###
|
|
387
|
+
if success: {code:1,data:save_result}
|
|
388
|
+
if fail: {code:-1,data:error}
|
|
389
|
+
`;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const get_component_instructions = function () {
|
|
393
|
+
return `
|
|
394
|
+
### context ###
|
|
395
|
+
uid=${uid}
|
|
396
|
+
app_id=${app_id}
|
|
397
|
+
|
|
398
|
+
### Persona & Role ###
|
|
399
|
+
- You are a helpful and professional technical assistant named ${object_unit} builder.
|
|
400
|
+
|
|
401
|
+
### Tasks ###
|
|
402
|
+
|
|
403
|
+
Your job is to assist the user with creating a ${user_prompt} that includes modern ui using Tailwind
|
|
404
|
+
|
|
405
|
+
- You must include all relevant fields a typical ${user_prompt} would require
|
|
406
|
+
|
|
407
|
+
- Follow the format and conventions shown in the ${object_unit} structure example.
|
|
408
|
+
- use uid for "createdByUid" and "checkedInUserId"
|
|
409
|
+
|
|
410
|
+
### workflow ###
|
|
411
|
+
|
|
412
|
+
Steps:
|
|
413
|
+
1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
|
|
414
|
+
|
|
415
|
+
2. use ### Structure and Examples ### section to build the object
|
|
416
|
+
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
|
|
417
|
+
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
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
### Additional information ###
|
|
421
|
+
${studio_units[`studio_${object_unit}`].short}
|
|
422
|
+
|
|
423
|
+
### Structure and Examples ###
|
|
424
|
+
|
|
425
|
+
${get_zod_unit_schema('component')}
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
### Output ###
|
|
431
|
+
if success: {code:1,data:save_result}
|
|
432
|
+
if fail: {code:-1,data:error}
|
|
433
|
+
`;
|
|
434
|
+
};
|
|
435
|
+
const get_get_data_instructions = function () {
|
|
436
|
+
return `
|
|
437
|
+
### context ###
|
|
438
|
+
uid=${uid}
|
|
439
|
+
app_id=${app_id}
|
|
440
|
+
|
|
441
|
+
### Persona & Role ###
|
|
442
|
+
- You are a helpful and professional technical assistant named ${object_unit} builder.
|
|
443
|
+
|
|
444
|
+
### Tasks ###
|
|
445
|
+
|
|
446
|
+
Your job is to assist the user with creating a ${user_prompt}.
|
|
447
|
+
|
|
448
|
+
- You must include all relevant fields a typical ${user_prompt} would require
|
|
449
|
+
|
|
450
|
+
- Follow the format and conventions shown in the ${object_unit} structure example.
|
|
451
|
+
- use uid for "createdByUid" and "checkedInUserId"
|
|
452
|
+
|
|
453
|
+
### workflow ###
|
|
454
|
+
|
|
455
|
+
Steps:
|
|
456
|
+
1. Use create_initial_studio_doc_tool to create the initial doc assign the return result in "doc" variable.
|
|
457
|
+
2. Get the ${object_unit} structure example from ### Structure and Examples ### section.
|
|
458
|
+
3. Build the ${object_unit} and validate against vs_68af4c84631c81919709268c2d0f1687
|
|
459
|
+
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
|
|
460
|
+
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
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
### Additional information ###
|
|
464
|
+
${studio_units[`studio_${object_unit}`].short}
|
|
465
|
+
|
|
466
|
+
### Output ###
|
|
467
|
+
if success: {code:1,data:save_result}
|
|
468
|
+
if fail: {code:-1,data:error}
|
|
469
|
+
`;
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const get_agents_as_a_tool = function (agent_list = []) {
|
|
473
|
+
let _tools = [];
|
|
474
|
+
for (const agent of agent_list) {
|
|
475
|
+
const _agent = new Agent(studio_agents_obj[agent]);
|
|
476
|
+
const tool = _agent.asTool({
|
|
477
|
+
toolName: studio_agents_obj[agent].name,
|
|
478
|
+
toolDescription: `Generate a ${agent} of the supplied text.`,
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
_tools.push(tool);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return _tools;
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
let studio_agents_obj = {
|
|
488
|
+
app: {
|
|
489
|
+
name: 'App builder',
|
|
490
|
+
instructions: get_app_instructions(),
|
|
491
|
+
tools: [get_user_name_tool],
|
|
492
|
+
model,
|
|
493
|
+
modelSettings: {
|
|
494
|
+
toolChoice: 'required', // ← this enables tool use
|
|
495
|
+
responseFormat: {
|
|
496
|
+
text: {
|
|
497
|
+
format: {
|
|
498
|
+
type: 'array', // or "markdown" if needed
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
outputType: z.array(z.object()),
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
table: {
|
|
506
|
+
name: 'Table builder',
|
|
507
|
+
instructions: get_table_instructions(),
|
|
508
|
+
tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af473196a88191afc6610fddfe4a62')],
|
|
509
|
+
model,
|
|
510
|
+
modelSettings: {
|
|
511
|
+
toolChoice: 'required', // ← this enables tool use
|
|
512
|
+
responseFormat: {
|
|
513
|
+
text: {
|
|
514
|
+
format: {
|
|
515
|
+
type: 'array', // or "markdown" if needed
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
outputType: z.array(
|
|
520
|
+
z.object({
|
|
521
|
+
_id: z.string(),
|
|
522
|
+
stat: z.number(),
|
|
523
|
+
docType: z.string(),
|
|
524
|
+
docDate: z.number(),
|
|
525
|
+
ts: z.number(),
|
|
526
|
+
order_ts: z.number(),
|
|
527
|
+
studio_meta: z.object({
|
|
528
|
+
created: z.number(),
|
|
529
|
+
createdByUid: z.string(),
|
|
530
|
+
checkedInUserId: z.string(),
|
|
531
|
+
savedByUid: z.string(),
|
|
532
|
+
checkedInUserName: z.string(),
|
|
533
|
+
parentId: z.string(),
|
|
534
|
+
source: z.string(),
|
|
535
|
+
}),
|
|
536
|
+
properties: z.object({
|
|
537
|
+
menuName: z.string(),
|
|
538
|
+
menuType: z.string(),
|
|
539
|
+
databaseSocket: z.string(),
|
|
540
|
+
}),
|
|
541
|
+
tableIndexes: z.array(
|
|
542
|
+
z.object({
|
|
543
|
+
id: z.string(),
|
|
544
|
+
data: z.object({
|
|
545
|
+
name: z.string(),
|
|
546
|
+
unique: z.boolean(),
|
|
547
|
+
keys: z.array(z.string()),
|
|
548
|
+
}),
|
|
549
|
+
}),
|
|
550
|
+
),
|
|
551
|
+
tableFields: z.array(
|
|
552
|
+
z.object({
|
|
553
|
+
id: z.string(),
|
|
554
|
+
data: z.object({
|
|
555
|
+
field_id: z.string(),
|
|
556
|
+
}),
|
|
557
|
+
props: z.object({
|
|
558
|
+
fieldType: z.string(),
|
|
559
|
+
}),
|
|
560
|
+
}),
|
|
561
|
+
),
|
|
562
|
+
}),
|
|
563
|
+
),
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
folder: {
|
|
567
|
+
name: 'Folder builder',
|
|
568
|
+
instructions: get_folder_instructions(),
|
|
569
|
+
tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af44989e4881918fc8bf8e84c6ce03')],
|
|
570
|
+
model: 'gpt-4o',
|
|
571
|
+
modelSettings: {
|
|
572
|
+
toolChoice: 'required', // ← this enables tool use
|
|
573
|
+
responseFormat: {
|
|
574
|
+
text: {
|
|
575
|
+
format: {
|
|
576
|
+
type: 'array', // or "markdown" if needed
|
|
577
|
+
},
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
outputType: z.array(
|
|
581
|
+
z.object({
|
|
582
|
+
_id: z.string(),
|
|
583
|
+
stat: z.number(),
|
|
584
|
+
docType: z.string(),
|
|
585
|
+
docDate: z.number(),
|
|
586
|
+
ts: z.number(),
|
|
587
|
+
order_ts: z.number(),
|
|
588
|
+
studio_meta: z.object({
|
|
589
|
+
created: z.number(),
|
|
590
|
+
createdByUid: z.string(),
|
|
591
|
+
checkedInUserId: z.string(),
|
|
592
|
+
savedByUid: z.string(),
|
|
593
|
+
checkedInUserName: z.string(),
|
|
594
|
+
parentId: z.string(),
|
|
595
|
+
source: z.string(),
|
|
596
|
+
}),
|
|
597
|
+
properties: z.object({
|
|
598
|
+
menuName: z.string(),
|
|
599
|
+
menuType: z.string(),
|
|
600
|
+
databaseSocket: z.string(),
|
|
601
|
+
}),
|
|
602
|
+
}),
|
|
603
|
+
),
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
component: {
|
|
607
|
+
name: 'Component builder',
|
|
608
|
+
instructions: get_component_instructions(),
|
|
609
|
+
tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool], //, fileSearchTool('vs_68af48a65cf88191a48a0f530d7e3919')
|
|
610
|
+
model,
|
|
611
|
+
modelSettings: {
|
|
612
|
+
toolChoice: 'required', // ← this enables tool use
|
|
613
|
+
responseFormat: {
|
|
614
|
+
text: {
|
|
615
|
+
format: {
|
|
616
|
+
type: 'array', // or "markdown" if needed
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
outputType: z.array(
|
|
621
|
+
z.object({
|
|
622
|
+
_id: z.string(),
|
|
623
|
+
stat: z.number(),
|
|
624
|
+
docType: z.string(),
|
|
625
|
+
docDate: z.number(),
|
|
626
|
+
ts: z.number(),
|
|
627
|
+
order_ts: z.number(),
|
|
628
|
+
studio_meta: z.object({
|
|
629
|
+
created: z.number(),
|
|
630
|
+
createdByUid: z.string(),
|
|
631
|
+
checkedInUserId: z.string(),
|
|
632
|
+
savedByUid: z.string(),
|
|
633
|
+
checkedInUserName: z.string(),
|
|
634
|
+
parentId: z.string(),
|
|
635
|
+
source: z.string(),
|
|
636
|
+
}),
|
|
637
|
+
properties: z.object({
|
|
638
|
+
menuName: z.string(),
|
|
639
|
+
menuType: z.string(),
|
|
640
|
+
databaseSocket: z.string(),
|
|
641
|
+
}),
|
|
642
|
+
progDataSource: z.object({}),
|
|
643
|
+
progFields: z.array(z.object({})),
|
|
644
|
+
progEvents: z.array(z.object({})),
|
|
645
|
+
progUi: z.array(z.object({})),
|
|
646
|
+
}),
|
|
647
|
+
),
|
|
648
|
+
},
|
|
649
|
+
},
|
|
650
|
+
get_data: {
|
|
651
|
+
name: 'Get data builder',
|
|
652
|
+
instructions: get_get_data_instructions(),
|
|
653
|
+
tools: [get_user_name_tool, create_initial_studio_doc_tool, check_studio_doc_tool, create_app_doc_tool, fileSearchTool('vs_68af4c84631c81919709268c2d0f1687'), fileSearchTool('vs_68af530d4ba081919ca57eabb5ae117a')],
|
|
654
|
+
model,
|
|
655
|
+
modelSettings: {
|
|
656
|
+
toolChoice: 'required', // ← this enables tool use
|
|
657
|
+
responseFormat: {
|
|
658
|
+
text: {
|
|
659
|
+
format: {
|
|
660
|
+
type: 'array', // or "markdown" if needed
|
|
661
|
+
},
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
outputType: z.array(
|
|
665
|
+
z.object({
|
|
666
|
+
_id: z.string(),
|
|
667
|
+
stat: z.number(),
|
|
668
|
+
docType: z.string(),
|
|
669
|
+
docDate: z.number(),
|
|
670
|
+
ts: z.number(),
|
|
671
|
+
order_ts: z.number(),
|
|
672
|
+
studio_meta: z.object({
|
|
673
|
+
created: z.number(),
|
|
674
|
+
createdByUid: z.string(),
|
|
675
|
+
checkedInUserId: z.string(),
|
|
676
|
+
savedByUid: z.string(),
|
|
677
|
+
checkedInUserName: z.string(),
|
|
678
|
+
parentId: z.string(),
|
|
679
|
+
source: z.string(),
|
|
680
|
+
}),
|
|
681
|
+
properties: z.object({
|
|
682
|
+
menuName: z.string(),
|
|
683
|
+
menuType: z.string(),
|
|
684
|
+
databaseSocket: z.string(),
|
|
685
|
+
}),
|
|
686
|
+
progDataSource: z.object({}),
|
|
687
|
+
progFields: z.array(z.object({})),
|
|
688
|
+
progEvents: z.array(z.object({})),
|
|
689
|
+
}),
|
|
690
|
+
),
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
if (object_unit === 'app') {
|
|
696
|
+
const agents_as_a_tool_arr = get_agents_as_a_tool(['table', 'folder', 'component', 'get_data']);
|
|
697
|
+
studio_agents_obj.app.tools = [...studio_agents_obj.app.tools, ...agents_as_a_tool_arr];
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
const run = async function (user_prompt, object_unit) {
|
|
701
|
+
const _agent = new Agent(studio_agents_obj[object_unit]);
|
|
702
|
+
const runner = new Runner();
|
|
703
|
+
|
|
704
|
+
const result = await runner.run(_agent, user_prompt, {
|
|
705
|
+
context: { uid, app_id },
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
return result;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
const result = await run(user_prompt, object_unit);
|
|
712
|
+
|
|
713
|
+
return { code: 1, data: result.finalOutput };
|
|
714
|
+
} catch (err) {
|
|
715
|
+
console.error('>>>>> AI:', err);
|
|
716
|
+
console.error('Cause:', err?.cause?.message);
|
|
717
|
+
return { code: -1, data: err.message };
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
export const get_chat_conversation = async function (req) {
|
|
722
|
+
let { conversation_id, order = 'asc', limit, after, _id, uid } = req;
|
|
723
|
+
|
|
724
|
+
if (_id) return await get_ai_doc({ uid, _id });
|
|
725
|
+
|
|
726
|
+
try {
|
|
727
|
+
const project_db = await get_account_project_db(uid);
|
|
728
|
+
const conversation_doc = await project_db.get(conversation_id);
|
|
729
|
+
let conversation = await client.conversations.items.list(conversation_id, { limit, order, after });
|
|
730
|
+
|
|
731
|
+
return { code: 1, data: { conversation, ...conversation_doc } };
|
|
732
|
+
} catch (err) {
|
|
733
|
+
return { code: -1, data: err.message };
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// try {
|
|
737
|
+
// // const conversation = await client.conversations.retrieve(conversation_id);
|
|
738
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
739
|
+
// const conversation_doc = await db.get(conversation_id);
|
|
740
|
+
// let conversation = await client.conversations.items.list(conversation_id, { limit, order, after });
|
|
741
|
+
|
|
742
|
+
// return { code: 1, data: { conversation, ...conversation_doc } };
|
|
743
|
+
// } catch (err) {
|
|
744
|
+
// return { code: -1, data: err.message };
|
|
745
|
+
// }
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
export const get_ai_chats = async function (req) {
|
|
749
|
+
let { uid, reference_id, _id } = req;
|
|
750
|
+
|
|
751
|
+
const project_db = await get_account_project_db(uid);
|
|
752
|
+
try {
|
|
753
|
+
if (_id) return await get_ai_doc({ _id, uid });
|
|
754
|
+
|
|
755
|
+
let opt = { selector: { docType: 'chat_conversation', uid, stat: 3 } };
|
|
756
|
+
if (reference_id) {
|
|
757
|
+
opt.selector.reference_id = reference_id;
|
|
758
|
+
}
|
|
759
|
+
const data = await project_db.find(opt);
|
|
760
|
+
|
|
761
|
+
return { code: 1, data };
|
|
762
|
+
} catch (err) {
|
|
763
|
+
return { code: -1, data: err.message };
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
767
|
+
// try {
|
|
768
|
+
// let opt = { selector: { docType: 'chat_conversation', uid, stat: 3 } };
|
|
769
|
+
// if (reference_id) {
|
|
770
|
+
// opt.selector.reference_id = reference_id;
|
|
771
|
+
// }
|
|
772
|
+
// const data = await db.find(opt);
|
|
773
|
+
|
|
774
|
+
// return { code: 1, data };
|
|
775
|
+
// } catch (err) {
|
|
776
|
+
// return { code: -1, data: err.message };
|
|
777
|
+
// }
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
export const delete_ai_chat = async function (req) {
|
|
781
|
+
let { conversation_id, uid } = req;
|
|
782
|
+
|
|
783
|
+
const project_db = await get_account_project_db(uid);
|
|
784
|
+
try {
|
|
785
|
+
let conversation_doc = await project_db.get(conversation_id);
|
|
786
|
+
conversation_doc.stat = 4;
|
|
787
|
+
conversation_doc.ts = Date.now();
|
|
788
|
+
const data = await project_db.insert(conversation_doc);
|
|
789
|
+
|
|
790
|
+
return { code: 1, data };
|
|
791
|
+
} catch (err) {
|
|
792
|
+
return { code: -1, data: err.message };
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
796
|
+
// try {
|
|
797
|
+
// let conversation_doc = await db.get(conversation_id);
|
|
798
|
+
// conversation_doc.stat = 4;
|
|
799
|
+
// conversation_doc.ts = Date.now();
|
|
800
|
+
// const data = await db.insert(conversation_doc);
|
|
801
|
+
|
|
802
|
+
// return { code: 1, data };
|
|
803
|
+
// } catch (err) {
|
|
804
|
+
// return { code: -1, data: err.message };
|
|
805
|
+
// }
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
export const submit_chat_conversation = async function (req) {
|
|
809
|
+
const { prompt, uid, reference_type, reference_id /* agent_mode not used here */ } = req;
|
|
810
|
+
let { conversation_id } = req;
|
|
811
|
+
|
|
812
|
+
const project_db = await get_account_project_db(uid);
|
|
813
|
+
|
|
814
|
+
let conversation_doc = {
|
|
815
|
+
docType: 'chat_conversation',
|
|
816
|
+
title: prompt.substr(0, 40),
|
|
817
|
+
date_created_ts: Date.now(),
|
|
818
|
+
ts: Date.now(),
|
|
819
|
+
stat: 3,
|
|
820
|
+
uid,
|
|
821
|
+
messages: [],
|
|
822
|
+
reference_type,
|
|
823
|
+
reference_id,
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
// 1. Ensure we have a conversation doc in Couch
|
|
827
|
+
let conversation_exist;
|
|
828
|
+
try {
|
|
829
|
+
if (!conversation_id) throw new Error('no id');
|
|
830
|
+
conversation_doc = await project_db.get(conversation_id);
|
|
831
|
+
|
|
832
|
+
conversation_exist = true;
|
|
833
|
+
} catch (err) {
|
|
834
|
+
// new conversation
|
|
835
|
+
const conversation_obj = await client.conversations.create();
|
|
836
|
+
conversation_id = conversation_obj.id;
|
|
837
|
+
conversation_doc.conversation_obj = conversation_obj;
|
|
838
|
+
conversation_doc._id = conversation_id;
|
|
839
|
+
|
|
840
|
+
// conversation_doc = {
|
|
841
|
+
// _id: conversation_id,
|
|
842
|
+
// docType: 'chat_conversation',
|
|
843
|
+
// title: prompt.substr(0, 40),
|
|
844
|
+
// date_created_ts: Date.now(),
|
|
845
|
+
// ts: Date.now(),
|
|
846
|
+
// stat: 3,
|
|
847
|
+
// uid,
|
|
848
|
+
// messages: [],
|
|
849
|
+
// };
|
|
850
|
+
|
|
851
|
+
// const ret_save = await db.insert(conversation_doc);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const get_agents = async function () {
|
|
855
|
+
const list = [];
|
|
856
|
+
|
|
857
|
+
// default/general Q&A agent
|
|
858
|
+
// list.push(
|
|
859
|
+
// new Agent({
|
|
860
|
+
// name: 'Default Agent',
|
|
861
|
+
// instructions: 'Answer any general user question clearly and briefly.',
|
|
862
|
+
// model,
|
|
863
|
+
// }),
|
|
864
|
+
// );
|
|
865
|
+
// debugger;
|
|
866
|
+
let ai_agents_ret = {};
|
|
867
|
+
let modelSettings = {};
|
|
868
|
+
|
|
869
|
+
if (reference_type === 'agent') {
|
|
870
|
+
modelSettings = { toolChoice: 'required' };
|
|
871
|
+
ai_agents_ret = { code: 1, data: { docs: [{ id: reference_id }] } };
|
|
872
|
+
} else {
|
|
873
|
+
ai_agents_ret = await get_ai_agents({ uid });
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
for (const doc of ai_agents_ret.data.docs) {
|
|
877
|
+
const ai_agent_ret = await get_ai_doc({ _id: doc.id, uid });
|
|
878
|
+
let tools = [];
|
|
879
|
+
let tool_resources = {};
|
|
880
|
+
if (ai_agent_ret.code < 0) continue;
|
|
881
|
+
const ai_agent_doc = ai_agent_ret.data;
|
|
882
|
+
for (const [key, val] of Object.entries(ai_agent_doc?.agentConfig?.agent_tools || [])) {
|
|
883
|
+
const { name, description } = val;
|
|
884
|
+
switch (val.type) {
|
|
885
|
+
case 'web_search': {
|
|
886
|
+
//hosted_web_search
|
|
887
|
+
tools.push(webSearchTool());
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// case 'web_search': {
|
|
892
|
+
// tools.push(
|
|
893
|
+
// tool({
|
|
894
|
+
// name: name || val.type,
|
|
895
|
+
// description: description || val.type,
|
|
896
|
+
// parameters: z.object({
|
|
897
|
+
// query: z.string().describe('The search query text.'),
|
|
898
|
+
// numResults: z.number().int().describe('Number of top search results to return.').default(3),
|
|
899
|
+
// }),
|
|
900
|
+
// async execute(e, RunContext) {
|
|
901
|
+
// const { query, numResults } = e;
|
|
902
|
+
// try {
|
|
903
|
+
// const searchUrl = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_redirect=1`;
|
|
904
|
+
// const response = await fetch(searchUrl);
|
|
905
|
+
// const data = await response.json();
|
|
906
|
+
|
|
907
|
+
// // Simplify results
|
|
908
|
+
// const results = (data.RelatedTopics || []).slice(0, numResults).map((item) => ({
|
|
909
|
+
// title: item.Text,
|
|
910
|
+
// url: item.FirstURL,
|
|
911
|
+
// }));
|
|
912
|
+
|
|
913
|
+
// return JSON.stringify(results, null, 2);
|
|
914
|
+
// } catch (err) {
|
|
915
|
+
// return 'unknown';
|
|
916
|
+
// }
|
|
917
|
+
// },
|
|
918
|
+
// }),
|
|
919
|
+
// );
|
|
920
|
+
// break;
|
|
921
|
+
// }
|
|
922
|
+
|
|
923
|
+
case 'image_generate': {
|
|
924
|
+
tools.push(
|
|
925
|
+
tool({
|
|
926
|
+
name,
|
|
927
|
+
description,
|
|
928
|
+
parameters: z.object({
|
|
929
|
+
prompt: z.string().describe('The prompt for the image.'),
|
|
930
|
+
numGenerations: z.number().int().describe('Number generations to image create.').default(3),
|
|
931
|
+
}),
|
|
932
|
+
async execute(e, RunContext) {
|
|
933
|
+
const { prompt, numGenerations = val?.image_generations } = e;
|
|
934
|
+
try {
|
|
935
|
+
const base64 = await create_image(prompt, undefined, undefined, numGenerations);
|
|
936
|
+
// console.log(base64);
|
|
937
|
+
|
|
938
|
+
return `<img src="data:image/jpg;base64,${base64}">`;
|
|
939
|
+
} catch (err) {
|
|
940
|
+
return 'unknown';
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
}),
|
|
944
|
+
);
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
case 'file_search': {
|
|
949
|
+
if (val.file.vector_store_id) {
|
|
950
|
+
tools.push(fileSearchTool(val.file.vector_store_id));
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// const vector_store_ids = val.files.map((file) => file.vector_store_id);
|
|
954
|
+
// if (vector_store_ids.length) {
|
|
955
|
+
// for (const store_id of vector_store_ids) {
|
|
956
|
+
// tools.push(fileSearchTool(store_id));
|
|
957
|
+
// }
|
|
958
|
+
// }
|
|
959
|
+
break;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
case 'ai_agent': {
|
|
963
|
+
if (val.ai_agent_id) {
|
|
964
|
+
const agent_ret = await get_ai_agents({ _id: val.ai_agent_id });
|
|
965
|
+
if (agent_ret.code > -1) {
|
|
966
|
+
const agent_doc = agent_ret.data;
|
|
967
|
+
|
|
968
|
+
const agent = new Agent({
|
|
969
|
+
name: agent_doc.agent_name,
|
|
970
|
+
instructions: agent_doc.agent_instructions,
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
tools.push(
|
|
974
|
+
agent.asTool({
|
|
975
|
+
toolName: agent_doc.agent_name,
|
|
976
|
+
toolDescription: agent_doc.agent_instructions,
|
|
977
|
+
}),
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
default:
|
|
984
|
+
break;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (!tools.length) continue;
|
|
988
|
+
|
|
989
|
+
list.push(
|
|
990
|
+
new Agent({
|
|
991
|
+
name: ai_agent_doc._id,
|
|
992
|
+
instructions: ai_agent_doc.agentConfig.agent_instructions,
|
|
993
|
+
model,
|
|
994
|
+
tools,
|
|
995
|
+
metadata: {
|
|
996
|
+
agent_id: ai_agent_doc._id,
|
|
997
|
+
ts: Date.now(),
|
|
998
|
+
},
|
|
999
|
+
tool_resources,
|
|
1000
|
+
modelSettings,
|
|
1001
|
+
}),
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
//tell me more on xuda
|
|
1005
|
+
// debugger;
|
|
1006
|
+
|
|
1007
|
+
return list;
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
try {
|
|
1011
|
+
// if (reference_type === 'agent') {
|
|
1012
|
+
// } else {
|
|
1013
|
+
const runner = new Runner();
|
|
1014
|
+
let _agent;
|
|
1015
|
+
// 2. Build specialist agents list
|
|
1016
|
+
|
|
1017
|
+
const agents = await get_agents();
|
|
1018
|
+
|
|
1019
|
+
if (reference_type === 'agent') {
|
|
1020
|
+
_agent = agents[0];
|
|
1021
|
+
} else {
|
|
1022
|
+
// 3. Build triage agent that can hand off
|
|
1023
|
+
_agent = new Agent({
|
|
1024
|
+
name: 'Triage Agent',
|
|
1025
|
+
instructions: 'You are a triage router. Decide which specialist should answer. If general, answer yourself. use web search only as last option',
|
|
1026
|
+
model,
|
|
1027
|
+
handoffs: agents, // this lets triageAgent forward to other agents
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
// 4. Run the triage agent with conversation memory
|
|
1031
|
+
// Runner.runSync / Runner.run depending on your SDK.
|
|
1032
|
+
// We pass { conversationId } so it can keep context across turns.
|
|
1033
|
+
|
|
1034
|
+
// const runner = new Runner();
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
const output = await runner.run(_agent, prompt, {
|
|
1038
|
+
conversationId: conversation_id,
|
|
1039
|
+
});
|
|
1040
|
+
// }
|
|
1041
|
+
try {
|
|
1042
|
+
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 };
|
|
1043
|
+
conversation_doc.ts = Date.now();
|
|
1044
|
+
conversation_doc.messages.push(obj);
|
|
1045
|
+
await project_db.insert(conversation_doc);
|
|
1046
|
+
|
|
1047
|
+
if (!conversation_exist) {
|
|
1048
|
+
setTimeout(async () => {
|
|
1049
|
+
// Ask GPT for title
|
|
1050
|
+
const title = await submit_chat_gpt_prompt({
|
|
1051
|
+
prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`,
|
|
1052
|
+
model: 'gpt-5-nano',
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
conversation_doc = await project_db.get(conversation_id);
|
|
1056
|
+
conversation_doc.title = title.data;
|
|
1057
|
+
|
|
1058
|
+
await project_db.insert(conversation_doc);
|
|
1059
|
+
update_thumbnail('conversation', conversation_doc, uid);
|
|
1060
|
+
}, 2500);
|
|
1061
|
+
} else {
|
|
1062
|
+
if (!conversation_doc.base64 && (!conversation_doc.thumbnail_request_ts || Date.now() - conversation_doc.thumbnail_request_ts > 120000)) {
|
|
1063
|
+
update_thumbnail('conversation', conversation_doc, uid);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
debugger;
|
|
1068
|
+
}
|
|
1069
|
+
// }
|
|
1070
|
+
|
|
1071
|
+
return {
|
|
1072
|
+
code: 1,
|
|
1073
|
+
data: {
|
|
1074
|
+
conversation_doc,
|
|
1075
|
+
response: output.output, // output.finalOutput ?? output.output ?? output, // depends on SDK shape
|
|
1076
|
+
},
|
|
1077
|
+
};
|
|
1078
|
+
} catch (err) {
|
|
1079
|
+
return { code: -1, data: err.message || String(err) };
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// const get_agents = function () {
|
|
1084
|
+
// let ret = [];
|
|
1085
|
+
|
|
1086
|
+
// // const default_agent = {
|
|
1087
|
+
// // name: 'Default agent',
|
|
1088
|
+
// // instructions: '',
|
|
1089
|
+
// // tools: [],
|
|
1090
|
+
// // model,
|
|
1091
|
+
// // };
|
|
1092
|
+
|
|
1093
|
+
// ret.push(
|
|
1094
|
+
// new Agent({
|
|
1095
|
+
// name: 'Default agent',
|
|
1096
|
+
// instructions: 'answer any question',
|
|
1097
|
+
// model,
|
|
1098
|
+
// }),
|
|
1099
|
+
// );
|
|
1100
|
+
|
|
1101
|
+
// return ret;
|
|
1102
|
+
// };
|
|
1103
|
+
|
|
1104
|
+
// export const submit_chat_conversation = async function (req) {
|
|
1105
|
+
// const { prompt, uid, agent_mode } = req;
|
|
1106
|
+
// let { conversation_id } = req;
|
|
1107
|
+
|
|
1108
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1109
|
+
// // let thread;
|
|
1110
|
+
// let conversation_doc;
|
|
1111
|
+
// try {
|
|
1112
|
+
// if (!conversation_id) throw '';
|
|
1113
|
+
// conversation_doc = await db.get(conversation_id);
|
|
1114
|
+
// } catch (err) {
|
|
1115
|
+
// conversation_doc = await client.conversations.create();
|
|
1116
|
+
|
|
1117
|
+
// // await client.beta.threads.create();
|
|
1118
|
+
// // console.log('thread', thread);
|
|
1119
|
+
// conversation_id = conversation_doc.id;
|
|
1120
|
+
|
|
1121
|
+
// let ret = await submit_chat_gpt_prompt({ prompt: `create title for the prompt 5 words max: ${prompt}` });
|
|
1122
|
+
// conversation_doc = { _id: conversation_id, docType: 'chat_thread', title: ret.data, date_created_ts: Date.now(), uid };
|
|
1123
|
+
// await db.insert(conversation_doc);
|
|
1124
|
+
// }
|
|
1125
|
+
|
|
1126
|
+
// try {
|
|
1127
|
+
// // await client.beta.threads.messages.create(conversation_id, {
|
|
1128
|
+
// // role: 'user',
|
|
1129
|
+
// // content: prompt,
|
|
1130
|
+
// // });
|
|
1131
|
+
|
|
1132
|
+
// // const response = await submit_chat_gpt_prompt({ prompt });
|
|
1133
|
+
|
|
1134
|
+
// // const thread_res = await client.beta.threads.messages.create(conversation_id, {
|
|
1135
|
+
// // role: 'assistant',
|
|
1136
|
+
// // content: response.data,
|
|
1137
|
+
// // });
|
|
1138
|
+
// debugger;
|
|
1139
|
+
// const agents = get_agents();
|
|
1140
|
+
|
|
1141
|
+
// const triageAgent = Agent.create({
|
|
1142
|
+
// name: 'Triage Agent',
|
|
1143
|
+
// instructions: `Help the user with their questions.`,
|
|
1144
|
+
// handoffs: agents,
|
|
1145
|
+
// });
|
|
1146
|
+
// // const output = await run(triageAgent, prompt, { conversationId: conversation_id });
|
|
1147
|
+
// const output = await run(triageAgent, prompt);
|
|
1148
|
+
// debugger;
|
|
1149
|
+
// return { code: 1, data: { conversation_doc, response: output } };
|
|
1150
|
+
// } catch (err) {
|
|
1151
|
+
// return { code: -1, data: err.message };
|
|
1152
|
+
// }
|
|
1153
|
+
// };
|
|
1154
|
+
// export const submit_chat_conversation = async function (req) {
|
|
1155
|
+
// const { prompt, uid } = req;
|
|
1156
|
+
// let { thread_id } = req;
|
|
1157
|
+
|
|
1158
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1159
|
+
// // let thread;
|
|
1160
|
+
// let thread_doc;
|
|
1161
|
+
// try {
|
|
1162
|
+
// if (!thread_id) throw '';
|
|
1163
|
+
// thread_doc = await db.get(thread_id);
|
|
1164
|
+
// } catch (err) {
|
|
1165
|
+
// thread_doc = await client.beta.threads.create();
|
|
1166
|
+
// // console.log('thread', thread);
|
|
1167
|
+
// thread_id = thread_doc.id;
|
|
1168
|
+
|
|
1169
|
+
// let ret = await submit_chat_gpt_prompt({ prompt: `create title for the prompt 5 words max: ${prompt}` });
|
|
1170
|
+
// thread_doc = { _id: thread_id, docType: 'chat_thread', title: ret.data, date_created_ts: Date.now(), uid };
|
|
1171
|
+
// await db.insert(thread_doc);
|
|
1172
|
+
// }
|
|
1173
|
+
|
|
1174
|
+
// try {
|
|
1175
|
+
// await client.beta.threads.messages.create(thread_id, {
|
|
1176
|
+
// role: 'user',
|
|
1177
|
+
// content: prompt,
|
|
1178
|
+
// });
|
|
1179
|
+
|
|
1180
|
+
// const response = await submit_chat_gpt_prompt({ prompt });
|
|
1181
|
+
|
|
1182
|
+
// const thread_res = await client.beta.threads.messages.create(thread_id, {
|
|
1183
|
+
// role: 'assistant',
|
|
1184
|
+
// content: response.data,
|
|
1185
|
+
// });
|
|
1186
|
+
// debugger;
|
|
1187
|
+
// return { code: 1, data: { thread_doc, response: response.data } };
|
|
1188
|
+
// } catch (err) {
|
|
1189
|
+
// return { code: -1, data: err.message };
|
|
1190
|
+
// }
|
|
1191
|
+
// };
|
|
1192
|
+
|
|
1193
|
+
// get_chat_thread({ thread_id: 'what the weather in herzeliya' });
|
|
1194
|
+
|
|
1195
|
+
export const submit_chat_gpt_prompt = async function (req) {
|
|
1196
|
+
const { model = 'gpt-5-mini', prompt } = req;
|
|
1197
|
+
try {
|
|
1198
|
+
const response = await client.responses.create({
|
|
1199
|
+
model,
|
|
1200
|
+
input: prompt,
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
return { code: 1, data: response.output_text };
|
|
1204
|
+
} catch (err) {
|
|
1205
|
+
return { code: -1, data: err.message };
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
export const create_studio_app = async function (subject) {
|
|
1210
|
+
try {
|
|
1211
|
+
let prompt = `
|
|
1212
|
+
|
|
1213
|
+
1. list all tables and screens to build an ${subject} app.
|
|
1214
|
+
2. return object array for each item (name,type,description)
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
`;
|
|
1218
|
+
|
|
1219
|
+
const data = await submit_chat_gpt_prompt({ prompt });
|
|
1220
|
+
|
|
1221
|
+
return { code: 1, data };
|
|
1222
|
+
} catch (err) {
|
|
1223
|
+
return { code: -1, data: err.message };
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
async function fineTuneWithMultipleFiles(datasetPaths, baseModel = 'gpt-4o-mini') {
|
|
1228
|
+
try {
|
|
1229
|
+
console.log('📤 Uploading datasets...');
|
|
1230
|
+
|
|
1231
|
+
// Step 1. Upload all JSONL files in parallel
|
|
1232
|
+
const uploadedFiles = await Promise.all(
|
|
1233
|
+
datasetPaths.map(async (filePath) => {
|
|
1234
|
+
const file = await openai.files.create({
|
|
1235
|
+
file: fs.createReadStream(path.resolve(filePath)),
|
|
1236
|
+
purpose: 'fine-tune',
|
|
1237
|
+
});
|
|
1238
|
+
console.log(`✅ Uploaded: ${file.filename} → ID: ${file.id}`);
|
|
1239
|
+
return file.id;
|
|
1240
|
+
}),
|
|
1241
|
+
);
|
|
1242
|
+
|
|
1243
|
+
// Step 2. Create fine-tuning job with multiple training files
|
|
1244
|
+
console.log(`🚀 Creating fine-tuning job for ${baseModel}...`);
|
|
1245
|
+
const fineTuneJob = await openai.fineTuning.jobs.create({
|
|
1246
|
+
training_files: uploadedFiles.map((id) => ({ file_id: id })), // <-- multiple files here
|
|
1247
|
+
model: baseModel,
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
console.log(`📌 Fine-tuning job created: ${fineTuneJob.id}`);
|
|
1251
|
+
|
|
1252
|
+
// Step 3. Poll job status until training completes
|
|
1253
|
+
let status = fineTuneJob.status;
|
|
1254
|
+
while (status === 'pending' || status === 'running') {
|
|
1255
|
+
console.log(`⏳ Job status: ${status}...`);
|
|
1256
|
+
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
1257
|
+
|
|
1258
|
+
const updatedJob = await openai.fineTuning.jobs.retrieve(fineTuneJob.id);
|
|
1259
|
+
status = updatedJob.status;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
// Step 4. Check final status
|
|
1263
|
+
if (status === 'succeeded') {
|
|
1264
|
+
console.log('🎉 Fine-tuning completed successfully!');
|
|
1265
|
+
console.log(`🆕 Fine-tuned model: ${fineTuneJob.fine_tuned_model}`);
|
|
1266
|
+
return fineTuneJob.fine_tuned_model;
|
|
1267
|
+
} else {
|
|
1268
|
+
throw new Error(`❌ Fine-tuning failed: ${status}`);
|
|
1269
|
+
}
|
|
1270
|
+
} catch (error) {
|
|
1271
|
+
console.error('⚠️ Fine-tuning error:', error);
|
|
1272
|
+
throw error;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
// const MODEL_NAME = 'gpt-5.1-mini'; // or whatever model you want
|
|
1277
|
+
|
|
1278
|
+
// export const submit_chat_conversation = async function (req) {
|
|
1279
|
+
// const { prompt, uid, reference_type, reference_id /* agent_mode not used here */ } = req;
|
|
1280
|
+
// let { conversation_id } = req;
|
|
1281
|
+
|
|
1282
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1283
|
+
|
|
1284
|
+
// let conversation_doc = {
|
|
1285
|
+
// docType: 'chat_conversation',
|
|
1286
|
+
// title: prompt.substr(0, 40),
|
|
1287
|
+
// date_created_ts: Date.now(),
|
|
1288
|
+
// ts: Date.now(),
|
|
1289
|
+
// stat: 3,
|
|
1290
|
+
// uid,
|
|
1291
|
+
// messages: [],
|
|
1292
|
+
// reference_type,
|
|
1293
|
+
// reference_id,
|
|
1294
|
+
// };
|
|
1295
|
+
|
|
1296
|
+
// // 1. Ensure we have a conversation doc in Couch
|
|
1297
|
+
// let conversation_exist;
|
|
1298
|
+
// try {
|
|
1299
|
+
// if (!conversation_id) throw new Error('no id');
|
|
1300
|
+
// conversation_doc = await db.get(conversation_id);
|
|
1301
|
+
|
|
1302
|
+
// conversation_exist = true;
|
|
1303
|
+
// } catch (err) {
|
|
1304
|
+
// // new conversation
|
|
1305
|
+
// const conversation_obj = await client.conversations.create();
|
|
1306
|
+
// conversation_id = conversation_obj.id;
|
|
1307
|
+
// conversation_doc.conversation_obj = conversation_obj;
|
|
1308
|
+
// conversation_doc._id = conversation_id;
|
|
1309
|
+
|
|
1310
|
+
// // conversation_doc = {
|
|
1311
|
+
// // _id: conversation_id,
|
|
1312
|
+
// // docType: 'chat_conversation',
|
|
1313
|
+
// // title: prompt.substr(0, 40),
|
|
1314
|
+
// // date_created_ts: Date.now(),
|
|
1315
|
+
// // ts: Date.now(),
|
|
1316
|
+
// // stat: 3,
|
|
1317
|
+
// // uid,
|
|
1318
|
+
// // messages: [],
|
|
1319
|
+
// // };
|
|
1320
|
+
|
|
1321
|
+
// // const ret_save = await db.insert(conversation_doc);
|
|
1322
|
+
// }
|
|
1323
|
+
|
|
1324
|
+
// const get_agents = async function () {
|
|
1325
|
+
// const list = [];
|
|
1326
|
+
|
|
1327
|
+
// // default/general Q&A agent
|
|
1328
|
+
// // list.push(
|
|
1329
|
+
// // new Agent({
|
|
1330
|
+
// // name: 'Default Agent',
|
|
1331
|
+
// // instructions: 'Answer any general user question clearly and briefly.',
|
|
1332
|
+
// // model,
|
|
1333
|
+
// // }),
|
|
1334
|
+
// // );
|
|
1335
|
+
|
|
1336
|
+
// const ret = await get_ai_agents({ uid });
|
|
1337
|
+
|
|
1338
|
+
// for (const doc of ret.data.docs) {
|
|
1339
|
+
// let tools = [];
|
|
1340
|
+
// let tool_resources = {};
|
|
1341
|
+
// for (const [key, val] of Object.entries(doc?.agent_tools || [])) {
|
|
1342
|
+
// const { name, description } = val;
|
|
1343
|
+
// switch (val.type) {
|
|
1344
|
+
// case 'hosted_web_search': {
|
|
1345
|
+
// tools.push(webSearchTool());
|
|
1346
|
+
// break;
|
|
1347
|
+
// }
|
|
1348
|
+
|
|
1349
|
+
// case 'web_search': {
|
|
1350
|
+
// tools.push(
|
|
1351
|
+
// tool({
|
|
1352
|
+
// name,
|
|
1353
|
+
// description,
|
|
1354
|
+
// parameters: z.object({
|
|
1355
|
+
// query: z.string().describe('The search query text.'),
|
|
1356
|
+
// numResults: z.number().int().describe('Number of top search results to return.').default(3),
|
|
1357
|
+
// }),
|
|
1358
|
+
// async execute(e, RunContext) {
|
|
1359
|
+
// const { query, numResults } = e;
|
|
1360
|
+
// try {
|
|
1361
|
+
// const searchUrl = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_redirect=1`;
|
|
1362
|
+
// const response = await fetch(searchUrl);
|
|
1363
|
+
// const data = await response.json();
|
|
1364
|
+
|
|
1365
|
+
// // Simplify results
|
|
1366
|
+
// const results = (data.RelatedTopics || []).slice(0, numResults).map((item) => ({
|
|
1367
|
+
// title: item.Text,
|
|
1368
|
+
// url: item.FirstURL,
|
|
1369
|
+
// }));
|
|
1370
|
+
|
|
1371
|
+
// return JSON.stringify(results, null, 2);
|
|
1372
|
+
// } catch (err) {
|
|
1373
|
+
// return 'unknown';
|
|
1374
|
+
// }
|
|
1375
|
+
// },
|
|
1376
|
+
// }),
|
|
1377
|
+
// );
|
|
1378
|
+
// break;
|
|
1379
|
+
// }
|
|
1380
|
+
|
|
1381
|
+
// case 'image_generate': {
|
|
1382
|
+
// tools.push(
|
|
1383
|
+
// tool({
|
|
1384
|
+
// name,
|
|
1385
|
+
// description,
|
|
1386
|
+
// parameters: z.object({
|
|
1387
|
+
// prompt: z.string().describe('The prompt for the image.'),
|
|
1388
|
+
// numGenerations: z.number().int().describe('Number generations to image create.').default(3),
|
|
1389
|
+
// }),
|
|
1390
|
+
// async execute(e, RunContext) {
|
|
1391
|
+
// const { prompt, numGenerations = val?.image_generations } = e;
|
|
1392
|
+
// try {
|
|
1393
|
+
// const base64 = await create_image(prompt, undefined, undefined, numGenerations);
|
|
1394
|
+
// // console.log(base64);
|
|
1395
|
+
|
|
1396
|
+
// return `<img src="data:image/jpg;base64,${base64}">`;
|
|
1397
|
+
// } catch (err) {
|
|
1398
|
+
// return 'unknown';
|
|
1399
|
+
// }
|
|
1400
|
+
// },
|
|
1401
|
+
// }),
|
|
1402
|
+
// );
|
|
1403
|
+
// break;
|
|
1404
|
+
// }
|
|
1405
|
+
|
|
1406
|
+
// case 'file_search': {
|
|
1407
|
+
// const vector_store_ids = val.files.map((file) => file.vector_store_id);
|
|
1408
|
+
// if (vector_store_ids.length) {
|
|
1409
|
+
// for (const store_id of vector_store_ids) {
|
|
1410
|
+
// tools.push(fileSearchTool(store_id));
|
|
1411
|
+
// }
|
|
1412
|
+
// }
|
|
1413
|
+
// break;
|
|
1414
|
+
// }
|
|
1415
|
+
|
|
1416
|
+
// case 'ai_agent': {
|
|
1417
|
+
// if (val.ai_agent_id) {
|
|
1418
|
+
// const agent_ret = await get_ai_agents({ _id: val.ai_agent_id });
|
|
1419
|
+
// if (agent_ret.code > -1) {
|
|
1420
|
+
// const agent_doc = agent_ret.data;
|
|
1421
|
+
|
|
1422
|
+
// const agent = new Agent({
|
|
1423
|
+
// name: agent_doc.agent_name,
|
|
1424
|
+
// instructions: agent_doc.agent_instructions,
|
|
1425
|
+
// });
|
|
1426
|
+
|
|
1427
|
+
// tools.push(
|
|
1428
|
+
// agent.asTool({
|
|
1429
|
+
// toolName: agent_doc.agent_name,
|
|
1430
|
+
// toolDescription: agent_doc.agent_instructions,
|
|
1431
|
+
// }),
|
|
1432
|
+
// );
|
|
1433
|
+
// }
|
|
1434
|
+
// }
|
|
1435
|
+
// break;
|
|
1436
|
+
// }
|
|
1437
|
+
// default:
|
|
1438
|
+
// break;
|
|
1439
|
+
// }
|
|
1440
|
+
// }
|
|
1441
|
+
// if (!tools.length) continue;
|
|
1442
|
+
|
|
1443
|
+
// list.push(
|
|
1444
|
+
// new Agent({
|
|
1445
|
+
// name: doc._id,
|
|
1446
|
+
// instructions: doc.agent_instructions,
|
|
1447
|
+
// model,
|
|
1448
|
+
// tools,
|
|
1449
|
+
// metadata: {
|
|
1450
|
+
// agent_id: doc._id,
|
|
1451
|
+
// ts: Date.now(),
|
|
1452
|
+
// },
|
|
1453
|
+
// tool_resources,
|
|
1454
|
+
// }),
|
|
1455
|
+
// );
|
|
1456
|
+
// }
|
|
1457
|
+
// //tell me more on xuda
|
|
1458
|
+
// // debugger;
|
|
1459
|
+
|
|
1460
|
+
// return list;
|
|
1461
|
+
// };
|
|
1462
|
+
|
|
1463
|
+
// try {
|
|
1464
|
+
// // 2. Build specialist agents list
|
|
1465
|
+
|
|
1466
|
+
// const agents = await get_agents();
|
|
1467
|
+
|
|
1468
|
+
// // 3. Build triage agent that can hand off
|
|
1469
|
+
// const triageAgent = new Agent({
|
|
1470
|
+
// name: 'Triage Agent',
|
|
1471
|
+
// instructions: 'You are a triage router. Decide which specialist should answer. If general, answer yourself. use web search only as last option',
|
|
1472
|
+
// model,
|
|
1473
|
+
// handoffs: agents, // this lets triageAgent forward to other agents
|
|
1474
|
+
// });
|
|
1475
|
+
|
|
1476
|
+
// // 4. Run the triage agent with conversation memory
|
|
1477
|
+
// // Runner.runSync / Runner.run depending on your SDK.
|
|
1478
|
+
// // We pass { conversationId } so it can keep context across turns.
|
|
1479
|
+
|
|
1480
|
+
// const runner = new Runner();
|
|
1481
|
+
|
|
1482
|
+
// const output = await runner.run(triageAgent, prompt, {
|
|
1483
|
+
// conversationId: conversation_id,
|
|
1484
|
+
// });
|
|
1485
|
+
|
|
1486
|
+
// // // 5. Persist any new conversationId the runner returns (some SDKs will
|
|
1487
|
+
// // // generate/stabilize it and give you output.conversationId)
|
|
1488
|
+
// // if (output.conversationId && output.conversationId !== conversation_id) {
|
|
1489
|
+
// // conversation_id = output.conversationId;
|
|
1490
|
+
// // // patch couch doc _id if you want them aligned OR store mapping
|
|
1491
|
+
// // // If you can't change _id after insert, store mapping instead:
|
|
1492
|
+
// // conversation_doc.thread_ref = output.conversationId;
|
|
1493
|
+
// // await db.insert(conversation_doc);
|
|
1494
|
+
// // }
|
|
1495
|
+
|
|
1496
|
+
// try {
|
|
1497
|
+
// 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 };
|
|
1498
|
+
// conversation_doc.ts = Date.now();
|
|
1499
|
+
// conversation_doc.messages.push(obj);
|
|
1500
|
+
// await db.insert(conversation_doc);
|
|
1501
|
+
|
|
1502
|
+
// if (!conversation_exist) {
|
|
1503
|
+
// setTimeout(async () => {
|
|
1504
|
+
// // Ask GPT for title
|
|
1505
|
+
// const title = await submit_chat_gpt_prompt({
|
|
1506
|
+
// prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`,
|
|
1507
|
+
// model: 'gpt-5-nano',
|
|
1508
|
+
// });
|
|
1509
|
+
|
|
1510
|
+
// conversation_doc = await db.get(conversation_id);
|
|
1511
|
+
// conversation_doc.title = title.data;
|
|
1512
|
+
|
|
1513
|
+
// await db.insert(conversation_doc);
|
|
1514
|
+
// update_thumbnail('conversation', conversation_doc, 'title');
|
|
1515
|
+
// }, 2500);
|
|
1516
|
+
// }
|
|
1517
|
+
// } catch (error) {
|
|
1518
|
+
// debugger;
|
|
1519
|
+
// }
|
|
1520
|
+
// // }
|
|
1521
|
+
|
|
1522
|
+
// return {
|
|
1523
|
+
// code: 1,
|
|
1524
|
+
// data: {
|
|
1525
|
+
// conversation_doc,
|
|
1526
|
+
// response: output.output, // output.finalOutput ?? output.output ?? output, // depends on SDK shape
|
|
1527
|
+
// },
|
|
1528
|
+
// };
|
|
1529
|
+
// } catch (err) {
|
|
1530
|
+
// return { code: -1, data: err.message || String(err) };
|
|
1531
|
+
// }
|
|
1532
|
+
// };
|
|
1533
|
+
|
|
1534
|
+
// helper to build specialist agents
|
|
1535
|
+
|
|
1536
|
+
const create_image_small = async function (prompt) {
|
|
1537
|
+
try {
|
|
1538
|
+
const response = await client.images.generate({
|
|
1539
|
+
model: 'dall-e-2',
|
|
1540
|
+
prompt,
|
|
1541
|
+
size: '256x256',
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1544
|
+
const imageUrl = response.data[0].url;
|
|
1545
|
+
const res = await fetch(imageUrl);
|
|
1546
|
+
if (!res.ok) throw new Error(`Failed to fetch image: ${res.status}`);
|
|
1547
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
1548
|
+
const imgBuffer = Buffer.from(arrayBuffer);
|
|
1549
|
+
|
|
1550
|
+
// Step 3. Resize down to 128×128 (fast, local)
|
|
1551
|
+
const resized = await sharp(imgBuffer).resize(128, 128).toFormat('png').toBuffer();
|
|
1552
|
+
|
|
1553
|
+
const base64 = resized.toString('base64');
|
|
1554
|
+
|
|
1555
|
+
return base64;
|
|
1556
|
+
} catch (err) {
|
|
1557
|
+
console.error('create_image error:', err);
|
|
1558
|
+
return '';
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
const create_image = async function (prompt, model = 'gpt-image-1-mini', size = '1024x1024', n = 1) {
|
|
1563
|
+
try {
|
|
1564
|
+
const response = await client.images.generate({
|
|
1565
|
+
model,
|
|
1566
|
+
prompt,
|
|
1567
|
+
size,
|
|
1568
|
+
n,
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
// Try to extract base64 directly
|
|
1572
|
+
const imgObj = response.data?.[0];
|
|
1573
|
+
if (!imgObj) throw new Error('No image returned from OpenAI');
|
|
1574
|
+
|
|
1575
|
+
// different SDK builds call it slightly differently, so normalize:
|
|
1576
|
+
const rawBase64 = imgObj.b64_json || imgObj.image_base64 || imgObj.base64 || imgObj.data || null;
|
|
1577
|
+
|
|
1578
|
+
if (!rawBase64) {
|
|
1579
|
+
// Fallback: if we *do* have a URL (some builds give both),
|
|
1580
|
+
// then we can download it.
|
|
1581
|
+
if (imgObj.url) {
|
|
1582
|
+
const res = await fetch(imgObj.url);
|
|
1583
|
+
if (!res.ok) {
|
|
1584
|
+
throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
|
|
1585
|
+
}
|
|
1586
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
1587
|
+
const fullImgBuffer = Buffer.from(arrayBuffer);
|
|
1588
|
+
|
|
1589
|
+
// Resize to 128x128
|
|
1590
|
+
const resized = await sharp(fullImgBuffer).resize(128, 128).toFormat('png').toBuffer();
|
|
1591
|
+
|
|
1592
|
+
return resized.toString('base64');
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
throw new Error('No base64 and no URL in image response');
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
// We got base64 from the API, so no extra fetch needed
|
|
1599
|
+
const fullImgBuffer = Buffer.from(rawBase64, 'base64');
|
|
1600
|
+
|
|
1601
|
+
// Resize to 128x128
|
|
1602
|
+
const resized = await sharp(fullImgBuffer).resize(128, 128).toFormat('png').toBuffer();
|
|
1603
|
+
|
|
1604
|
+
const thumbnailBase64 = resized.toString('base64');
|
|
1605
|
+
return thumbnailBase64;
|
|
1606
|
+
} catch (err) {
|
|
1607
|
+
console.error('create_image error:', err);
|
|
1608
|
+
return '';
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
const get_ai_doc = async function (req) {
|
|
1613
|
+
let { uid, _id } = req;
|
|
1614
|
+
|
|
1615
|
+
const project_db = await get_account_project_db(uid);
|
|
1616
|
+
try {
|
|
1617
|
+
let data = await project_db.get(_id);
|
|
1618
|
+
if (data?.studio_meta?.createdByUid !== uid) throw new Error('doctype not supported');
|
|
1619
|
+
return { code: 1, data };
|
|
1620
|
+
} catch (err) {
|
|
1621
|
+
return { code: -1, data: err.message };
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1625
|
+
|
|
1626
|
+
// try {
|
|
1627
|
+
// let data = await db.get(_id);
|
|
1628
|
+
// if (!['ai_agent', 'chat_conversation'].includes(data.docType)) throw new Error('doctype not supported');
|
|
1629
|
+
// return { code: 1, data };
|
|
1630
|
+
// } catch (err) {
|
|
1631
|
+
// return { code: -1, data: err.message };
|
|
1632
|
+
// }
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1635
|
+
export const get_ai_agents = async function (req) {
|
|
1636
|
+
let { uid, _id } = req;
|
|
1637
|
+
|
|
1638
|
+
try {
|
|
1639
|
+
// const system_project_id = _conf.superuser_account_ids[0];
|
|
1640
|
+
// const user_project_id = await get_account_project_id(uid);
|
|
1641
|
+
// debugger;
|
|
1642
|
+
// const db = get_xuda_couch('xuda_master');
|
|
1643
|
+
// const app_obj = await db.get(user_project_id);
|
|
1644
|
+
// const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
1645
|
+
// // const doc = await project_db.get('5b1_cmp_313d53e56c2d');
|
|
1646
|
+
// // const user_agents = await db.find({ selector: { docType: 'ai_agent', stat: 3 } });
|
|
1647
|
+
const project_db = await get_account_project_db(uid);
|
|
1648
|
+
|
|
1649
|
+
if (_id) return await get_ai_doc({ _id, uid });
|
|
1650
|
+
|
|
1651
|
+
const user_agents = await project_db.view('xuda', 'studio_docs_by_type', {
|
|
1652
|
+
key: 'ai_agent',
|
|
1653
|
+
include_docs: true,
|
|
1654
|
+
});
|
|
1655
|
+
|
|
1656
|
+
return { code: 1, data: { docs: user_agents.rows.map((row) => row.value) } };
|
|
1657
|
+
} catch (err) {
|
|
1658
|
+
return { code: -1, data: err.message };
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1662
|
+
|
|
1663
|
+
// if (_id) return await get_ai_doc({ _id });
|
|
1664
|
+
|
|
1665
|
+
// try {
|
|
1666
|
+
// const user_agents = await db.find({ selector: { docType: 'ai_agent', agent_ownership_type: 'user', uid, stat: 3 } });
|
|
1667
|
+
// const system_agents = await db.find({ selector: { docType: 'ai_agent', agent_ownership_type: 'system', stat: 3 } });
|
|
1668
|
+
|
|
1669
|
+
// return { code: 1, data: { docs: [...user_agents.docs, ...system_agents.docs] } };
|
|
1670
|
+
// } catch (err) {
|
|
1671
|
+
// return { code: -1, data: err.message };
|
|
1672
|
+
// }
|
|
1673
|
+
};
|
|
1674
|
+
|
|
1675
|
+
export const delete_ai_agent = async function (req) {
|
|
1676
|
+
let { agent_id, uid } = req;
|
|
1677
|
+
|
|
1678
|
+
const project_db = await get_account_project_db(uid);
|
|
1679
|
+
|
|
1680
|
+
try {
|
|
1681
|
+
let agent_doc = await project_db.get(agent_id);
|
|
1682
|
+
agent_doc.stat = 4;
|
|
1683
|
+
agent_doc.ts = Date.now();
|
|
1684
|
+
const data = await project_db.insert(agent_doc);
|
|
1685
|
+
|
|
1686
|
+
return { code: 1, data };
|
|
1687
|
+
} catch (err) {
|
|
1688
|
+
return { code: -1, data: err.message };
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1692
|
+
// try {
|
|
1693
|
+
// let agent_doc = await db.get(agent_id);
|
|
1694
|
+
// agent_doc.stat = 4;
|
|
1695
|
+
// agent_doc.ts = Date.now();
|
|
1696
|
+
// const data = await db.insert(agent_doc);
|
|
1697
|
+
|
|
1698
|
+
// return { code: 1, data };
|
|
1699
|
+
// } catch (err) {
|
|
1700
|
+
// return { code: -1, data: err.message };
|
|
1701
|
+
// }
|
|
1702
|
+
};
|
|
1703
|
+
|
|
1704
|
+
export const update_ai_agent = async function (req) {
|
|
1705
|
+
let { agent_id, agentConfig, uid } = req;
|
|
1706
|
+
|
|
1707
|
+
const project_db = await get_account_project_db(uid);
|
|
1708
|
+
|
|
1709
|
+
try {
|
|
1710
|
+
let agent_doc = await project_db.get(agent_id);
|
|
1711
|
+
// doc._id = agent_doc._id;
|
|
1712
|
+
// doc._rev = agent_doc._rev;
|
|
1713
|
+
agent_doc.ts = Date.now();
|
|
1714
|
+
agent_doc.agentConfig = agentConfig;
|
|
1715
|
+
|
|
1716
|
+
await upload_agent_files(agent_doc.agentConfig);
|
|
1717
|
+
|
|
1718
|
+
const data = await project_db.insert(agent_doc);
|
|
1719
|
+
|
|
1720
|
+
update_thumbnail('ai_agent', agent_doc, uid);
|
|
1721
|
+
return { code: 1, data };
|
|
1722
|
+
} catch (err) {
|
|
1723
|
+
return { code: -1, data: err.message };
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1727
|
+
// try {
|
|
1728
|
+
// const agent_doc = await db.get(agent_id);
|
|
1729
|
+
// doc._rev = agent_doc._rev;
|
|
1730
|
+
// doc.ts = Date.now();
|
|
1731
|
+
|
|
1732
|
+
// // for await (let tool of doc.agent_tools || []) {
|
|
1733
|
+
// // if (tool.type === 'file_search' && tool?.files?.length) {
|
|
1734
|
+
// // for await (let file of tool.files || []) {
|
|
1735
|
+
// // if (!file.file_id) {
|
|
1736
|
+
// // file.file_id = await upload_file_to_openai_storage(file.filename);
|
|
1737
|
+
// // if (!file.vector_file_id) {
|
|
1738
|
+
// // const ret = await client.vectorStores.files.create(_conf.OPENAI_VECTOR_STORE_ID, {
|
|
1739
|
+
// // file_id: file.file_id,
|
|
1740
|
+
// // });
|
|
1741
|
+
// // file.vector_store_id = ret.vector_store_id;
|
|
1742
|
+
// // }
|
|
1743
|
+
// // }
|
|
1744
|
+
// // }
|
|
1745
|
+
// // }
|
|
1746
|
+
// // }
|
|
1747
|
+
|
|
1748
|
+
// await upload_agent_files(doc);
|
|
1749
|
+
|
|
1750
|
+
// const data = await db.insert(doc);
|
|
1751
|
+
|
|
1752
|
+
// update_thumbnail('ai_agent', doc, 'agent_name');
|
|
1753
|
+
// return { code: 1, data };
|
|
1754
|
+
// } catch (err) {
|
|
1755
|
+
// return { code: -1, data: err.message };
|
|
1756
|
+
// }
|
|
1757
|
+
};
|
|
1758
|
+
|
|
1759
|
+
const upload_agent_files = async function (agentConfig) {
|
|
1760
|
+
for await (let tool of agentConfig.agent_tools || []) {
|
|
1761
|
+
if (tool.type === 'file_search' && !_.isEmpty(tool.file)) {
|
|
1762
|
+
if (!tool.file.file_id) {
|
|
1763
|
+
tool.file.file_id = await upload_file_to_openai_storage(tool.file.name);
|
|
1764
|
+
if (!tool.file.vector_file_id) {
|
|
1765
|
+
const ret = await client.vectorStores.files.create(_conf.OPENAI_VECTOR_STORE_ID, {
|
|
1766
|
+
file_id: tool.file.file_id,
|
|
1767
|
+
});
|
|
1768
|
+
tool.file.vector_store_id = ret.vector_store_id;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
// if (tool.type === 'file_search' && tool?.files?.length) {
|
|
1774
|
+
// for await (let file of tool.files || []) {
|
|
1775
|
+
// if (!file.file_id) {
|
|
1776
|
+
// file.file_id = await upload_file_to_openai_storage(file.filename);
|
|
1777
|
+
// if (!file.vector_file_id) {
|
|
1778
|
+
// const ret = await client.vectorStores.files.create(_conf.OPENAI_VECTOR_STORE_ID, {
|
|
1779
|
+
// file_id: file.file_id,
|
|
1780
|
+
// });
|
|
1781
|
+
// file.vector_store_id = ret.vector_store_id;
|
|
1782
|
+
// }
|
|
1783
|
+
// }
|
|
1784
|
+
// }
|
|
1785
|
+
// }
|
|
1786
|
+
}
|
|
1787
|
+
};
|
|
1788
|
+
|
|
1789
|
+
const validate_ai_agent = async function (req) {
|
|
1790
|
+
// "tool_type": {
|
|
1791
|
+
// "name": "Tool Type",
|
|
1792
|
+
// "description": "",
|
|
1793
|
+
// "type": "array",
|
|
1794
|
+
// "enum": [
|
|
1795
|
+
// "web_search",
|
|
1796
|
+
// "file_search",
|
|
1797
|
+
// "program",
|
|
1798
|
+
// "mcp",
|
|
1799
|
+
// "plugin",
|
|
1800
|
+
// "ai_agent",
|
|
1801
|
+
// "table",
|
|
1802
|
+
// "image_generate"
|
|
1803
|
+
// ],
|
|
1804
|
+
// "mandatory": true
|
|
1805
|
+
// }
|
|
1806
|
+
};
|
|
1807
|
+
|
|
1808
|
+
export const create_ai_agent = async function (req) {
|
|
1809
|
+
const { agentConfig, uid } = req;
|
|
1810
|
+
|
|
1811
|
+
const { account_project_id, account_info } = await get_account_object(uid);
|
|
1812
|
+
|
|
1813
|
+
try {
|
|
1814
|
+
const param = { uid, properties: { menuName: agentConfig.agent_name, menuTitle: agentConfig.agent_name, menuType: 'ai_agent' }, checkedInUserName: account_info.first_name + ' ' + account_info.last_name, app_id: account_project_id, parentId: 'ai_agents' };
|
|
1815
|
+
var agent_doc = createDoc(param);
|
|
1816
|
+
agent_doc.agentConfig = agentConfig;
|
|
1817
|
+
|
|
1818
|
+
await upload_agent_files(agent_doc.agentConfig);
|
|
1819
|
+
|
|
1820
|
+
// const data = await db.insert(agent_doc);
|
|
1821
|
+
const project_db = await get_account_project_db(uid);
|
|
1822
|
+
const data = await project_db.insert(agent_doc);
|
|
1823
|
+
|
|
1824
|
+
update_thumbnail('ai_agent', agent_doc, uid);
|
|
1825
|
+
|
|
1826
|
+
return { code: 1, data };
|
|
1827
|
+
} catch (err) {
|
|
1828
|
+
return { code: -1, data: err.message };
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
|
|
1832
|
+
const update_thumbnail = function (type, doc, uid) {
|
|
1833
|
+
let prompt = '';
|
|
1834
|
+
|
|
1835
|
+
setTimeout(async () => {
|
|
1836
|
+
try {
|
|
1837
|
+
const project_db = await get_account_project_db(uid);
|
|
1838
|
+
let db_doc = await project_db.get(doc._id);
|
|
1839
|
+
|
|
1840
|
+
switch (type) {
|
|
1841
|
+
case 'ai_agent': {
|
|
1842
|
+
if (db_doc.studio_meta.base64 && db_doc.properties.menuName === db_doc.properties.menuName) return;
|
|
1843
|
+
|
|
1844
|
+
prompt = `create image:
|
|
1845
|
+
|
|
1846
|
+
Overview
|
|
1847
|
+
The image portrays a futuristic humanoid or abstract AI entity designed to represent a specific role — such as a sales assistant, data analyst, creative advisor, or search agent. The scene blends cutting-edge technology with an artistic or cinematic atmosphere, creating a visual narrative of intelligence, precision, and innovation.
|
|
1848
|
+
|
|
1849
|
+
Subject
|
|
1850
|
+
|
|
1851
|
+
The central figure (or core system) embodies artificial intelligence personified.
|
|
1852
|
+
It may appear as a humanoid robot, a digital avatar, or a symbolic interface made of light and code. The features — whether facial, mechanical, or abstract — convey awareness, focus, and adaptability. The subject’s posture and expression (if applicable) suggest calm confidence, curiosity, or analytical engagement.
|
|
1853
|
+
|
|
1854
|
+
🕶 Appearance
|
|
1855
|
+
|
|
1856
|
+
The AI’s form is designed to match its role:
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
${doc.name}
|
|
1861
|
+
|
|
1862
|
+
Reflective or metallic textures emphasize intelligence and sophistication, while the surrounding lighting harmonizes with the AI’s color scheme to project its purpose and tone.
|
|
1863
|
+
|
|
1864
|
+
Interface & Interaction
|
|
1865
|
+
|
|
1866
|
+
The AI often interacts with floating holographic or projected interfaces, symbolizing its digital workspace.
|
|
1867
|
+
Common elements include:
|
|
1868
|
+
|
|
1869
|
+
Graphs, data panels, dashboards, or search bars.
|
|
1870
|
+
|
|
1871
|
+
Abstract geometric shapes representing logic or neural activity.
|
|
1872
|
+
|
|
1873
|
+
Light trails or motion blur effects suggesting processing or communication.
|
|
1874
|
+
|
|
1875
|
+
The AI engaging with gestures — pointing, typing in mid-air, or scanning visual elements.
|
|
1876
|
+
|
|
1877
|
+
These details illustrate the agent’s domain: sales forecasting, query resolution, creative generation, or data interpretation.
|
|
1878
|
+
|
|
1879
|
+
Environment & Lighting
|
|
1880
|
+
|
|
1881
|
+
The environment bridges the real and virtual worlds — a fusion of architecture, code, and energy.
|
|
1882
|
+
It may include:
|
|
1883
|
+
|
|
1884
|
+
Corporate or futuristic interiors (clean walls, neon highlights, glass surfaces).
|
|
1885
|
+
|
|
1886
|
+
Abstract digital landscapes filled with data grids or holographic streams.
|
|
1887
|
+
|
|
1888
|
+
Natural or surreal elements (roses, water reflections, sky motifs) that humanize the setting.
|
|
1889
|
+
|
|
1890
|
+
Lighting contrasts — blue/orange, violet/silver, gold/teal — create emotional tension between logic and inspiration.
|
|
1891
|
+
|
|
1892
|
+
Mood & Style
|
|
1893
|
+
|
|
1894
|
+
The overall mood is visionary and intelligent, evoking trust and advancement.
|
|
1895
|
+
The visual style can vary:
|
|
1896
|
+
|
|
1897
|
+
Cyber-surreal: dreamlike, poetic, glowing.
|
|
1898
|
+
|
|
1899
|
+
Corporate-futuristic: clean, efficient, minimalistic.
|
|
1900
|
+
|
|
1901
|
+
Cinematic-AI realism: detailed, photorealistic, story-driven.
|
|
1902
|
+
|
|
1903
|
+
Composition centers the AI or interface as the focal point, surrounded by hints of motion, light, and context. The image symbolizes the fusion of human creativity and machine intelligence.`;
|
|
1904
|
+
db_doc.studio_meta.thumbnail_request_ts = Date.now();
|
|
1905
|
+
const base64 = await create_image(prompt);
|
|
1906
|
+
db_doc.studio_meta.base64 = base64;
|
|
1907
|
+
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
case 'conversation': {
|
|
1911
|
+
prompt = `create image: ${doc.title}`;
|
|
1912
|
+
db_doc.thumbnail_request_ts = Date.now();
|
|
1913
|
+
const base64 = await create_image(prompt);
|
|
1914
|
+
db_doc.base64 = base64;
|
|
1915
|
+
break;
|
|
1916
|
+
}
|
|
1917
|
+
default:
|
|
1918
|
+
prompt = '';
|
|
1919
|
+
break;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
const save_ret = await project_db.insert(db_doc);
|
|
1923
|
+
|
|
1924
|
+
// const db = get_xuda_couch('xuda_contacts');
|
|
1925
|
+
|
|
1926
|
+
// let db_doc = await db.get(doc._id);
|
|
1927
|
+
// if (db_doc.base64 && db_doc[prop] === doc[prop]) return;
|
|
1928
|
+
// const base64 = await create_image(prompt);
|
|
1929
|
+
// db_doc.base64 = base64;
|
|
1930
|
+
// const save_ret = await db.insert(db_doc);
|
|
1931
|
+
} catch (error) {
|
|
1932
|
+
debugger;
|
|
1933
|
+
}
|
|
1934
|
+
}, 500);
|
|
1935
|
+
};
|
|
1936
|
+
|
|
1937
|
+
const upload_file_to_openai_storage = async function (file_path) {
|
|
1938
|
+
const filename = path.basename(file_path);
|
|
1939
|
+
const db = get_xuda_couch('xuda_drive');
|
|
1940
|
+
const ret = await db.find({
|
|
1941
|
+
selector: {
|
|
1942
|
+
docType: 'user_drive',
|
|
1943
|
+
type: 'file',
|
|
1944
|
+
file_path: path.dirname(file_path) === '.' ? '/' : path.dirname(file_path),
|
|
1945
|
+
originalname: filename,
|
|
1946
|
+
stat: 3,
|
|
1947
|
+
},
|
|
1948
|
+
});
|
|
1949
|
+
const doc = ret?.docs?.[0];
|
|
1950
|
+
const _region = process.env.XUDA_HOSTNAME; // "eu.xuda.io"; //
|
|
1951
|
+
let file_location = doc?.bucket?.[_region]?.Location;
|
|
1952
|
+
|
|
1953
|
+
try {
|
|
1954
|
+
const res = await fetch(file_location);
|
|
1955
|
+
|
|
1956
|
+
if (!res.ok) throw new Error(`Failed to download file: ${res.statusText}`);
|
|
1957
|
+
|
|
1958
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
1959
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
1960
|
+
|
|
1961
|
+
const tmp_file = '/tmp/' + filename;
|
|
1962
|
+
await writeFile(tmp_file, buffer);
|
|
1963
|
+
// 3️⃣ Upload file to OpenAI
|
|
1964
|
+
const stream = fs.createReadStream(tmp_file);
|
|
1965
|
+
const uploadedFile = await client.files.create({
|
|
1966
|
+
file: stream,
|
|
1967
|
+
purpose: 'assistants',
|
|
1968
|
+
});
|
|
1969
|
+
|
|
1970
|
+
// const file = await toFile(stream, filename, { purpose: 'assistants' });
|
|
1971
|
+
// debugger;
|
|
1972
|
+
// const uploadedFile = await client.vectorStores.files.create(_conf.OPENAI_VECTOR_STORE_ID, {
|
|
1973
|
+
// file_id: tmp_file,
|
|
1974
|
+
// });
|
|
1975
|
+
|
|
1976
|
+
console.log('📂 Uploaded file:', uploadedFile.id);
|
|
1977
|
+
unlink(tmp_file);
|
|
1978
|
+
return uploadedFile.id;
|
|
1979
|
+
} catch (err) {
|
|
1980
|
+
console.error(err);
|
|
1981
|
+
}
|
|
1982
|
+
};
|
|
1983
|
+
|
|
1984
|
+
const get_account_object = async function (uid) {
|
|
1985
|
+
const db = get_xuda_couch('xuda_accounts');
|
|
1986
|
+
const account_obj = await db.get(uid);
|
|
1987
|
+
return account_obj;
|
|
1988
|
+
};
|
|
1989
|
+
|
|
1990
|
+
const get_account_project_id = async function (uid) {
|
|
1991
|
+
const account_obj = await get_account_object(uid);
|
|
1992
|
+
return account_obj.account_project_id;
|
|
1993
|
+
};
|
|
1994
|
+
|
|
1995
|
+
const get_account_project_db = async function (uid) {
|
|
1996
|
+
const user_project_id = await get_account_project_id(uid);
|
|
1997
|
+
const db = get_xuda_couch('xuda_master');
|
|
1998
|
+
const app_obj = await db.get(user_project_id);
|
|
1999
|
+
const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
2000
|
+
return project_db;
|
|
2001
|
+
};
|
|
2002
|
+
|
|
2003
|
+
setTimeout(async () => {
|
|
2004
|
+
const app_id = 'prjac771215b7a70d86bc3a8435bb18c885'; //'prj3937cb6f9a31c8c7dea25055bba845b1'; //
|
|
2005
|
+
const uid = 'd39126e0e2c51ffbd1aad10709fc8335';
|
|
2006
|
+
|
|
2007
|
+
// await init_studio_units();
|
|
2008
|
+
let ret;
|
|
2009
|
+
// ret = await update_ai_agent({
|
|
2010
|
+
// uid: 'd39126e0e2c51ffbd1aad10709fc8335',
|
|
2011
|
+
// agent_id: '392_agn_ddbca7c25457',
|
|
2012
|
+
// agentConfig: {
|
|
2013
|
+
// agent_instructions: 'docxsite business plan agent response with detailed answers using bp',
|
|
2014
|
+
// agent_tools: [
|
|
2015
|
+
// {
|
|
2016
|
+
// type: 'file_search',
|
|
2017
|
+
// file: {
|
|
2018
|
+
// name: 'docxsite-bp.xlsx.pdf',
|
|
2019
|
+
// sizeInBytes: 250222,
|
|
2020
|
+
// size: '244.36 KB',
|
|
2021
|
+
// extension: 'pdf',
|
|
2022
|
+
// type: 'file',
|
|
2023
|
+
// access_link: 'https://dev.xuda.io/user-drive/undefined/drv_d39126e0e2c51ffbd1aad10709fc8335_3243be15c292843c9d0901904513cd1f.pdf',
|
|
2024
|
+
// is_archive: false,
|
|
2025
|
+
// path: '/',
|
|
2026
|
+
// date_created: 1761659838034,
|
|
2027
|
+
// date_modified: 1761659838034,
|
|
2028
|
+
// file_path: '/docxsite-bp.xlsx.pdf',
|
|
2029
|
+
// tags: [],
|
|
2030
|
+
// },
|
|
2031
|
+
// name: 'bp',
|
|
2032
|
+
// },
|
|
2033
|
+
// ],
|
|
2034
|
+
// agent_name: 'Docxsite bp',
|
|
2035
|
+
// },
|
|
2036
|
+
// });
|
|
2037
|
+
|
|
2038
|
+
// ret = upload_file_to_openai_storage('/docxsite-bp.xlsx.pdf');
|
|
2039
|
+
// ret = await create_image("'Generate an image of gray tabby cat hugging an otter with an orange scarf'");
|
|
2040
|
+
// ret = await submit_chat_conversation({ prompt: 'my name is Boaz' });
|
|
2041
|
+
// ret = await submit_chat_conversation({ prompt: 'what is my name', conversation_id: ret.data.conversation_doc._id });
|
|
2042
|
+
// const ret = await create_studio_app('crm');
|
|
2043
|
+
// ret = await submit_chat_gpt_prompt({ prompt: `what is xuda` });
|
|
2044
|
+
// const ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'crm app', object_unit: 'app', uid, app_id });
|
|
2045
|
+
// ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'products', object_unit: 'table', uid, app_id });
|
|
2046
|
+
// ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'test3', object_unit: 'folder', uid, app_id });
|
|
2047
|
+
// ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'contact contact form', object_unit: 'component', uid, app_id });
|
|
2048
|
+
// ret = await submit_agentic_studio_chat_gpt_prompt({ user_prompt: 'get data from tasks by task id', object_unit: 'get_data', uid, app_id });
|
|
2049
|
+
console.log(ret);
|
|
2050
|
+
|
|
2051
|
+
// init({}, {}, _, true, null, null, UglifyJS, JSON5, _conf, false, z);
|
|
2052
|
+
// const schema = get_zod_schema('component');
|
|
2053
|
+
|
|
2054
|
+
// const db = get_xuda_couch('xuda_master');
|
|
2055
|
+
// const app_obj = await db.get(app_id);
|
|
2056
|
+
// const project_db = get_xuda_couch(app_obj.app_db_name);
|
|
2057
|
+
// const doc = await project_db.get('5b1_cmp_313d53e56c2d');
|
|
2058
|
+
|
|
2059
|
+
////////////////////
|
|
2060
|
+
// let err_ret = [];
|
|
2061
|
+
// const addValidationError = (code, data) => {
|
|
2062
|
+
// err_ret.push({
|
|
2063
|
+
// code,
|
|
2064
|
+
// data,
|
|
2065
|
+
// type: 'E',
|
|
2066
|
+
// category: 'document',
|
|
2067
|
+
// structure_error: true,
|
|
2068
|
+
// });
|
|
2069
|
+
// };
|
|
2070
|
+
//////////////////
|
|
2071
|
+
|
|
2072
|
+
// const result = schema.safeParse({});
|
|
2073
|
+
// if (!result.success) {
|
|
2074
|
+
// console.log(result.error.errors); // Array of error objects
|
|
2075
|
+
// result.error.errors.forEach((error) => {
|
|
2076
|
+
// // console.log(`Path: ${error.path}, Message: ${error.message}`);
|
|
2077
|
+
// const msg = `${error.message}: ${error.path}(${error.expected})`;
|
|
2078
|
+
// addValidationError('CHK_MSG_OBJ_GEN_000', msg);
|
|
2079
|
+
// });
|
|
2080
|
+
// console.log(err_ret);
|
|
2081
|
+
// } else {
|
|
2082
|
+
// console.log('Validation succeeded:', result.data);
|
|
2083
|
+
// }
|
|
2084
|
+
|
|
2085
|
+
// const jsonSchema = zodToJsonSchema(schema);
|
|
2086
|
+
// // console.log(jsonSchema);
|
|
2087
|
+
// console.log(JSON.stringify(jsonSchema, null, 2));
|
|
2088
|
+
|
|
2089
|
+
// console.log(
|
|
2090
|
+
// check(
|
|
2091
|
+
// createDoc({
|
|
2092
|
+
// uid: '11',
|
|
2093
|
+
// app_id: 'prj-444',
|
|
2094
|
+
// menuType: 'folder',
|
|
2095
|
+
// checkedInUserName: 'boaz',
|
|
2096
|
+
// parentId: '',
|
|
2097
|
+
// }),
|
|
2098
|
+
// ),
|
|
2099
|
+
// );
|
|
2100
|
+
|
|
2101
|
+
// const vectorStore = await client.beta.vector_stores.create({
|
|
2102
|
+
// name: 'Xuda Docs Vector Store',
|
|
2103
|
+
// });
|
|
2104
|
+
// console.log('Vector Store ID:', vectorStore.id);
|
|
2105
|
+
// console.log('OpenAI version:', (await import('openai/package.json')).version);
|
|
2106
|
+
// console.log('has beta?', !!client.beta);
|
|
2107
|
+
// console.log('has vector_stores?', !!client.beta?.vector_stores);
|
|
2108
|
+
// console.log('keys on vector_stores:', Object.keys(client.beta?.vector_stores || {}));
|
|
2109
|
+
|
|
2110
|
+
// const vectorStore = await client.vectorStores.create({
|
|
2111
|
+
// name: 'Xuda Docs Vector Store',
|
|
2112
|
+
// });
|
|
2113
|
+
// console.log(vectorStore);
|
|
2114
|
+
}, 1000);
|
|
2115
|
+
|
|
2116
|
+
// PROMPT OBJECT UNIT OUTPUT
|
|
2117
|
+
//================================================================== ==================== =====================
|
|
2118
|
+
// create customer table
|
|
2119
|
+
// fill 5 rows to customer table
|
|
2120
|
+
// describe the customer table
|
|
2121
|
+
// create router for the app
|
|
2122
|
+
// create form program and save the data in the customer table
|
|
2123
|
+
// generate 10 buttons using tailwind
|
|
2124
|
+
// describe the program
|
|
2125
|
+
// create crm app
|
|
2126
|
+
// change text color
|
|
2127
|
+
// fetch only new customers using mongo query
|
|
2128
|
+
// create dashboard program for crm app
|
|
2129
|
+
// find diffs between two objects
|