@xuda.io/ai_module 1.1.5611 → 1.1.5612
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 +351 -19
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -232,7 +232,7 @@ const email_ms = await import(`${module_path}/email_module/index_ms.mjs`);
|
|
|
232
232
|
const ws_dashboard_msa = await import(`${module_path}/ws_dashboard_module/index_msa.mjs`);
|
|
233
233
|
const account_msa = await import(`${module_path}/account_module/index_msa.mjs`);
|
|
234
234
|
const drive_msa = await import(`${module_path}/drive_module/index_msa.mjs`);
|
|
235
|
-
const
|
|
235
|
+
const misc_msa = await import(`${module_path}/misc_module/index_msa.mjs`);
|
|
236
236
|
|
|
237
237
|
var open_ai_status = {};
|
|
238
238
|
const report_ai_status = function (model, err) {
|
|
@@ -2151,7 +2151,7 @@ const get_studio_doc = async function (req) {
|
|
|
2151
2151
|
};
|
|
2152
2152
|
|
|
2153
2153
|
export const get_ai_agent_info = async function (uid, job_id, headers, doc, from_marketplace) {
|
|
2154
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2154
|
+
const account_profile_info = await get_active_account_profile_info(uid, from_marketplace ? doc?.studio_meta?.account_profiles?.[0] : undefined);
|
|
2155
2155
|
|
|
2156
2156
|
const get_contact_border = function (doc) {
|
|
2157
2157
|
const disable_color = `#1a3557`;
|
|
@@ -2673,7 +2673,7 @@ export const delete_ai_agent = async function (req) {
|
|
|
2673
2673
|
const save_ret = await db_module.save_app_couch_doc_native(account_profile_info.app_id, agent_doc);
|
|
2674
2674
|
|
|
2675
2675
|
if (agent_doc?.agentConfig?.npm_package_name) {
|
|
2676
|
-
|
|
2676
|
+
misc_msa.sync_agent_npm_state({ app_id: account_profile_info.app_id, prog_id: agent_id, event: 'deleted' });
|
|
2677
2677
|
}
|
|
2678
2678
|
|
|
2679
2679
|
for (const [key, val] of Object.entries(agent_doc?.agentConfig?.agent_tools || [])) {
|
|
@@ -2894,6 +2894,8 @@ export const start_cli_agent_conversation = async function (req) {
|
|
|
2894
2894
|
if (!agent_id) return { code: -1, data: 'agent_id required' };
|
|
2895
2895
|
try {
|
|
2896
2896
|
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2897
|
+
const profile_id = account_profile_info.account_profile_id;
|
|
2898
|
+
const conversation_obj = await create_openai_conversation();
|
|
2897
2899
|
const conversation_id = await _common.xuda_get_uuid('chat_conversation');
|
|
2898
2900
|
const now = Date.now();
|
|
2899
2901
|
const doc = {
|
|
@@ -2907,23 +2909,25 @@ export const start_cli_agent_conversation = async function (req) {
|
|
|
2907
2909
|
messages: [],
|
|
2908
2910
|
reference_type: 'ai_agents',
|
|
2909
2911
|
reference_id: agent_id,
|
|
2912
|
+
conversation_obj,
|
|
2913
|
+
reference_conversation_id: conversation_obj.id,
|
|
2910
2914
|
conversation_type: 'ai_chat',
|
|
2911
2915
|
initiator_uid: uid,
|
|
2912
|
-
account_profiles: [
|
|
2916
|
+
account_profiles: [profile_id],
|
|
2913
2917
|
source: 'cli',
|
|
2914
2918
|
};
|
|
2915
2919
|
const save_ret = await db_module.save_app_couch_doc(account_profile_info.app_id, doc);
|
|
2916
2920
|
if (save_ret.code < 0) return save_ret;
|
|
2917
|
-
return { code: 1, data: { conversation_id, profile_id
|
|
2921
|
+
return { code: 1, data: { conversation_id, profile_id, app_id: account_profile_info.app_id } };
|
|
2918
2922
|
} catch (err) {
|
|
2919
2923
|
return { code: -1, data: err.message };
|
|
2920
2924
|
}
|
|
2921
2925
|
};
|
|
2922
2926
|
|
|
2923
2927
|
export const update_ai_agent = async function (req, job_id, headers) {
|
|
2924
|
-
let { agent_id, agentConfig, uid } = req;
|
|
2928
|
+
let { agent_id, agentConfig, uid, profile_id } = req;
|
|
2925
2929
|
|
|
2926
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2930
|
+
const account_profile_info = await get_active_account_profile_info(uid, profile_id);
|
|
2927
2931
|
|
|
2928
2932
|
try {
|
|
2929
2933
|
let agent_doc = await await db_module.get_app_couch_doc_native(account_profile_info.app_id, agent_id);
|
|
@@ -3329,11 +3333,11 @@ const save_agent_status = async function (uid, agent_id, stat, agentConfig) {
|
|
|
3329
3333
|
};
|
|
3330
3334
|
|
|
3331
3335
|
export const create_ai_agent = async function (req, job_id, headers) {
|
|
3332
|
-
const { agentConfig, uid } = req;
|
|
3336
|
+
const { agentConfig, uid, profile_id } = req;
|
|
3333
3337
|
|
|
3334
3338
|
const { account_project_id: app_id, account_info } = await account_ms.get_default_project_account_doc(uid);
|
|
3335
3339
|
|
|
3336
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
3340
|
+
const account_profile_info = await get_active_account_profile_info(uid, profile_id);
|
|
3337
3341
|
const { account_profile_obj } = account_profile_info;
|
|
3338
3342
|
try {
|
|
3339
3343
|
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_profile_info.app_id, parentId: 'ai_agents' };
|
|
@@ -3611,7 +3615,7 @@ export const update_thumbnail = async function (type, doc, app_id, uid, job_id,
|
|
|
3611
3615
|
|
|
3612
3616
|
switch (type) {
|
|
3613
3617
|
case 'ai_agent': {
|
|
3614
|
-
const images_arr = await create_ai_agent_image({ app_id, uid, ai_agent_id: doc._id, tags }, job_id, headers);
|
|
3618
|
+
const images_arr = await create_ai_agent_image({ app_id, uid, ai_agent_id: doc._id, tags, account_profile_info }, job_id, headers);
|
|
3615
3619
|
db_doc = await get_db_doc();
|
|
3616
3620
|
db_doc.studio_meta.thumbnail_request_ts = Date.now();
|
|
3617
3621
|
db_doc.studio_meta.agent_image = [images_arr.data];
|
|
@@ -5742,9 +5746,337 @@ const get_ai_agent_tools = async function ({ ai_agent_doc, agent_id, reference_t
|
|
|
5742
5746
|
let tool_resources = {};
|
|
5743
5747
|
let eligible_agent = true;
|
|
5744
5748
|
|
|
5749
|
+
const add_internal_codex_tool = function ({ name, description, system_prompt }) {
|
|
5750
|
+
if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
|
|
5751
|
+
eligible_agent = false;
|
|
5752
|
+
return;
|
|
5753
|
+
}
|
|
5754
|
+
|
|
5755
|
+
tools.push(
|
|
5756
|
+
tool({
|
|
5757
|
+
name: name.substring(0, 60),
|
|
5758
|
+
description,
|
|
5759
|
+
parameters: z.object({
|
|
5760
|
+
question: z.string().describe('The support question to investigate.'),
|
|
5761
|
+
}),
|
|
5762
|
+
async execute(e) {
|
|
5763
|
+
const question = String(e?.question || '').trim();
|
|
5764
|
+
if (!question) {
|
|
5765
|
+
return 'question is required';
|
|
5766
|
+
}
|
|
5767
|
+
|
|
5768
|
+
const dev_host = _conf?.internal_ai_agents?.dev_server_host || 'dev.xuda.ai';
|
|
5769
|
+
const codex_ret = await execute_codex_request(
|
|
5770
|
+
{
|
|
5771
|
+
ip: dev_host,
|
|
5772
|
+
uid,
|
|
5773
|
+
account_profile_info,
|
|
5774
|
+
job_id,
|
|
5775
|
+
stream: false,
|
|
5776
|
+
prompt: `${system_prompt}
|
|
5777
|
+
|
|
5778
|
+
User question:
|
|
5779
|
+
${question}
|
|
5780
|
+
|
|
5781
|
+
Return a concise answer. Include only non-sensitive findings and mention when the requested information is outside the allowed scope.`,
|
|
5782
|
+
},
|
|
5783
|
+
job_id,
|
|
5784
|
+
headers,
|
|
5785
|
+
);
|
|
5786
|
+
|
|
5787
|
+
if (codex_ret.code < 0) {
|
|
5788
|
+
return `Codex readonly lookup failed: ${get_error_message(codex_ret.data, 'unknown error')}`;
|
|
5789
|
+
}
|
|
5790
|
+
|
|
5791
|
+
const events = codex_ret?.data?.events || [];
|
|
5792
|
+
const final_message = [...events].reverse().find((event) => event?.item?.type === 'agent_message' && event.item.text)?.item?.text;
|
|
5793
|
+
return final_message || 'Codex readonly lookup completed without a final answer.';
|
|
5794
|
+
},
|
|
5795
|
+
}),
|
|
5796
|
+
);
|
|
5797
|
+
};
|
|
5798
|
+
|
|
5799
|
+
const add_xuda_public_website_tool = function ({ name, description }) {
|
|
5800
|
+
if (reference_type !== 'ai_agents' && !prompt_suggestion_activated && !chat_suggestion_activated) {
|
|
5801
|
+
eligible_agent = false;
|
|
5802
|
+
return;
|
|
5803
|
+
}
|
|
5804
|
+
|
|
5805
|
+
const website_origin = _conf?.internal_ai_agents?.public_website_url || 'https://xuda.ai';
|
|
5806
|
+
const dump_dir = path.join(os.tmpdir(), 'xuda_public_website_dump', new URL(website_origin).hostname.replace(/[^a-z0-9.-]/gi, '_'));
|
|
5807
|
+
const manifest_path = path.join(dump_dir, 'manifest.json');
|
|
5808
|
+
const ttl_ms = Number(_conf?.internal_ai_agents?.public_website_dump_ttl_ms || 10 * 60 * 1000);
|
|
5809
|
+
const cache_version = 2;
|
|
5810
|
+
const website_base = website_origin.replace(/\/$/, '');
|
|
5811
|
+
|
|
5812
|
+
const decode_html = function (value = '') {
|
|
5813
|
+
return String(value)
|
|
5814
|
+
.replace(/ /gi, ' ')
|
|
5815
|
+
.replace(/&/gi, '&')
|
|
5816
|
+
.replace(/</gi, '<')
|
|
5817
|
+
.replace(/>/gi, '>')
|
|
5818
|
+
.replace(/"/gi, '"')
|
|
5819
|
+
.replace(/'/g, "'");
|
|
5820
|
+
};
|
|
5821
|
+
|
|
5822
|
+
const strip_html = function (html = '') {
|
|
5823
|
+
return decode_html(
|
|
5824
|
+
String(html)
|
|
5825
|
+
.replace(/<script[\s\S]*?<\/script>/gi, ' ')
|
|
5826
|
+
.replace(/<style[\s\S]*?<\/style>/gi, ' ')
|
|
5827
|
+
.replace(/<noscript[\s\S]*?<\/noscript>/gi, ' ')
|
|
5828
|
+
.replace(/<svg[\s\S]*?<\/svg>/gi, ' ')
|
|
5829
|
+
.replace(/<[^>]+>/g, ' ')
|
|
5830
|
+
.replace(/\s+/g, ' ')
|
|
5831
|
+
.trim(),
|
|
5832
|
+
);
|
|
5833
|
+
};
|
|
5834
|
+
|
|
5835
|
+
const extract_title = function (html = '') {
|
|
5836
|
+
const match = String(html).match(/<title[^>]*>([\s\S]*?)<\/title>/i);
|
|
5837
|
+
return match ? decode_html(match[1]).replace(/\s+/g, ' ').trim() : '';
|
|
5838
|
+
};
|
|
5839
|
+
|
|
5840
|
+
const get_terms = function (question) {
|
|
5841
|
+
const terms = String(question)
|
|
5842
|
+
.toLowerCase()
|
|
5843
|
+
.replace(/[^a-z0-9\s-]/g, ' ')
|
|
5844
|
+
.split(/\s+/)
|
|
5845
|
+
.filter((term) => term.length > 2 && !['the', 'and', 'for', 'about', 'tell', 'with', 'from', 'what', 'who', 'how', 'xuda'].includes(term));
|
|
5846
|
+
if (/\baddress|where|location|located|office|contact\b/i.test(question)) {
|
|
5847
|
+
terms.push('address', 'contact', 'llc', 'boca', 'raton', 'florida');
|
|
5848
|
+
}
|
|
5849
|
+
return [...new Set(terms)];
|
|
5850
|
+
};
|
|
5851
|
+
|
|
5852
|
+
const score_page = function (page, terms, question) {
|
|
5853
|
+
const haystack = `${page.url} ${page.title} ${page.text}`.toLowerCase();
|
|
5854
|
+
let score = 0;
|
|
5855
|
+
for (const term of terms) {
|
|
5856
|
+
if (haystack.includes(term)) score += term.length > 4 ? 3 : 1;
|
|
5857
|
+
}
|
|
5858
|
+
if (/\b(company|about|xuda)\b/i.test(question) && new URL(page.url).pathname === '/') score += 20;
|
|
5859
|
+
if (/\bdocs?|guide|how|cli|dashboard|deploy|agent|app|vps|database|couchdb\b/i.test(question) && page.url.includes('/docs')) score += 8;
|
|
5860
|
+
if (/\bnetwork|ambassador|mentor|city|region\b/i.test(question) && page.url.includes('network')) score += 8;
|
|
5861
|
+
if (/\baddress|where|location|located|office|contact\b/i.test(question) && /\/legal\/privacy-policy/i.test(page.url)) score += 100;
|
|
5862
|
+
if (/\baddress|where|location|located|office|contact\b/i.test(question) && /\/legal\/terms|contact/i.test(page.url)) score += 30;
|
|
5863
|
+
return score;
|
|
5864
|
+
};
|
|
5865
|
+
|
|
5866
|
+
const make_snippet = function (text = '', terms = [], max_length = 3000) {
|
|
5867
|
+
const lower = text.toLowerCase();
|
|
5868
|
+
const anchors = ['address', 'contact us', 'xuda llc', 'boca raton', 'florida', ...terms];
|
|
5869
|
+
let index = -1;
|
|
5870
|
+
for (const anchor of anchors) {
|
|
5871
|
+
index = lower.indexOf(String(anchor).toLowerCase());
|
|
5872
|
+
if (index > -1) break;
|
|
5873
|
+
}
|
|
5874
|
+
if (index < 0) return text.slice(0, max_length);
|
|
5875
|
+
const start = Math.max(0, index - Math.floor(max_length / 3));
|
|
5876
|
+
const end = Math.min(text.length, start + max_length);
|
|
5877
|
+
return `${start > 0 ? '...' : ''}${text.slice(start, end)}${end < text.length ? '...' : ''}`;
|
|
5878
|
+
};
|
|
5879
|
+
|
|
5880
|
+
const extract_public_facts = function (page, question) {
|
|
5881
|
+
const facts = [];
|
|
5882
|
+
if (/\baddress|where|location|located|office|contact\b/i.test(question)) {
|
|
5883
|
+
const address_match = String(page.text || '').match(/Address:\s*([^|]+?)(?=\s+By using|\s+Privacy Policy|\s+Terms|\s*$)/i);
|
|
5884
|
+
if (address_match?.[1]) {
|
|
5885
|
+
facts.push({
|
|
5886
|
+
label: 'Address',
|
|
5887
|
+
value: address_match[1].replace(/\s+/g, ' ').trim(),
|
|
5888
|
+
url: page.url,
|
|
5889
|
+
});
|
|
5890
|
+
}
|
|
5891
|
+
}
|
|
5892
|
+
return facts;
|
|
5893
|
+
};
|
|
5894
|
+
|
|
5895
|
+
const fetch_text = async function (url, timeout_ms = 8000) {
|
|
5896
|
+
const controller = new AbortController();
|
|
5897
|
+
const timer = setTimeout(() => controller.abort(), timeout_ms);
|
|
5898
|
+
try {
|
|
5899
|
+
const res = await fetch(url, {
|
|
5900
|
+
signal: controller.signal,
|
|
5901
|
+
headers: { 'User-Agent': 'Xuda Ambassador Support Readonly Website Indexer' },
|
|
5902
|
+
});
|
|
5903
|
+
if (!res.ok) throw new Error(`${url} returned ${res.status}`);
|
|
5904
|
+
return await res.text();
|
|
5905
|
+
} finally {
|
|
5906
|
+
clearTimeout(timer);
|
|
5907
|
+
}
|
|
5908
|
+
};
|
|
5909
|
+
|
|
5910
|
+
const load_dump = async function () {
|
|
5911
|
+
try {
|
|
5912
|
+
const manifest = JSON.parse(await fs.promises.readFile(manifest_path, 'utf8'));
|
|
5913
|
+
if (Number(manifest.cache_version || 0) === cache_version && Date.now() - Number(manifest.created_ts || 0) < ttl_ms && Array.isArray(manifest.pages) && manifest.pages.length) {
|
|
5914
|
+
const pages = [];
|
|
5915
|
+
for (const page of manifest.pages) {
|
|
5916
|
+
try {
|
|
5917
|
+
pages.push(JSON.parse(await fs.promises.readFile(path.join(dump_dir, page.file), 'utf8')));
|
|
5918
|
+
} catch (_) {
|
|
5919
|
+
/* ignore corrupt cache item */
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
if (pages.length) return { pages, from_cache: true };
|
|
5923
|
+
}
|
|
5924
|
+
} catch (_) {
|
|
5925
|
+
/* build cache below */
|
|
5926
|
+
}
|
|
5927
|
+
|
|
5928
|
+
await fs.promises.mkdir(dump_dir, { recursive: true });
|
|
5929
|
+
const sitemap_xml = await fetch_text(`${website_base}/sitemap.xml`, 8000);
|
|
5930
|
+
const priority_urls = [
|
|
5931
|
+
`${website_base}/`,
|
|
5932
|
+
`${website_base}/about`,
|
|
5933
|
+
`${website_base}/legal/privacy-policy`,
|
|
5934
|
+
`${website_base}/legal/terms`,
|
|
5935
|
+
`${website_base}/contact`,
|
|
5936
|
+
];
|
|
5937
|
+
const sitemap_urls = [...sitemap_xml.matchAll(/<loc>([\s\S]*?)<\/loc>/gi)]
|
|
5938
|
+
.map((match) => decode_html(match[1]).trim())
|
|
5939
|
+
.filter((url) => {
|
|
5940
|
+
try {
|
|
5941
|
+
const parsed = new URL(url);
|
|
5942
|
+
return parsed.origin === website_base && !/\.(png|jpe?g|gif|webp|svg|pdf|zip)$/i.test(parsed.pathname);
|
|
5943
|
+
} catch (_) {
|
|
5944
|
+
return false;
|
|
5945
|
+
}
|
|
5946
|
+
})
|
|
5947
|
+
.slice(0, 120);
|
|
5948
|
+
const urls = [...new Set([...priority_urls, ...sitemap_urls])];
|
|
5949
|
+
|
|
5950
|
+
const pages = [];
|
|
5951
|
+
for (const url of urls) {
|
|
5952
|
+
try {
|
|
5953
|
+
const html = await fetch_text(url, 8000);
|
|
5954
|
+
const page = {
|
|
5955
|
+
url,
|
|
5956
|
+
title: extract_title(html),
|
|
5957
|
+
text: strip_html(html).slice(0, 80000),
|
|
5958
|
+
fetched_ts: Date.now(),
|
|
5959
|
+
};
|
|
5960
|
+
if (page.text.length < 80) continue;
|
|
5961
|
+
const file = `${crypto.createHash('sha1').update(url).digest('hex')}.json`;
|
|
5962
|
+
await fs.promises.writeFile(path.join(dump_dir, file), JSON.stringify(page, null, 2));
|
|
5963
|
+
pages.push({ ...page, file });
|
|
5964
|
+
} catch (err) {
|
|
5965
|
+
pages.push({ url, title: '', text: `Fetch failed: ${err.message || String(err)}`, fetch_error: true });
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
|
|
5969
|
+
await fs.promises.writeFile(
|
|
5970
|
+
manifest_path,
|
|
5971
|
+
JSON.stringify(
|
|
5972
|
+
{
|
|
5973
|
+
source: website_origin,
|
|
5974
|
+
cache_version,
|
|
5975
|
+
created_ts: Date.now(),
|
|
5976
|
+
pages: pages.filter((page) => !page.fetch_error).map((page) => ({ url: page.url, file: page.file, title: page.title })),
|
|
5977
|
+
},
|
|
5978
|
+
null,
|
|
5979
|
+
2,
|
|
5980
|
+
),
|
|
5981
|
+
);
|
|
5982
|
+
return { pages, from_cache: false };
|
|
5983
|
+
};
|
|
5984
|
+
|
|
5985
|
+
tools.push(
|
|
5986
|
+
tool({
|
|
5987
|
+
name: (name || 'Xuda Ambassador Public Website Readonly').substring(0, 60),
|
|
5988
|
+
description: description || 'Readonly lookup against public xuda.ai website pages for ambassador support answers.',
|
|
5989
|
+
parameters: z.object({
|
|
5990
|
+
question: z.string().describe('The support question to answer from public xuda.ai website pages.'),
|
|
5991
|
+
}),
|
|
5992
|
+
async execute(e) {
|
|
5993
|
+
const question = String(e?.question || '').trim();
|
|
5994
|
+
if (!question) {
|
|
5995
|
+
return 'question is required';
|
|
5996
|
+
}
|
|
5997
|
+
|
|
5998
|
+
const run_lookup = async function () {
|
|
5999
|
+
const { pages } = await load_dump();
|
|
6000
|
+
const terms = get_terms(question);
|
|
6001
|
+
const ranked = pages
|
|
6002
|
+
.filter((page) => !page.fetch_error)
|
|
6003
|
+
.map((page) => ({ page, score: score_page(page, terms, question) }))
|
|
6004
|
+
.filter((item) => item.score > 0)
|
|
6005
|
+
.sort((a, b) => b.score - a.score)
|
|
6006
|
+
.slice(0, 5)
|
|
6007
|
+
.map((item) => ({
|
|
6008
|
+
score: item.score,
|
|
6009
|
+
url: item.page.url,
|
|
6010
|
+
title: item.page.title,
|
|
6011
|
+
snippet: make_snippet(item.page.text, terms),
|
|
6012
|
+
}));
|
|
6013
|
+
const facts = pages
|
|
6014
|
+
.filter((page) => !page.fetch_error)
|
|
6015
|
+
.flatMap((page) => extract_public_facts(page, question))
|
|
6016
|
+
.slice(0, 5);
|
|
6017
|
+
|
|
6018
|
+
return {
|
|
6019
|
+
source: website_origin,
|
|
6020
|
+
readonly: true,
|
|
6021
|
+
question,
|
|
6022
|
+
facts,
|
|
6023
|
+
result_count: ranked.length,
|
|
6024
|
+
results: ranked,
|
|
6025
|
+
instruction: ranked.length
|
|
6026
|
+
? 'Answer only from these public xuda.ai website facts and snippets. If facts are present, use them as the primary source. Cite page URLs inline when useful. Do not mention internal cache, dump folders, or implementation details.'
|
|
6027
|
+
: 'No relevant public xuda.ai pages were found. Say that the public xuda.ai website did not contain enough information and ask for a narrower page or topic. Do not mention internal cache, dump folders, or implementation details.',
|
|
6028
|
+
};
|
|
6029
|
+
};
|
|
6030
|
+
|
|
6031
|
+
try {
|
|
6032
|
+
const data = await Promise.race([
|
|
6033
|
+
run_lookup(),
|
|
6034
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('xuda.ai website lookup timed out')), 20000)),
|
|
6035
|
+
]);
|
|
6036
|
+
return JSON.stringify(data, null, 2);
|
|
6037
|
+
} catch (err) {
|
|
6038
|
+
return `xuda.ai website lookup failed: ${err.message || String(err)}`;
|
|
6039
|
+
}
|
|
6040
|
+
},
|
|
6041
|
+
}),
|
|
6042
|
+
);
|
|
6043
|
+
};
|
|
6044
|
+
|
|
5745
6045
|
for (const [key, val] of Object.entries(ai_agent_doc?.agentConfig?.agent_tools || [])) {
|
|
5746
6046
|
const { name = '', description = '' } = val;
|
|
5747
6047
|
switch (val.type) {
|
|
6048
|
+
case 'xuda_network_ambassador_dev_couchdb_readonly': {
|
|
6049
|
+
add_xuda_public_website_tool({
|
|
6050
|
+
name: name || 'Xuda Ambassador Public Website Readonly',
|
|
6051
|
+
description: description || 'Readonly lookup against public xuda.ai website pages for ambassador support answers.',
|
|
6052
|
+
});
|
|
6053
|
+
break;
|
|
6054
|
+
}
|
|
6055
|
+
|
|
6056
|
+
case 'xuda_network_mentor_dev_server_readonly': {
|
|
6057
|
+
add_internal_codex_tool({
|
|
6058
|
+
name: name || 'Xuda Mentor Dev Server Readonly',
|
|
6059
|
+
description: description || 'Readonly Codex lookup on /var/xuda of the dev server for technical mentor answers.',
|
|
6060
|
+
system_prompt: `You are Codex helping a Xuda Network mentor answer technical questions about the Xuda codebase.
|
|
6061
|
+
|
|
6062
|
+
Scope:
|
|
6063
|
+
- You may inspect only the dev server ${_conf?.internal_ai_agents?.dev_server_host || 'dev.xuda.ai'}.
|
|
6064
|
+
- You may use SSH only for readonly inspection.
|
|
6065
|
+
- You may read only under /var/xuda.
|
|
6066
|
+
- Prefer safe inspection commands such as pwd, ls, find, rg, sed -n, head, tail, wc, git status, git diff --stat, git log --oneline, and git show.
|
|
6067
|
+
|
|
6068
|
+
Hard restrictions:
|
|
6069
|
+
- Never access config, config_dev, .env files, secret folders, SSH keys, certificates, credential files, database dumps, backups, logs likely to contain credentials, or any path outside /var/xuda.
|
|
6070
|
+
- Never query CouchDB or any database.
|
|
6071
|
+
- Never use network commands to call internal services.
|
|
6072
|
+
- Never run commands that write, mutate, install, delete, restart, deploy, publish, chmod/chown, kill processes, or change system state.
|
|
6073
|
+
- Never reveal passwords, tokens, API keys, private keys, names of private people, private emails, personal information, customer data, security details, or anything that could harm Xuda, its team, customers, or product security.
|
|
6074
|
+
- If the answer requires forbidden access, say it is outside the readonly mentor scope.
|
|
6075
|
+
- If sensitive data appears accidentally, do not quote it. State that sensitive output was omitted.`,
|
|
6076
|
+
});
|
|
6077
|
+
break;
|
|
6078
|
+
}
|
|
6079
|
+
|
|
5748
6080
|
case 'web_search': {
|
|
5749
6081
|
tools.push(webSearchTool());
|
|
5750
6082
|
break;
|
|
@@ -6033,8 +6365,8 @@ const load_ai_agent_doc = async function (app_id, agent_id) {
|
|
|
6033
6365
|
ai_agent_doc.reference_doc = reference_doc;
|
|
6034
6366
|
} else if (ai_agent_doc.studio_meta.installed_from_app_uid) {
|
|
6035
6367
|
const reference_doc = _.cloneDeep(ai_agent_doc);
|
|
6036
|
-
await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid);
|
|
6037
|
-
ai_agent_doc = await db_module.get_app_couch_doc_native(
|
|
6368
|
+
const source_app_id = ai_agent_doc.studio_meta.installed_from_app_id || (await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid));
|
|
6369
|
+
ai_agent_doc = await db_module.get_app_couch_doc_native(source_app_id, ai_agent_doc.studio_meta.share_item_id || ai_agent_doc._id);
|
|
6038
6370
|
ai_agent_doc.reference_doc = reference_doc;
|
|
6039
6371
|
}
|
|
6040
6372
|
|
|
@@ -7406,10 +7738,10 @@ const get_plugin_tool = async function (app_id, uid, plugin_name, method, prop_d
|
|
|
7406
7738
|
}
|
|
7407
7739
|
};
|
|
7408
7740
|
|
|
7409
|
-
const create_and_upload_image_to_drive = async function (drive_type, file_path, file_name, prompt, numGenerations, uid, app_id, job_id, headers = {}, is_system, tags = [], account_profile_info) {
|
|
7741
|
+
const create_and_upload_image_to_drive = async function (drive_type, file_path, file_name, prompt, numGenerations, uid, app_id, job_id, headers = {}, is_system, tags = [], account_profile_info, width = 256, height = 256) {
|
|
7410
7742
|
try {
|
|
7411
7743
|
// 1. Generate the images
|
|
7412
|
-
let result = await create_image(uid, prompt, undefined, undefined, numGenerations,
|
|
7744
|
+
let result = await create_image(uid, prompt, undefined, undefined, numGenerations, width, height, { drive_type, file_path, file_name }, account_profile_info);
|
|
7413
7745
|
|
|
7414
7746
|
// Normalize to array
|
|
7415
7747
|
const images = Array.isArray(result) ? result : [result];
|
|
@@ -8250,12 +8582,12 @@ const create_ai_agent_image = async function (req, job_id, headers) {
|
|
|
8250
8582
|
const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`);
|
|
8251
8583
|
|
|
8252
8584
|
const { app_id, uid, ai_agent_id, tags } = req;
|
|
8253
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
8585
|
+
const account_profile_info = req.account_profile_info || (await get_active_account_profile_info(uid));
|
|
8254
8586
|
const ai_agent_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, ai_agent_id);
|
|
8255
8587
|
const account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
|
|
8256
8588
|
|
|
8257
8589
|
// faceless humanoid for business
|
|
8258
|
-
if (account_doc.account_info.account_type === 'business') {
|
|
8590
|
+
if (account_doc.account_info.account_type === 'business' || ai_agent_doc.studio_meta?.force_faceless_agent_image) {
|
|
8259
8591
|
const prompt = `
|
|
8260
8592
|
Create a futuristic, faceless humanoid profile portrait with a transparent background.
|
|
8261
8593
|
|
|
@@ -8290,7 +8622,7 @@ const create_ai_agent_image = async function (req, job_id, headers) {
|
|
|
8290
8622
|
|
|
8291
8623
|
`;
|
|
8292
8624
|
|
|
8293
|
-
const images_arr = await create_and_upload_image_to_drive('studio', 'Progs Thumbnails', ai_agent_id, prompt, 1, uid, app_id, job_id, headers, false, tags, account_profile_info);
|
|
8625
|
+
const images_arr = await create_and_upload_image_to_drive('studio', 'Progs Thumbnails', ai_agent_id, prompt, 1, uid, app_id, job_id, headers, false, tags, account_profile_info, 1024, 1024);
|
|
8294
8626
|
return { code: 1, data: images_arr[0] };
|
|
8295
8627
|
}
|
|
8296
8628
|
|
|
@@ -13538,8 +13870,8 @@ export const get_chat_suggestions = async function (req) {
|
|
|
13538
13870
|
ai_agent_doc.reference_doc = reference_doc;
|
|
13539
13871
|
} else if (ai_agent_doc.studio_meta.installed_from_app_uid) {
|
|
13540
13872
|
const reference_doc = _.cloneDeep(ai_agent_doc);
|
|
13541
|
-
await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid);
|
|
13542
|
-
ai_agent_doc = await db_module.get_app_couch_doc_native(
|
|
13873
|
+
const source_app_id = ai_agent_doc.studio_meta.installed_from_app_id || (await get_account_default_project_id(ai_agent_doc.studio_meta.installed_from_app_uid));
|
|
13874
|
+
ai_agent_doc = await db_module.get_app_couch_doc_native(source_app_id, ai_agent_doc.studio_meta.share_item_id || ai_agent_doc._id);
|
|
13543
13875
|
ai_agent_doc.reference_doc = reference_doc;
|
|
13544
13876
|
}
|
|
13545
13877
|
|