@xuda.io/ai_module 1.1.5552 → 1.1.5554

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.
Files changed (2) hide show
  1. package/index.mjs +476 -349
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -4109,6 +4109,313 @@ const chat_email = async function (req, job_id, headers) {
4109
4109
  return { code: -15, data: err.message };
4110
4110
  }
4111
4111
  };
4112
+
4113
+ const get_ai_agent_tools = async function ({ ai_agent_doc, agent_id, reference_type, prompt_suggestion_activated, chat_suggestion_activated, gtp_token, uid, account_profile_info, job_id, headers, context, app_id }) {
4114
+ let tools = [];
4115
+ let tool_resources = {};
4116
+ let eligible_agent = true;
4117
+
4118
+ for (const [key, val] of Object.entries(ai_agent_doc?.agentConfig?.agent_tools || [])) {
4119
+ const { name = '', description = '' } = val;
4120
+ switch (val.type) {
4121
+ case 'web_search': {
4122
+ tools.push(webSearchTool());
4123
+ break;
4124
+ }
4125
+
4126
+ case 'mcp': {
4127
+ if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4128
+ eligible_agent = false;
4129
+ break;
4130
+ }
4131
+
4132
+ tools.push(
4133
+ hostedMcpTool({
4134
+ serverLabel: 'mcp_' + (val?.name?.replaceAll(' ', '_') || key),
4135
+ serverUrl: val.url,
4136
+ headers: {
4137
+ Authorization: `Bearer ${val.authentication_key || gtp_token}`,
4138
+ 'X-gtp-token': 'true',
4139
+ 'Content-Type': 'application/json',
4140
+ },
4141
+ require_approval: 'never',
4142
+ }),
4143
+ );
4144
+ break;
4145
+ }
4146
+
4147
+ case 'cpi': {
4148
+ if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4149
+ eligible_agent = false;
4150
+ break;
4151
+ }
4152
+ continue;
4153
+ try {
4154
+ debugger;
4155
+ const api_allow_methods = Object.keys(_conf.cpi_methods);
4156
+ for (const method_name of api_allow_methods || []) {
4157
+ const method_prop = _conf.cpi_methods[method_name];
4158
+
4159
+ if (!method_prop) continue;
4160
+ if (method_prop.private) continue;
4161
+ if (!method_prop.description) continue;
4162
+
4163
+ let inputSchema = {};
4164
+
4165
+ const get_z_item = function (key, val) {
4166
+ let prop = {};
4167
+ if (val.type === 'object' && val.items) {
4168
+ for (const [item_key, item_val] of Object.entries(val.items.properties)) {
4169
+ prop[item_key] = get_z_item(item_key, item_val);
4170
+ if (!val?.items?.required?.includes(item_key)) {
4171
+ prop[item_key] = prop[item_key].optional();
4172
+ }
4173
+ }
4174
+ }
4175
+
4176
+ if (val.type === 'array') {
4177
+ prop = get_z_item('', val.items);
4178
+ }
4179
+
4180
+ let _z = z[val.type](prop);
4181
+
4182
+ if (!val.mandatory) {
4183
+ _z = _z.optional();
4184
+ }
4185
+
4186
+ if (val.enum) {
4187
+ _z = z.enum(val.enum);
4188
+ }
4189
+
4190
+ let valid_values = '';
4191
+ if (val.options) {
4192
+ valid_values = val.options.join(', ');
4193
+ }
4194
+ if (val.description) {
4195
+ const desc = val.name || key.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase());
4196
+ _z = _z.describe((desc ? desc + ' - ' : '') + val.description + (valid_values ? ' Valid values: ' + valid_values : ''));
4197
+ }
4198
+
4199
+ return _z;
4200
+ };
4201
+
4202
+ if (method_prop.fields) {
4203
+ try {
4204
+ for (const [key, val] of Object.entries(method_prop.fields)) {
4205
+ inputSchema[key] = get_z_item(key, val);
4206
+ }
4207
+ } catch (error) {
4208
+ debugger;
4209
+ }
4210
+ }
4211
+ try {
4212
+ const tool_name = method_name.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase());
4213
+ tools.push(
4214
+ tool({
4215
+ name: tool_name.substring(0, 60),
4216
+ description: method_prop.description,
4217
+ parameters: z.object(inputSchema),
4218
+ async execute(e, RunContext) {
4219
+ const params = e;
4220
+ try {
4221
+ const response = await fetch(`http://localhost:3007/cpi/${method_name}`, {
4222
+ method: 'POST',
4223
+ headers: {
4224
+ Accept: 'application/json',
4225
+ 'Content-Type': 'application/json',
4226
+ },
4227
+ body: JSON.stringify({ ...params, ...{ gtp_token } }),
4228
+ });
4229
+ const ret = await response.json();
4230
+ return {
4231
+ content: [{ type: 'text', text: JSON.stringify(ret || '', null, 2) }],
4232
+ };
4233
+ } catch (err) {
4234
+ return 'unknown';
4235
+ }
4236
+ },
4237
+ }),
4238
+ );
4239
+ } catch (error) {
4240
+ debugger;
4241
+ }
4242
+ }
4243
+ } catch (error) {
4244
+ debugger;
4245
+ }
4246
+ break;
4247
+ }
4248
+
4249
+ case 'image_generate': {
4250
+ if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4251
+ eligible_agent = false;
4252
+ break;
4253
+ }
4254
+ tools.push(
4255
+ tool({
4256
+ name: name.substring(0, 60),
4257
+ description,
4258
+ parameters: z.object({
4259
+ prompt: z.string().describe('The prompt for the image.'),
4260
+ numGenerations: z.number().int().describe('Number generations to image create.').default(3),
4261
+ }),
4262
+ async execute(e, RunContext) {
4263
+ debugger;
4264
+ const { prompt, numGenerations } = e;
4265
+
4266
+ try {
4267
+ let imgTags = '';
4268
+ const images_arr = await create_and_upload_image_to_drive('workspace', 'Chat Images', agent_id, prompt, numGenerations, uid, account_profile_info.app_id, job_id, headers, null, null, account_profile_info);
4269
+ for (const img_obj of images_arr) {
4270
+ imgTags += `<img src="${img_obj.file_url}" alt="${prompt}" style="max-width: 100%; border-radius: 8px;" />`;
4271
+ }
4272
+
4273
+ return imgTags;
4274
+ } catch (err) {
4275
+ console.error('Image Tool Error:', err);
4276
+ return `Error generating image: ${err.message}`;
4277
+ }
4278
+ },
4279
+ }),
4280
+ );
4281
+ break;
4282
+ }
4283
+
4284
+ case 'table': {
4285
+ const table_id = val.prog_id;
4286
+ context.table_id = table_id;
4287
+ tools.push(get_studio_table_info_by_table_id_tool);
4288
+
4289
+ tools.push(
4290
+ add_data_to_table_agent.asTool({
4291
+ toolName: 'add data to table',
4292
+ toolDescription: `add data to table`,
4293
+ }),
4294
+ );
4295
+
4296
+ tools.push(
4297
+ fetch_table_data_agent.asTool({
4298
+ toolName: 'Fetch Table Data Agent',
4299
+ toolDescription: `fetch data from a table`,
4300
+ }),
4301
+ );
4302
+
4303
+ tools.push(
4304
+ delete_table_doc.asTool({
4305
+ toolName: 'Delete Table Doc',
4306
+ toolDescription: `The tool delete document from the database, need to ask for table`,
4307
+ }),
4308
+ );
4309
+
4310
+ break;
4311
+ }
4312
+
4313
+ case 'file_search': {
4314
+ if (val?.file?.vector_store_id) {
4315
+ tools.push(fileSearchTool(val.file.vector_store_id));
4316
+ }
4317
+
4318
+ if (val?.youtube?.vector_store_id) {
4319
+ tools.push(fileSearchTool(val.youtube.vector_store_id));
4320
+ }
4321
+
4322
+ break;
4323
+ }
4324
+
4325
+ case 'ai_agent': {
4326
+ if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4327
+ eligible_agent = false;
4328
+ break;
4329
+ }
4330
+
4331
+ let opt = {
4332
+ selector: {
4333
+ docType: 'studio',
4334
+ stat: 3,
4335
+ 'properties.menuType': 'ai_agent',
4336
+ },
4337
+ limit: 9999,
4338
+ };
4339
+
4340
+ if (val.ai_agent_id) {
4341
+ opt.selector._id = val.ai_agent_id;
4342
+ }
4343
+
4344
+ const user_agents = await db_module.find_app_couch_query(ai_agent_doc?.reference_doc?.studio_meta?.shared_from_app_id || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_id || app_id, opt);
4345
+ for (const agent_doc of user_agents.docs) {
4346
+ const agent = new Agent({
4347
+ name: agent_doc.agent_name.substring(0, 60),
4348
+ instructions: agent_doc.agent_instructions,
4349
+ });
4350
+
4351
+ tools.push(
4352
+ agent.asTool({
4353
+ toolName: agent_doc.agent_name,
4354
+ toolDescription: agent_doc.agent_instructions,
4355
+ }),
4356
+ );
4357
+ }
4358
+ break;
4359
+ }
4360
+ case 'plugin': {
4361
+ if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4362
+ eligible_agent = false;
4363
+ break;
4364
+ }
4365
+
4366
+ if (!val.plugin_id) {
4367
+ throw new Error('undefined plugin_id');
4368
+ }
4369
+ if (!val.plugin_method) {
4370
+ throw new Error('undefined method');
4371
+ }
4372
+
4373
+ const { plugin_method, type, plugin_id, ...params } = val;
4374
+
4375
+ const plugin_tool = await get_plugin_tool(
4376
+ ai_agent_doc?.reference_doc?.studio_meta?.shared_from_app_id || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_id || account_profile_info.app_id,
4377
+ ai_agent_doc?.reference_doc?.studio_meta?.shared_from_uid || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_uid || uid,
4378
+ val.plugin_id,
4379
+ val.plugin_method,
4380
+ params,
4381
+ undefined,
4382
+ undefined,
4383
+ ai_agent_doc,
4384
+ );
4385
+
4386
+ tools.push(plugin_tool);
4387
+
4388
+ break;
4389
+ }
4390
+ default:
4391
+ break;
4392
+ }
4393
+ }
4394
+
4395
+ return { tools, tool_resources, eligible_agent, context };
4396
+ };
4397
+
4398
+ const load_ai_agent_doc = async function (app_id, agent_id) {
4399
+ try {
4400
+ let ai_agent_doc = await db_module.get_app_couch_doc_native(app_id, agent_id);
4401
+ if (ai_agent_doc.studio_meta.shared_from_uid) {
4402
+ const reference_doc = _.cloneDeep(ai_agent_doc);
4403
+ await get_account_default_project_id(ai_agent_doc.studio_meta.shared_from_uid);
4404
+ ai_agent_doc = await db_module.get_app_couch_doc_native(app_id, ai_agent_doc.studio_meta.share_item_id);
4405
+ ai_agent_doc.reference_doc = reference_doc;
4406
+ } else if (ai_agent_doc.studio_meta.installed_from_app_uid) {
4407
+ const reference_doc = _.cloneDeep(ai_agent_doc);
4408
+ await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid);
4409
+ ai_agent_doc = await db_module.get_app_couch_doc_native(app_id, ai_agent_doc.studio_meta.share_item_id);
4410
+ ai_agent_doc.reference_doc = reference_doc;
4411
+ }
4412
+
4413
+ return ai_agent_doc;
4414
+ } catch (err) {
4415
+ throw new Error(err.message);
4416
+ }
4417
+ };
4418
+
4112
4419
  const ai_chat_conversation = async function (req, job_id, headers) {
4113
4420
  const { uid, gtp_token, profile_id, conversation_item_id } = req;
4114
4421
  const account_profile_info = await get_active_account_profile_info(uid, profile_id);
@@ -4414,23 +4721,7 @@ const ai_chat_conversation = async function (req, job_id, headers) {
4414
4721
 
4415
4722
  for (const agent_id of local_ai_agents) {
4416
4723
  try {
4417
- let ai_agent_doc;
4418
- try {
4419
- ai_agent_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, agent_id);
4420
- if (ai_agent_doc.studio_meta.shared_from_uid) {
4421
- const reference_doc = _.cloneDeep(ai_agent_doc);
4422
- const app_id = await get_account_default_project_id(ai_agent_doc.studio_meta.shared_from_uid);
4423
- ai_agent_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, ai_agent_doc.studio_meta.share_item_id);
4424
- ai_agent_doc.reference_doc = reference_doc;
4425
- } else if (ai_agent_doc.studio_meta.installed_from_app_uid) {
4426
- const reference_doc = _.cloneDeep(ai_agent_doc);
4427
- const app_id = await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid);
4428
- ai_agent_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, ai_agent_doc.studio_meta.share_item_id);
4429
- ai_agent_doc.reference_doc = reference_doc;
4430
- }
4431
- } catch (err) {
4432
- throw new Error(err.message);
4433
- }
4724
+ let ai_agent_doc = await load_ai_agent_doc(account_profile_info.app_id, agent_id);
4434
4725
 
4435
4726
  if (prompt_suggestion_activated || chat_suggestion_activated || reference_type === 'ai_agents') {
4436
4727
  if (ai_agent_doc?.agentConfig?.agent_ai_model) {
@@ -4442,330 +4733,23 @@ const ai_chat_conversation = async function (req, job_id, headers) {
4442
4733
  modelSettings.toolChoice = 'required';
4443
4734
  }
4444
4735
 
4445
- let tools = [];
4446
- let tool_resources = {};
4447
-
4448
- for (const [key, val] of Object.entries(ai_agent_doc?.agentConfig?.agent_tools || [])) {
4449
- const { name = '', description = '' } = val;
4450
- switch (val.type) {
4451
- case 'web_search': {
4452
- //hosted_web_search
4453
- tools.push(webSearchTool());
4454
- break;
4455
- }
4456
-
4457
- case 'mcp': {
4458
- if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4459
- eligible_agent = false;
4460
- break;
4461
- }
4462
-
4463
- tools.push(
4464
- hostedMcpTool({
4465
- serverLabel: 'mcp_' + (val?.name?.replaceAll(' ', '_') || key), //ai_agent_doc.properties.menuName,
4466
- serverUrl: val.url,
4467
- headers: {
4468
- Authorization: `Bearer ${val.authentication_key || gtp_token}`,
4469
- 'X-gtp-token': 'true',
4470
- 'Content-Type': 'application/json',
4471
- },
4472
- require_approval: 'never',
4473
- }),
4474
- );
4475
- break;
4476
- }
4477
-
4478
- case 'cpi': {
4479
- if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4480
- eligible_agent = false;
4481
- break;
4482
- }
4483
- continue;
4484
- try {
4485
- debugger;
4486
- const api_allow_methods = Object.keys(_conf.cpi_methods);
4487
- for (const method_name of api_allow_methods || []) {
4488
- const method_prop = _conf.cpi_methods[method_name];
4489
-
4490
- if (!method_prop) continue;
4491
- if (method_prop.private) continue;
4492
- if (!method_prop.description) continue;
4493
-
4494
- let inputSchema = {};
4495
-
4496
- const get_z_item = function (key, val) {
4497
- let prop = {};
4498
- if (val.type === 'object' && val.items) {
4499
- for (const [item_key, item_val] of Object.entries(val.items.properties)) {
4500
- prop[item_key] = get_z_item(item_key, item_val);
4501
- if (!val?.items?.required?.includes(item_key)) {
4502
- prop[item_key] = prop[item_key].optional();
4503
- }
4504
- }
4505
- }
4506
-
4507
- if (val.type === 'array') {
4508
- prop = get_z_item('', val.items);
4509
- }
4510
-
4511
- let _z = z[val.type](prop);
4512
-
4513
- if (!val.mandatory) {
4514
- _z = _z.optional();
4515
- }
4516
-
4517
- if (val.enum) {
4518
- _z = z.enum(val.enum);
4519
- }
4520
-
4521
- let valid_values = '';
4522
- if (val.options) {
4523
- valid_values = val.options.join(', ');
4524
- }
4525
- if (val.description) {
4526
- const desc = val.name || key.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase());
4527
- _z = _z.describe((desc ? desc + ' - ' : '') + val.description + (valid_values ? ' Valid values: ' + valid_values : ''));
4528
- }
4529
-
4530
- return _z;
4531
- };
4532
-
4533
- if (method_prop.fields) {
4534
- try {
4535
- for (const [key, val] of Object.entries(method_prop.fields)) {
4536
- inputSchema[key] = get_z_item(key, val);
4537
- }
4538
- } catch (error) {
4539
- debugger;
4540
- }
4541
- }
4542
- try {
4543
- const tool_name = method_name.replace(/_/g, ' ').replace(/\b(\w)/g, (_, char) => char.toUpperCase());
4544
- tools.push(
4545
- tool({
4546
- name: tool_name.substring(0, 60),
4547
- description: method_prop.description,
4548
- parameters: z.object(inputSchema),
4549
- async execute(e, RunContext) {
4550
- const params = e;
4551
- try {
4552
- const response = await fetch(`http://localhost:3007/cpi/${method_name}`, {
4553
- method: 'POST',
4554
- headers: {
4555
- Accept: 'application/json',
4556
- 'Content-Type': 'application/json',
4557
- },
4558
- body: JSON.stringify({ ...params, ...{ gtp_token } }),
4559
- });
4560
- const ret = await response.json();
4561
- return {
4562
- content: [{ type: 'text', text: JSON.stringify(ret || '', null, 2) }],
4563
- };
4564
- } catch (err) {
4565
- return 'unknown';
4566
- }
4567
- },
4568
- }),
4569
- );
4570
- } catch (error) {
4571
- debugger;
4572
- }
4573
- }
4574
- } catch (error) {
4575
- debugger;
4576
- }
4577
- break;
4578
- }
4579
-
4580
- case 'image_generate': {
4581
- if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4582
- eligible_agent = false;
4583
- break;
4584
- }
4585
- tools.push(
4586
- tool({
4587
- name: name.substring(0, 60),
4588
- description,
4589
- parameters: z.object({
4590
- prompt: z.string().describe('The prompt for the image.'),
4591
- numGenerations: z.number().int().describe('Number generations to image create.').default(3),
4592
- }),
4593
- async execute(e, RunContext) {
4594
- debugger;
4595
- const { prompt, numGenerations } = e;
4596
-
4597
- try {
4598
- let imgTags = '';
4599
- const images_arr = await create_and_upload_image_to_drive('workspace', 'Chat Images', agent_id, prompt, numGenerations, uid, account_profile_info.app_id, job_id, headers, null, null, account_profile_info);
4600
- for (const img_obj of images_arr) {
4601
- imgTags += `<img src="${img_obj.file_url}" alt="${prompt}" style="max-width: 100%; border-radius: 8px;" />`;
4602
- }
4603
-
4604
- return imgTags;
4605
- } catch (err) {
4606
- console.error('Image Tool Error:', err);
4607
- return `Error generating image: ${err.message}`;
4608
- }
4609
- },
4610
- }),
4611
- );
4612
- break;
4613
- }
4614
-
4615
- case 'table': {
4616
- const table_id = val.prog_id;
4617
- // prompt += ` for table_id: ${table_id}`;
4618
- context.table_id = table_id;
4619
- tools.push(get_studio_table_info_by_table_id_tool);
4620
- //======== mock data ==========
4621
- // const mock_data_generator_agent = get_mock_data_generator_agent(app_id, table_id);
4622
- // tools.push(
4623
- // mock_data_generator_agent.asTool({
4624
- // toolName: 'Mock Data Generator',
4625
- // toolDescription: `generate Mock Data to a table`,
4626
- // }),
4627
- // );
4628
- // tools.push(get_studio_table_info_by_table_id_tool);
4629
-
4630
- //======== add data ==========
4631
- tools.push(
4632
- add_data_to_table_agent.asTool({
4633
- toolName: 'add data to table',
4634
- toolDescription: `add data to table`,
4635
- }),
4636
- );
4637
-
4638
- //======== fetch data ==========
4639
- tools.push(
4640
- fetch_table_data_agent.asTool({
4641
- toolName: 'Fetch Table Data Agent',
4642
- toolDescription: `fetch data from a table`,
4643
- }),
4644
- );
4645
-
4646
- //======== delete data ==========
4647
- tools.push(
4648
- delete_table_doc.asTool({
4649
- toolName: 'Delete Table Doc',
4650
- toolDescription: `The tool delete document from the database, need to ask for table`,
4651
- }),
4652
- );
4653
-
4654
- // tools.push(create_table_management_tool);
4655
-
4656
- // tools.push(create_landing_page_tool);
4657
-
4658
- // const add_data_to_table_agent = get_add_data_to_table_agent(app_id, table_id);
4659
- // tools.push(
4660
- // add_data_to_table_agent.asTool({
4661
- // toolName: 'add data to table',
4662
- // toolDescription: `add data to table`,
4663
- // }),
4664
- // );
4665
-
4666
- break;
4667
- }
4668
-
4669
- case 'file_search': {
4670
- if (val?.file?.vector_store_id) {
4671
- tools.push(fileSearchTool(val.file.vector_store_id));
4672
- }
4673
-
4674
- if (val?.youtube?.vector_store_id) {
4675
- tools.push(fileSearchTool(val.youtube.vector_store_id));
4676
- }
4677
-
4678
- break;
4679
- }
4680
-
4681
- case 'ai_agent': {
4682
- if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4683
- eligible_agent = false;
4684
- break;
4685
- }
4686
-
4687
- let opt = {
4688
- selector: {
4689
- docType: 'studio',
4690
- stat: 3,
4691
- 'properties.menuType': 'ai_agent',
4692
- },
4693
- limit: limit || 9999,
4694
- };
4695
-
4696
- // let opt = {};
4697
- // add all agents if no agent id
4698
- if (val.ai_agent_id) {
4699
- opt.selector._id = val.ai_agent_id;
4700
- }
4701
-
4702
- const user_agents = await db_module.find_app_couch_query(ai_agent_doc?.reference_doc?.studio_meta?.shared_from_app_id || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_id || app_id, opt);
4703
- for (const agent_doc of user_agents.docs) {
4704
- const agent = new Agent({
4705
- name: agent_doc.agent_name.substring(0, 60),
4706
- instructions: agent_doc.agent_instructions,
4707
- });
4708
-
4709
- tools.push(
4710
- agent.asTool({
4711
- toolName: agent_doc.agent_name,
4712
- toolDescription: agent_doc.agent_instructions,
4713
- }),
4714
- );
4715
- }
4716
- // const agent_ret = await get_ai_agents(opt);
4717
- // if (agent_ret.code > -1) {
4718
- // const agent_doc = agent_ret.data;
4719
-
4720
- // const agent = new Agent({
4721
- // name: agent_doc.agent_name,
4722
- // instructions: agent_doc.agent_instructions,
4723
- // });
4724
-
4725
- // tools.push(
4726
- // agent.asTool({
4727
- // toolName: agent_doc.agent_name,
4728
- // toolDescription: agent_doc.agent_instructions,
4729
- // }),
4730
- // );
4731
- // }
4732
- // }
4733
- break;
4734
- }
4735
- case 'plugin': {
4736
- if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
4737
- eligible_agent = false;
4738
- break;
4739
- }
4740
-
4741
- if (!val.plugin_id) {
4742
- throw new Error('undefined plugin_id');
4743
- }
4744
- if (!val.plugin_method) {
4745
- throw new Error('undefined method');
4746
- }
4747
-
4748
- const { plugin_method, type, plugin_id, ...params } = val;
4749
-
4750
- const tool = await get_plugin_tool(
4751
- ai_agent_doc?.reference_doc?.studio_meta?.shared_from_app_id || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_id || account_profile_info.app_id,
4752
- ai_agent_doc?.reference_doc?.studio_meta?.shared_from_uid || ai_agent_doc?.reference_doc?.studio_meta?.installed_from_app_uid || uid,
4753
- val.plugin_id,
4754
- val.plugin_method,
4755
- params,
4756
- undefined,
4757
- undefined,
4758
- ai_agent_doc,
4759
- );
4760
-
4761
- tools.push(tool);
4762
-
4763
- break;
4764
- }
4765
- default:
4766
- break;
4767
- }
4768
- }
4736
+ const tools_ret = await get_ai_agent_tools({
4737
+ ai_agent_doc,
4738
+ agent_id,
4739
+ reference_type,
4740
+ prompt_suggestion_activated,
4741
+ chat_suggestion_activated,
4742
+ gtp_token,
4743
+ uid,
4744
+ account_profile_info,
4745
+ job_id,
4746
+ headers,
4747
+ context,
4748
+ app_id,
4749
+ });
4750
+ let { tools, tool_resources } = tools_ret;
4751
+ context = tools_ret.context;
4752
+ eligible_agent = eligible_agent && tools_ret.eligible_agent;
4769
4753
  // if (!tools.length) continue;
4770
4754
  // console.log('tool', tools);
4771
4755
  // const agent_name = `${ai_agent_doc._id} ${ai_agent_doc?.properties?.menuName || ''}`;
@@ -5178,19 +5162,162 @@ const add_conversation_item = async function (uid, profile_id, conversation_id,
5178
5162
  };
5179
5163
 
5180
5164
  const auto_response = async function (uid, profile_id, contact_id, conversation_id) {
5181
- const account_profile_info = await get_active_account_profile_info(uid, profile_id);
5165
+ try {
5166
+ const account_profile_info = await get_active_account_profile_info(uid, profile_id);
5167
+
5168
+ const account_profile_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, profile_id);
5169
+ if (account_profile_doc.stat >= 4) return;
5170
+ if (!account_profile_doc.auto_respond) return;
5171
+ if (!account_profile_doc.auto_respond_mode) return;
5172
+
5173
+ let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
5174
+
5175
+ if (account_profile_doc.auto_respond_mode === 'when_offline' && account_doc.socket_id) return;
5176
+ if (!['always', 'when_offline'].includes(account_profile_doc.auto_respond_mode)) return;
5177
+
5178
+ const contact_doc = await get_contact_info(account_profile_info.uid, null, contact_id);
5179
+ if (!contact_doc?.contact_reference_conversation_id) return;
5180
+
5181
+ const conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_id);
5182
+
5183
+ let auto_respond_agents = account_profile_doc.auto_respond_agents;
5184
+ if (auto_respond_agents === null || typeof auto_respond_agents === 'undefined') return;
5185
+
5186
+ if (!Array.isArray(auto_respond_agents)) {
5187
+ auto_respond_agents = [];
5188
+ }
5189
+
5190
+ if (!auto_respond_agents.length) {
5191
+ const ai_agents_ret = await get_user_ai_agents(uid);
5192
+ auto_respond_agents = ai_agents_ret.docs.map((doc) => doc._id).filter(Boolean);
5193
+ }
5194
+
5195
+ if (!auto_respond_agents.length) return;
5196
+
5197
+ const runner = new Runner();
5198
+ const app_obj = await get_app_obj(account_profile_info.app_id);
5199
+ const userName = await account_ms.get_user_name(uid);
5200
+ const account_info = (await get_account_name({ uid })).data;
5201
+ let context = {
5202
+ app_id: account_profile_info.app_id,
5203
+ uid,
5204
+ userName,
5205
+ account_info,
5206
+ app_obj,
5207
+ account_id: uid,
5208
+ contact: {
5209
+ _id: contact_doc._id,
5210
+ name: contact_doc.name,
5211
+ email: contact_doc.email,
5212
+ contact_uid: contact_doc.contact_uid,
5213
+ },
5214
+ auto_response: true,
5215
+ conversation_type: 'email',
5216
+ profile_name: account_profile_doc.profile_name,
5217
+ profile_signature: account_profile_doc.profile_signature,
5218
+ };
5182
5219
 
5183
- const account_profile_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, profile_id);
5184
- if (!account_profile_doc.auto_respond_mode) return;
5220
+ let agents = [];
5221
+ let model = _conf.default_ai_model;
5185
5222
 
5186
- let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
5223
+ for (const agent_id of auto_respond_agents) {
5224
+ try {
5225
+ const ai_agent_doc = await load_ai_agent_doc(account_profile_info.app_id, agent_id);
5226
+ if (ai_agent_doc?.agentConfig?.agent_ai_model) {
5227
+ model = ai_agent_doc.agentConfig.agent_ai_model;
5228
+ }
5229
+
5230
+ const tools_ret = await get_ai_agent_tools({
5231
+ ai_agent_doc,
5232
+ agent_id,
5233
+ reference_type: 'ai_agents',
5234
+ prompt_suggestion_activated: false,
5235
+ chat_suggestion_activated: false,
5236
+ gtp_token: undefined,
5237
+ uid,
5238
+ account_profile_info,
5239
+ job_id: undefined,
5240
+ headers: {},
5241
+ context,
5242
+ app_id: account_profile_info.app_id,
5243
+ });
5244
+
5245
+ context = tools_ret.context;
5246
+
5247
+ const agent = new Agent({
5248
+ name: `${ai_agent_doc._id}`.substring(0, 55),
5249
+ instructions: `${ai_agent_doc.agentConfig.agent_instructions}
5250
+
5251
+ You are composing an automatic email reply.
5252
+ Use the existing conversation history as context.
5253
+ Reply as ${account_profile_doc.profile_name || userName}.
5254
+ Return only the email body text, ready to send.
5255
+ Keep the response concise, natural, and professional.
5256
+ If a signature is available, append it at the end:
5257
+ ${account_profile_doc.profile_signature || ''}`.trim(),
5258
+ model,
5259
+ tools: tools_ret.tools,
5260
+ metadata: {
5261
+ agent_id: ai_agent_doc._id,
5262
+ ts: Date.now(),
5263
+ auto_response: true,
5264
+ },
5265
+ tool_resources: tools_ret.tool_resources,
5266
+ });
5267
+
5268
+ if (tools_ret.eligible_agent) {
5269
+ agents.push(agent);
5270
+ }
5271
+ } catch (err) {
5272
+ console.error('auto_response agent load failed', err?.message || err);
5273
+ }
5274
+ }
5275
+
5276
+ if (!agents.length) return;
5187
5277
 
5188
- if (account_profile_doc.auto_respond_mode === 'when_offline' && account_doc.socket_id) return;
5189
- if (account_profile_doc.auto_respond_mode !== 'always') return;
5278
+ let active_agent;
5279
+ if (agents.length === 1) {
5280
+ active_agent = agents[0];
5281
+ } else {
5282
+ active_agent = new Agent({
5283
+ name: 'Auto Response Triage Agent',
5284
+ instructions: `Select the best specialist agent to draft an automatic email response.
5285
+ Return only the final email body text.`,
5286
+ model,
5287
+ handoffs: agents,
5288
+ });
5289
+ }
5190
5290
 
5191
- const contact_doc = await get_contact_info(account_profile_info.uid, null, contact_id);
5291
+ const prompt = `Write an automatic email reply to the latest incoming message in this conversation.
5292
+ Do not mention that the reply is automated.
5293
+ Use the conversation history for context.
5294
+ Return only the email body.`;
5192
5295
 
5193
- ///
5296
+ const output = await runner.run(active_agent, prompt, {
5297
+ conversationId: contact_doc.contact_reference_conversation_id,
5298
+ context,
5299
+ stream: false,
5300
+ });
5301
+
5302
+ const response_text = output?.state?._currentStep?.output?.trim();
5303
+ if (!response_text) return;
5304
+
5305
+ await chat_email(
5306
+ {
5307
+ profile_id,
5308
+ uid,
5309
+ prompt: response_text,
5310
+ conversation_doc,
5311
+ attachments: [],
5312
+ perform_ai_execution: false,
5313
+ direction: 'out',
5314
+ },
5315
+ undefined,
5316
+ undefined,
5317
+ );
5318
+ } catch (err) {
5319
+ console.error('auto_response failed', err);
5320
+ }
5194
5321
  };
5195
5322
 
5196
5323
  setTimeout(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/ai_module",
3
- "version": "1.1.5552",
3
+ "version": "1.1.5554",
4
4
  "description": "Xuda AI Module",
5
5
  "main": "index.mjs",
6
6
  "type": "module",