@xuda.io/ai_module 1.1.5639 → 1.1.5641
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/index.mjs +172 -39
- package/old.mjs +0 -1
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -308,6 +308,30 @@ const { init, check, check_structure, get_zod_schema, get_fields_z_schema } = aw
|
|
|
308
308
|
const { get_xuda_couch } = _common;
|
|
309
309
|
|
|
310
310
|
const db_module = await import(`${module_path}/db_module/index.mjs`);
|
|
311
|
+
|
|
312
|
+
// Sort keys for the dashboard list tabs, per docType. Each entry is a fallback
|
|
313
|
+
// chain (first defined value wins) because the doc shapes differ: a chat has
|
|
314
|
+
// its own title + date_created_ts, a studio doc carries the name under
|
|
315
|
+
// properties.menuName and may only have ts. See
|
|
316
|
+
// db_module.find_app_couch_sorted_page.
|
|
317
|
+
// `shared` points at the owner's copy: an app/agent shared with you, or bought
|
|
318
|
+
// from the marketplace, is stored locally as a stub with no menuName, so a name
|
|
319
|
+
// sort has to read the source doc. Same two pointers the enrichment follows
|
|
320
|
+
// (get_ai_agents/get_apps: shared_from_app_id + share_item_id, then
|
|
321
|
+
// installed_from_app_id keyed by the doc's own _id).
|
|
322
|
+
const LIST_SORT_PATHS = {
|
|
323
|
+
chat: { created: ['date_created_ts', 'date_created', 'ts'], updated: ['ts', 'date_created_ts'], name: ['title'] },
|
|
324
|
+
studio: {
|
|
325
|
+
created: ['date_created_ts', 'date_created', 'ts'],
|
|
326
|
+
updated: ['ts', 'date_created_ts'],
|
|
327
|
+
name: ['properties.menuName', 'studio_meta.name'],
|
|
328
|
+
shared: [
|
|
329
|
+
{ app_id: 'studio_meta.shared_from_app_id', doc_id: 'studio_meta.share_item_id' },
|
|
330
|
+
{ app_id: 'studio_meta.installed_from_app_id', doc_id: '_id' },
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
|
|
311
335
|
const account_ms = await import(`${module_path}/account_module/index_ms.mjs`);
|
|
312
336
|
const drive_ms = await import(`${module_path}/drive_module/index_ms.mjs`);
|
|
313
337
|
const jobs_ms = await import(`${module_path}/jobs_module/index_ms.mjs`);
|
|
@@ -413,7 +437,6 @@ const get_studio_table_info_tool = tool({
|
|
|
413
437
|
async execute(e, RunContext) {
|
|
414
438
|
const { table } = e;
|
|
415
439
|
const { app_id, uid } = RunContext.context;
|
|
416
|
-
debugger;
|
|
417
440
|
if (!table) throw new Error('got null in the table parameter');
|
|
418
441
|
|
|
419
442
|
try {
|
|
@@ -558,7 +581,6 @@ const fetch_data_tool = tool({
|
|
|
558
581
|
}
|
|
559
582
|
|
|
560
583
|
const validateQuery_result = validateQueryAgainstTable(query_obj, table_doc.tableFields);
|
|
561
|
-
debugger;
|
|
562
584
|
if (!validateQuery_result.isValid) {
|
|
563
585
|
// console.error('Validation failed:', validateQuery_result.errors);
|
|
564
586
|
throw new Error(`Validation failed: ${JSON.stringify(validateQuery_result.errors)}`);
|
|
@@ -795,7 +817,6 @@ const create_index_tool = tool({
|
|
|
795
817
|
const { index } = e;
|
|
796
818
|
const { app_id, uid } = RunContext.context;
|
|
797
819
|
try {
|
|
798
|
-
debugger;
|
|
799
820
|
const index_obj = JSON5.parse(index);
|
|
800
821
|
console.log('Create Index', index_obj);
|
|
801
822
|
const project_db = await get_project_db(app_id);
|
|
@@ -2076,6 +2097,14 @@ export const get_ai_chats = async function (req, job_id, headers) {
|
|
|
2076
2097
|
};
|
|
2077
2098
|
}
|
|
2078
2099
|
|
|
2100
|
+
// User-picked order from the dashboard list controls (sort_by date |
|
|
2101
|
+
// updated | name, sort_dir asc | desc). Null when none was asked for,
|
|
2102
|
+
// which leaves the default newest-first path below untouched. Only the
|
|
2103
|
+
// top-level chat list is sortable: with a reference_id these are the
|
|
2104
|
+
// items INSIDE one conversation, which must stay in thread order.
|
|
2105
|
+
const sorted = reference_id || conversation_id ? null : await db_module.find_app_couch_sorted_page(account_profile_info.app_id, opt, req, LIST_SORT_PATHS.chat);
|
|
2106
|
+
if (sorted) return sorted;
|
|
2107
|
+
|
|
2079
2108
|
let ai_chats = await db_module.find_app_couch_query(account_profile_info.app_id, opt);
|
|
2080
2109
|
if (!limit || conversation_id) {
|
|
2081
2110
|
ai_chats.total_docs = ai_chats.docs.length;
|
|
@@ -2246,9 +2275,19 @@ export const get_ai_chats = async function (req, job_id, headers) {
|
|
|
2246
2275
|
doc.notifications = contact_chat_conversation_count_ret[doc._id] - contact_chat_conversation_read_ret[doc._id];
|
|
2247
2276
|
doc.chats = doc.interactions;
|
|
2248
2277
|
|
|
2249
|
-
|
|
2278
|
+
// Who WROTE this row. A contact/profile timeline comes back from
|
|
2279
|
+
// get_data_view_conversation_items as a composite { conversation, conversation_item }
|
|
2280
|
+
// that carries no uid of its own, so `doc.uid` was undefined here. get_user_card then
|
|
2281
|
+
// built a selector with contact_uid dropped (JSON.stringify strips undefined) and
|
|
2282
|
+
// matched ANY contact, which is why every note on a contact page was bylined with the
|
|
2283
|
+
// first contact in the book, the person the note is ABOUT, instead of its author.
|
|
2284
|
+
const author_uid = doc.uid || doc.conversation_item?.uid || doc.conversation?.initiator_uid || doc.conversation?.uid;
|
|
2250
2285
|
|
|
2251
|
-
|
|
2286
|
+
if (author_uid) {
|
|
2287
|
+
doc.user_contact = await get_user_card({ uid, uid_query: author_uid });
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
doc.privilege = author_uid === uid || doc?.account_profile_info?.uid === uid;
|
|
2252
2291
|
|
|
2253
2292
|
if (reference_id && doc.reference_type === 'contact') {
|
|
2254
2293
|
// only valid for contacts conversation
|
|
@@ -2257,6 +2296,17 @@ export const get_ai_chats = async function (req, job_id, headers) {
|
|
|
2257
2296
|
docs.push(doc);
|
|
2258
2297
|
}
|
|
2259
2298
|
|
|
2299
|
+
// Calls and SMS belong on the contact's timeline next to the notes rather than behind
|
|
2300
|
+
// their own tabs, so merge them in and order the whole thing by time. Only for a real
|
|
2301
|
+
// contact timeline: the account-wide lists have their own screens.
|
|
2302
|
+
if (reference_id && reference_type === 'contacts') {
|
|
2303
|
+
const voice_rows = await _tl_voice_rows(uid, account_profile_info, reference_id, docs[0]?.user_contact || null);
|
|
2304
|
+
if (voice_rows.length) {
|
|
2305
|
+
const row_ts = (r) => Number(r?.conversation_item?.date_created_ts || r?.conversation?.date_created_ts || r?.date_created_ts || 0);
|
|
2306
|
+
docs = [...docs, ...voice_rows].sort((a, b) => row_ts(a) - row_ts(b));
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2260
2310
|
return { code: 2, data: { docs: [...requests_from.docs, ...docs], total_docs: ai_chats.total_docs + requests_from.total_docs } };
|
|
2261
2311
|
} catch (err) {
|
|
2262
2312
|
return { code: -2, data: err.message };
|
|
@@ -2977,17 +3027,24 @@ export const get_ai_agents = async function (req, job_id, headers) {
|
|
|
2977
3027
|
|
|
2978
3028
|
let user_agents = { docs: [], total_docs: 0 };
|
|
2979
3029
|
if (filter_type !== 'pending') {
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
3030
|
+
// User-picked order from the dashboard list controls, see
|
|
3031
|
+
// db_module.find_app_couch_sorted_page. Null when none was asked for.
|
|
3032
|
+
const sorted = agent_id ? null : await db_module.find_app_couch_sorted_page(account_profile_info.app_id, opt, req, LIST_SORT_PATHS.studio);
|
|
3033
|
+
if (sorted) {
|
|
3034
|
+
user_agents = sorted;
|
|
2983
3035
|
} else {
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3036
|
+
user_agents = await db_module.find_app_couch_query(account_profile_info.app_id, opt);
|
|
3037
|
+
if (!limit || agent_id) {
|
|
3038
|
+
user_agents.total_docs = user_agents.docs.length;
|
|
3039
|
+
} else {
|
|
3040
|
+
delete opt.sort;
|
|
3041
|
+
delete opt.skip;
|
|
3042
|
+
opt.limit = 9999;
|
|
3043
|
+
opt.fields = ['_id'];
|
|
2988
3044
|
|
|
2989
|
-
|
|
2990
|
-
|
|
3045
|
+
const counter = await db_module.find_app_couch_query(account_profile_info.app_id, opt);
|
|
3046
|
+
user_agents.total_docs = counter.docs.length;
|
|
3047
|
+
}
|
|
2991
3048
|
}
|
|
2992
3049
|
}
|
|
2993
3050
|
|
|
@@ -3463,17 +3520,25 @@ export const get_apps = async function (req, job_id, headers) {
|
|
|
3463
3520
|
|
|
3464
3521
|
let user_apps = { docs: [], total_docs: 0 };
|
|
3465
3522
|
if (filter_type !== 'pending') {
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3523
|
+
// User-picked order from the dashboard list controls, see
|
|
3524
|
+
// db_module.find_app_couch_sorted_page. Null when none was asked for,
|
|
3525
|
+
// which leaves the default newest-first path below untouched.
|
|
3526
|
+
const sorted = mini_app_id ? null : await db_module.find_app_couch_sorted_page(account_profile_info.app_id, opt, req, LIST_SORT_PATHS.studio);
|
|
3527
|
+
if (sorted) {
|
|
3528
|
+
user_apps = sorted;
|
|
3469
3529
|
} else {
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3530
|
+
user_apps = await db_module.find_app_couch_query(account_profile_info.app_id, opt);
|
|
3531
|
+
if (!limit || mini_app_id) {
|
|
3532
|
+
user_apps.total_docs = user_apps.docs.length;
|
|
3533
|
+
} else {
|
|
3534
|
+
delete opt.sort;
|
|
3535
|
+
delete opt.skip;
|
|
3536
|
+
opt.limit = 9999;
|
|
3537
|
+
opt.fields = ['_id'];
|
|
3474
3538
|
|
|
3475
|
-
|
|
3476
|
-
|
|
3539
|
+
const counter = await db_module.find_app_couch_query(account_profile_info.app_id, opt);
|
|
3540
|
+
user_apps.total_docs = counter.docs.length;
|
|
3541
|
+
}
|
|
3477
3542
|
}
|
|
3478
3543
|
}
|
|
3479
3544
|
|
|
@@ -3993,7 +4058,6 @@ export const update_ai_agent_properties = async function (doc, app_id, uid, fiel
|
|
|
3993
4058
|
db_doc.agentConfig.agent_industry = await get_agent_industry();
|
|
3994
4059
|
db_doc.studio_meta.agent_industry = db_doc.agentConfig.agent_industry;
|
|
3995
4060
|
}
|
|
3996
|
-
debugger;
|
|
3997
4061
|
if (db_doc.agentConfig.agent_user_guide && (fields_changed.agent_user_guide_changed || fields_changed.all)) {
|
|
3998
4062
|
db_doc.agentConfig.agent_user_guide_fields = await get_agent_user_guide_fields();
|
|
3999
4063
|
db_doc.studio_meta.agent_user_guide_fields = db_doc.agentConfig.agent_user_guide_fields;
|
|
@@ -4122,7 +4186,6 @@ export const update_thumbnail = async function (type, doc, app_id, uid, job_id,
|
|
|
4122
4186
|
}
|
|
4123
4187
|
return save_ret;
|
|
4124
4188
|
} catch (error) {
|
|
4125
|
-
debugger;
|
|
4126
4189
|
}
|
|
4127
4190
|
// }, 500);
|
|
4128
4191
|
};
|
|
@@ -5067,7 +5130,6 @@ export const create_conversation = async function (req, job_id, headers) {
|
|
|
5067
5130
|
|
|
5068
5131
|
return save_ret;
|
|
5069
5132
|
} catch (err) {
|
|
5070
|
-
debugger;
|
|
5071
5133
|
|
|
5072
5134
|
return { code: -5, data: err.message || String(err) };
|
|
5073
5135
|
}
|
|
@@ -5149,6 +5211,85 @@ const process_conversation = async function (uid, conversation_id, account_profi
|
|
|
5149
5211
|
// }
|
|
5150
5212
|
};
|
|
5151
5213
|
|
|
5214
|
+
// --- contact timeline: calls and SMS -----------------------------------------------------
|
|
5215
|
+
// Phone activity lives in xuda_master as voice_call / voice_message docs keyed by
|
|
5216
|
+
// owner_uid + phone number, NOT by contact, so it can only be tied to a contact by matching
|
|
5217
|
+
// numbers. Digits only, comparing the last 10, so a number written +1 561 235 1675 on an
|
|
5218
|
+
// account matches +15612351675 on a call. Same rule as voice_module's own caller matching.
|
|
5219
|
+
const _tl_digits = (value) => String(value ?? '').replace(/\D+/g, '');
|
|
5220
|
+
const _tl_same_phone = (a, b) => {
|
|
5221
|
+
const x = _tl_digits(a);
|
|
5222
|
+
const y = _tl_digits(b);
|
|
5223
|
+
if (!x || !y) return false;
|
|
5224
|
+
if (x === y) return true;
|
|
5225
|
+
const n = Math.min(10, x.length, y.length);
|
|
5226
|
+
return n >= 7 && x.slice(-n) === y.slice(-n);
|
|
5227
|
+
};
|
|
5228
|
+
|
|
5229
|
+
// Every number this contact can be reached on. A contact linked to a Xuda user carries no
|
|
5230
|
+
// phone on its own doc at all: it lives on their account, which is why matching only the
|
|
5231
|
+
// contact doc finds nothing for exactly the contacts that matter most.
|
|
5232
|
+
const _tl_contact_phones = async function (app_id, contact_id) {
|
|
5233
|
+
const out = [];
|
|
5234
|
+
let contact = null;
|
|
5235
|
+
try {
|
|
5236
|
+
contact = await db_module.get_app_couch_doc_native(app_id, contact_id);
|
|
5237
|
+
for (const f of ['phone_e164', 'phone', 'telephone', 'phone_number', 'mobile', 'tel']) {
|
|
5238
|
+
if (contact?.[f]) out.push(contact[f]);
|
|
5239
|
+
}
|
|
5240
|
+
if (contact?.contact_uid) {
|
|
5241
|
+
const ret = await db_module.get_couch_doc('xuda_accounts', contact.contact_uid);
|
|
5242
|
+
const info = ret?.code >= 0 ? ret.data?.account_info || {} : {};
|
|
5243
|
+
if (info.phone_number) out.push(info.phone_number);
|
|
5244
|
+
if (info.tel) out.push(info.tel);
|
|
5245
|
+
}
|
|
5246
|
+
} catch (_) { /* no phone is a normal contact, not an error */ }
|
|
5247
|
+
return { phones: out.filter(Boolean), contact };
|
|
5248
|
+
};
|
|
5249
|
+
|
|
5250
|
+
// Calls and SMS as timeline rows, in the same composite shape the note and email rows use
|
|
5251
|
+
// ({ conversation, conversation_item, user_contact }) so the timeline renders them by
|
|
5252
|
+
// conversation_type without a second code path.
|
|
5253
|
+
const _tl_voice_rows = async function (uid, account_profile_info, contact_id, user_contact) {
|
|
5254
|
+
try {
|
|
5255
|
+
const { phones, contact } = await _tl_contact_phones(account_profile_info.app_id, contact_id);
|
|
5256
|
+
if (!phones.length) return [];
|
|
5257
|
+
const peer = (d) => (d.direction === 'inbound' ? d.from : d.to);
|
|
5258
|
+
// Byline the party who did the thing: an inbound call or SMS came FROM the contact, an
|
|
5259
|
+
// outbound one went out under this account. Bylining every call with the account name
|
|
5260
|
+
// read as if the business had called itself.
|
|
5261
|
+
const card_for = (d) => (d.direction === 'inbound' ? contact || user_contact : user_contact);
|
|
5262
|
+
const [calls, messages] = await Promise.all([
|
|
5263
|
+
db_module.find_couch_query('xuda_master', { selector: { docType: 'voice_call', owner_uid: uid }, limit: 500 }, false, true),
|
|
5264
|
+
db_module.find_couch_query('xuda_master', { selector: { docType: 'voice_message', owner_uid: uid }, limit: 500 }, false, true),
|
|
5265
|
+
]);
|
|
5266
|
+
const mine = (d) => phones.some((p) => _tl_same_phone(p, peer(d)));
|
|
5267
|
+
const row = (type, doc, text, extra) => ({
|
|
5268
|
+
conversation: { _id: doc._id, docType: 'chat_conversation', conversation_type: type, reference_type: 'contacts', reference_id: contact_id, uid, prompt: text, title: text, date_created_ts: doc.created_ts, ts: doc.created_ts, stat: 3 },
|
|
5269
|
+
conversation_item: { _id: doc._id, docType: 'chat_conversation_item', conversation_type: type, type, text, direction: doc.direction, date_created_ts: doc.created_ts, ts: doc.created_ts, stat: 3, uid },
|
|
5270
|
+
user_contact: card_for(doc),
|
|
5271
|
+
voice: { kind: type, ...extra },
|
|
5272
|
+
privilege: true,
|
|
5273
|
+
});
|
|
5274
|
+
|
|
5275
|
+
const call_rows = (calls?.docs || []).filter((d) => d.status !== 'ringing' && mine(d)).map((d) =>
|
|
5276
|
+
row('call', d, d.direction === 'inbound' ? 'Incoming call' : 'Outgoing call', {
|
|
5277
|
+
status: d.status,
|
|
5278
|
+
duration_sec: d.duration_sec || 0,
|
|
5279
|
+
has_recording: !!d.recording,
|
|
5280
|
+
transcript_turns: (d.transcript || []).length,
|
|
5281
|
+
handled_by: d.handled_by || '',
|
|
5282
|
+
}),
|
|
5283
|
+
);
|
|
5284
|
+
const sms_rows = (messages?.docs || []).filter(mine).map((d) => row('sms', d, d.body || '', { status: d.status, segments: d.segments || 1 }));
|
|
5285
|
+
return [...call_rows, ...sms_rows];
|
|
5286
|
+
} catch (err) {
|
|
5287
|
+
// A phone lookup must never take the whole timeline down with it.
|
|
5288
|
+
console.error('[ai_module] contact voice timeline rows failed:', err.message);
|
|
5289
|
+
return [];
|
|
5290
|
+
}
|
|
5291
|
+
};
|
|
5292
|
+
|
|
5152
5293
|
const contactGuardrailAgent = new Agent({
|
|
5153
5294
|
name: 'Person Guardrail check',
|
|
5154
5295
|
instructions: 'Check if the prompt about person.',
|
|
@@ -5324,7 +5465,6 @@ const update_conversation_mood_level = async function (uid, target_contacts = []
|
|
|
5324
5465
|
}
|
|
5325
5466
|
}
|
|
5326
5467
|
} catch (err) {
|
|
5327
|
-
debugger;
|
|
5328
5468
|
}
|
|
5329
5469
|
};
|
|
5330
5470
|
|
|
@@ -7292,7 +7432,6 @@ Hard restrictions:
|
|
|
7292
7432
|
}
|
|
7293
7433
|
|
|
7294
7434
|
try {
|
|
7295
|
-
debugger;
|
|
7296
7435
|
const api_allow_methods = Object.keys(_conf.cpi_methods);
|
|
7297
7436
|
for (const method_name of api_allow_methods || []) {
|
|
7298
7437
|
const method_prop = _conf.cpi_methods[method_name];
|
|
@@ -7347,7 +7486,6 @@ Hard restrictions:
|
|
|
7347
7486
|
inputSchema[key] = get_z_item(key, val);
|
|
7348
7487
|
}
|
|
7349
7488
|
} catch (error) {
|
|
7350
|
-
debugger;
|
|
7351
7489
|
}
|
|
7352
7490
|
}
|
|
7353
7491
|
try {
|
|
@@ -7379,11 +7517,9 @@ Hard restrictions:
|
|
|
7379
7517
|
}),
|
|
7380
7518
|
);
|
|
7381
7519
|
} catch (error) {
|
|
7382
|
-
debugger;
|
|
7383
7520
|
}
|
|
7384
7521
|
}
|
|
7385
7522
|
} catch (error) {
|
|
7386
|
-
debugger;
|
|
7387
7523
|
}
|
|
7388
7524
|
break;
|
|
7389
7525
|
}
|
|
@@ -7454,7 +7590,6 @@ Hard restrictions:
|
|
|
7454
7590
|
numGenerations: z.number().int().describe('Number generations to image create.').default(3),
|
|
7455
7591
|
}),
|
|
7456
7592
|
async execute(e, RunContext) {
|
|
7457
|
-
debugger;
|
|
7458
7593
|
const { prompt, numGenerations } = e;
|
|
7459
7594
|
|
|
7460
7595
|
try {
|
|
@@ -7838,7 +7973,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
7838
7973
|
});
|
|
7839
7974
|
|
|
7840
7975
|
agent.on('agent_tool_start', (context, tool, details) => {
|
|
7841
|
-
debugger;
|
|
7842
7976
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
7843
7977
|
emitToDashboard('stream_phase', `Starting ${tool?.name?.replaceAll('_', ' ')} tool`, { update: true });
|
|
7844
7978
|
});
|
|
@@ -7997,13 +8131,11 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
7997
8131
|
if (!prompt_suggestion_activated) {
|
|
7998
8132
|
// init_agent_hooks(agent);
|
|
7999
8133
|
agent.on('onToolStart', (context, tool, details) => {
|
|
8000
|
-
debugger;
|
|
8001
8134
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
8002
8135
|
// emitToDashboard('stream_phase', `Starting ${tool.name} tool`);
|
|
8003
8136
|
});
|
|
8004
8137
|
|
|
8005
8138
|
agent.on('onToolEnd', (context, tool, details) => {
|
|
8006
|
-
debugger;
|
|
8007
8139
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
8008
8140
|
// emitToDashboard('stream_phase', `Starting ${tool.name} tool`);
|
|
8009
8141
|
});
|
|
@@ -8148,7 +8280,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8148
8280
|
emitToDashboard('stream_phase', 'Submitting chat', { update: true });
|
|
8149
8281
|
init_agent_hooks(_agent);
|
|
8150
8282
|
// const output = await runner.run(_agent, prompt, opt);
|
|
8151
|
-
debugger;
|
|
8152
8283
|
const output = await run_agent(_agent, prompt, opt);
|
|
8153
8284
|
const done = async function (output) {
|
|
8154
8285
|
try {
|
|
@@ -8196,7 +8327,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8196
8327
|
// }
|
|
8197
8328
|
const save_ret = await db_module.save_app_couch_doc_native(account_profile_info.app_id, in_conversation_item_obj);
|
|
8198
8329
|
|
|
8199
|
-
debugger;
|
|
8200
8330
|
|
|
8201
8331
|
let conversation_items = await client.conversations.items.list(conversation_doc.reference_conversation_id, { order: 'asc', after: last_conversation_item });
|
|
8202
8332
|
|
|
@@ -8218,7 +8348,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8218
8348
|
|
|
8219
8349
|
return save_ret;
|
|
8220
8350
|
} catch (error) {
|
|
8221
|
-
debugger;
|
|
8222
8351
|
}
|
|
8223
8352
|
// }
|
|
8224
8353
|
|
|
@@ -8283,7 +8412,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8283
8412
|
};
|
|
8284
8413
|
// }
|
|
8285
8414
|
} catch (err) {
|
|
8286
|
-
debugger;
|
|
8287
8415
|
|
|
8288
8416
|
conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_id);
|
|
8289
8417
|
conversation_doc.ts = Date.now();
|
|
@@ -8387,6 +8515,11 @@ const auto_response = async function (uid, profile_id, contact_id, conversation_
|
|
|
8387
8515
|
|
|
8388
8516
|
let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
|
|
8389
8517
|
|
|
8518
|
+
// The main profile is the account's OWN identity: never auto-respond on it
|
|
8519
|
+
// (you don't auto-reply to yourself). Authoritative check via the account's
|
|
8520
|
+
// account_profile_id, independent of the stored auto_respond flag.
|
|
8521
|
+
if (account_doc?.account_profile_id && profile_id === account_doc.account_profile_id) return;
|
|
8522
|
+
|
|
8390
8523
|
if (account_profile_doc.auto_respond_mode === 'when_offline' && account_doc.socket_id) return;
|
|
8391
8524
|
if (!['always', 'when_offline'].includes(account_profile_doc.auto_respond_mode)) return;
|
|
8392
8525
|
|
package/old.mjs
CHANGED
|
@@ -580,7 +580,6 @@ async function testTool(app_id, uid) {
|
|
|
580
580
|
|
|
581
581
|
console.log('Input:', JSON.stringify(input, null, 2));
|
|
582
582
|
console.log('RunContext:', JSON.stringify(runContext, null, 2));
|
|
583
|
-
debugger;
|
|
584
583
|
// CORRECT ORDER: input first, then runContext
|
|
585
584
|
const result = await get_studio_table_info_by_table_id_tool.invoke(
|
|
586
585
|
runContext, // 1st: context
|