@xuda.io/ai_module 1.1.5638 → 1.1.5640
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 +153 -19
- package/index_ms.mjs +4 -0
- package/index_msa.mjs +4 -0
- package/old.mjs +0 -1
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -413,7 +413,6 @@ const get_studio_table_info_tool = tool({
|
|
|
413
413
|
async execute(e, RunContext) {
|
|
414
414
|
const { table } = e;
|
|
415
415
|
const { app_id, uid } = RunContext.context;
|
|
416
|
-
debugger;
|
|
417
416
|
if (!table) throw new Error('got null in the table parameter');
|
|
418
417
|
|
|
419
418
|
try {
|
|
@@ -558,7 +557,6 @@ const fetch_data_tool = tool({
|
|
|
558
557
|
}
|
|
559
558
|
|
|
560
559
|
const validateQuery_result = validateQueryAgainstTable(query_obj, table_doc.tableFields);
|
|
561
|
-
debugger;
|
|
562
560
|
if (!validateQuery_result.isValid) {
|
|
563
561
|
// console.error('Validation failed:', validateQuery_result.errors);
|
|
564
562
|
throw new Error(`Validation failed: ${JSON.stringify(validateQuery_result.errors)}`);
|
|
@@ -795,7 +793,6 @@ const create_index_tool = tool({
|
|
|
795
793
|
const { index } = e;
|
|
796
794
|
const { app_id, uid } = RunContext.context;
|
|
797
795
|
try {
|
|
798
|
-
debugger;
|
|
799
796
|
const index_obj = JSON5.parse(index);
|
|
800
797
|
console.log('Create Index', index_obj);
|
|
801
798
|
const project_db = await get_project_db(app_id);
|
|
@@ -3993,7 +3990,6 @@ export const update_ai_agent_properties = async function (doc, app_id, uid, fiel
|
|
|
3993
3990
|
db_doc.agentConfig.agent_industry = await get_agent_industry();
|
|
3994
3991
|
db_doc.studio_meta.agent_industry = db_doc.agentConfig.agent_industry;
|
|
3995
3992
|
}
|
|
3996
|
-
debugger;
|
|
3997
3993
|
if (db_doc.agentConfig.agent_user_guide && (fields_changed.agent_user_guide_changed || fields_changed.all)) {
|
|
3998
3994
|
db_doc.agentConfig.agent_user_guide_fields = await get_agent_user_guide_fields();
|
|
3999
3995
|
db_doc.studio_meta.agent_user_guide_fields = db_doc.agentConfig.agent_user_guide_fields;
|
|
@@ -4122,7 +4118,6 @@ export const update_thumbnail = async function (type, doc, app_id, uid, job_id,
|
|
|
4122
4118
|
}
|
|
4123
4119
|
return save_ret;
|
|
4124
4120
|
} catch (error) {
|
|
4125
|
-
debugger;
|
|
4126
4121
|
}
|
|
4127
4122
|
// }, 500);
|
|
4128
4123
|
};
|
|
@@ -4738,6 +4733,154 @@ export const diagnose_vps_snapshot = async function (req) {
|
|
|
4738
4733
|
}
|
|
4739
4734
|
};
|
|
4740
4735
|
|
|
4736
|
+
// Map a studio program's menuType to a friendly, user-facing noun so the
|
|
4737
|
+
// release-notes prompt talks about "screens" and "workflows" rather than the
|
|
4738
|
+
// internal type ids. Unknown types fall back to a de-underscored label.
|
|
4739
|
+
const _human_menu_type = function (t) {
|
|
4740
|
+
const map = {
|
|
4741
|
+
component: 'screen',
|
|
4742
|
+
workflow: 'workflow',
|
|
4743
|
+
table: 'data table',
|
|
4744
|
+
javascript: 'logic',
|
|
4745
|
+
js: 'logic',
|
|
4746
|
+
ai_agent: 'AI agent',
|
|
4747
|
+
api: 'API',
|
|
4748
|
+
style: 'style',
|
|
4749
|
+
function: 'function',
|
|
4750
|
+
query: 'query',
|
|
4751
|
+
report: 'report',
|
|
4752
|
+
};
|
|
4753
|
+
return map[t] || (t ? String(t).replace(/_/g, ' ') : 'item');
|
|
4754
|
+
};
|
|
4755
|
+
|
|
4756
|
+
// Generate user-facing release notes for a build the developer is about to
|
|
4757
|
+
// create. READ-ONLY: reads the project's PUBLISHED studio programs, diffs them
|
|
4758
|
+
// against the previous release's timestamp to see what changed since the last
|
|
4759
|
+
// build, and asks the model for a concise, plain-language changelog. Never
|
|
4760
|
+
// writes the release or mutates a program — the notes are returned for the
|
|
4761
|
+
// developer to review/edit before they hit Build. Credits are metered to the
|
|
4762
|
+
// caller via submit_chat_gpt_prompt -> record_ai_usage.
|
|
4763
|
+
// req: { app_id, version?, build_type?(major|minor|patch), instructions? }
|
|
4764
|
+
// -> { code:1, data:{ notes, changed_count, since_build, version } }
|
|
4765
|
+
// { code:-6, insufficient_credits:true } when the account is out of credits.
|
|
4766
|
+
export const generate_release_notes = async function (req) {
|
|
4767
|
+
const uid = req.uid || req.token_ret?.data?.uid;
|
|
4768
|
+
const app_id_in = req.app_id;
|
|
4769
|
+
const version = String(req.version || '').trim();
|
|
4770
|
+
const build_type = String(req.build_type || '').trim(); // major | minor | patch
|
|
4771
|
+
const steer = String(req.instructions || '')
|
|
4772
|
+
.trim()
|
|
4773
|
+
.slice(0, 400); // optional free-text hint from the developer
|
|
4774
|
+
|
|
4775
|
+
if (!uid) return { code: -1, data: 'not authorized' };
|
|
4776
|
+
if (!app_id_in) return { code: -1, data: 'app_id required' };
|
|
4777
|
+
|
|
4778
|
+
// Credit gate — usage is metered, but block up-front if the account is
|
|
4779
|
+
// already out (validate_credits_limit RETURNS the error, never throws).
|
|
4780
|
+
const credit_err = await validate_credits_limit(uid, null, _conf.release_notes?.model || _conf.default_ai_model, 'release notes');
|
|
4781
|
+
if (credit_err) return { code: -6, data: credit_err.message || 'insufficient credits', insufficient_credits: true };
|
|
4782
|
+
|
|
4783
|
+
// Resolve to the project (master) app — build/release data lives there.
|
|
4784
|
+
let app_obj;
|
|
4785
|
+
let app_ref;
|
|
4786
|
+
try {
|
|
4787
|
+
app_ref = await _common.get_project_app_id(app_id_in, true);
|
|
4788
|
+
const app_ret = await db_module.get_app_obj(app_ref);
|
|
4789
|
+
if (app_ret.code < 0 || !app_ret.data) return { code: -1, data: 'app not found' };
|
|
4790
|
+
app_obj = app_ret.data;
|
|
4791
|
+
} catch (e) {
|
|
4792
|
+
return { code: -1, data: 'app not found' };
|
|
4793
|
+
}
|
|
4794
|
+
|
|
4795
|
+
const app_name = app_obj.app_name || 'the app';
|
|
4796
|
+
const prev_version = app_obj.app_publish_info?.version || '';
|
|
4797
|
+
const last_build = app_obj.app_publish_info?.app_lastBuild || 0;
|
|
4798
|
+
|
|
4799
|
+
// Cutoff = the previous release's timestamp. Any program whose `ts`
|
|
4800
|
+
// (last-saved time) is newer than this changed since that build.
|
|
4801
|
+
let since_ts = 0;
|
|
4802
|
+
try {
|
|
4803
|
+
const rel = await db_module.find_app_couch_query(app_ref, {
|
|
4804
|
+
selector: { docType: 'release', stat: { $lt: 4 } },
|
|
4805
|
+
sort: [{ build_id: 'desc' }],
|
|
4806
|
+
limit: 1,
|
|
4807
|
+
});
|
|
4808
|
+
since_ts = rel.docs?.[0]?.date || 0;
|
|
4809
|
+
} catch (e) {
|
|
4810
|
+
since_ts = 0;
|
|
4811
|
+
}
|
|
4812
|
+
|
|
4813
|
+
// Published programs, projected to a tiny summary (bounds prompt tokens).
|
|
4814
|
+
let progs = [];
|
|
4815
|
+
try {
|
|
4816
|
+
const res = await db_module.find_app_couch_query(app_ref, {
|
|
4817
|
+
selector: { docType: 'studio', stat: 3 },
|
|
4818
|
+
fields: ['ts', 'properties.menuType', 'properties.menuName', 'properties.menuTitle'],
|
|
4819
|
+
limit: 99999,
|
|
4820
|
+
});
|
|
4821
|
+
progs = res.docs || [];
|
|
4822
|
+
} catch (e) {
|
|
4823
|
+
progs = [];
|
|
4824
|
+
}
|
|
4825
|
+
|
|
4826
|
+
const first_build = !since_ts || last_build === 0;
|
|
4827
|
+
const changed = progs.filter((p) => p && (first_build || (p.ts && p.ts > since_ts))).sort((a, b) => (b.ts || 0) - (a.ts || 0));
|
|
4828
|
+
|
|
4829
|
+
// Compact, deduped change list for the prompt (name + type; capped at 80).
|
|
4830
|
+
const seen = new Set();
|
|
4831
|
+
const items = [];
|
|
4832
|
+
for (const p of changed) {
|
|
4833
|
+
const name = p.properties?.menuTitle || p.properties?.menuName || 'Untitled';
|
|
4834
|
+
const type = _human_menu_type(p.properties?.menuType);
|
|
4835
|
+
const key = `${type}:${name}`;
|
|
4836
|
+
if (seen.has(key)) continue;
|
|
4837
|
+
seen.add(key);
|
|
4838
|
+
items.push({ name, type });
|
|
4839
|
+
if (items.length >= 80) break;
|
|
4840
|
+
}
|
|
4841
|
+
|
|
4842
|
+
const by_type = {};
|
|
4843
|
+
for (const it of items) by_type[it.type] = (by_type[it.type] || 0) + 1;
|
|
4844
|
+
const type_summary = Object.entries(by_type)
|
|
4845
|
+
.map(([t, n]) => `${n} ${t}${n > 1 ? 's' : ''}`)
|
|
4846
|
+
.join(', ');
|
|
4847
|
+
|
|
4848
|
+
const parts = [
|
|
4849
|
+
`You are writing end-user release notes for a no-code app called "${app_name}" built on the Xuda platform.`,
|
|
4850
|
+
`The developer is publishing a new build to every deployment of this app. Write short, friendly, user-facing release notes that tell the people who USE the app what is new — in plain language, not technical jargon.`,
|
|
4851
|
+
'',
|
|
4852
|
+
'RULES:',
|
|
4853
|
+
'- Output ONLY 2 to 5 concise bullet points, each a single short line. No title, no preamble, no sign-off — bullets only.',
|
|
4854
|
+
'- Describe outcomes and improvements ("New School Info screen", "Faster class enrollment"), never internal file names or program types.',
|
|
4855
|
+
'- Group related changes into one bullet instead of listing every item.',
|
|
4856
|
+
'- Neutral, professional tone. Never invent features that the change list does not imply.',
|
|
4857
|
+
'- Write in the SAME language as the program names below (e.g. Hebrew names -> Hebrew notes).',
|
|
4858
|
+
steer ? `- The developer added this guidance — follow it: ${steer}` : '',
|
|
4859
|
+
'',
|
|
4860
|
+
`Version: ${prev_version ? prev_version + ' -> ' : ''}${version || '(new)'}${build_type ? ` (${build_type} release)` : ''}`,
|
|
4861
|
+
first_build ? 'This is the FIRST published build. Write a brief "initial release" style note highlighting the main areas of the app.' : `Programs changed since the last build (${type_summary || 'general updates'}):`,
|
|
4862
|
+
items.length ? items.map((it) => `- ${it.name} (${it.type})`).join('\n') : '(No specific program changes were detected — write a brief note about minor improvements and stability fixes.)',
|
|
4863
|
+
].filter(Boolean);
|
|
4864
|
+
|
|
4865
|
+
// account_profile_info is REQUIRED for usage to be metered: record_ai_usage
|
|
4866
|
+
// throws (and skips broadcast_credits, so the nav meter never moves) without
|
|
4867
|
+
// it. Fetch it like classify_external_app_scan / the chat flows do.
|
|
4868
|
+
const account_profile_info = await get_active_account_profile_info(uid);
|
|
4869
|
+
|
|
4870
|
+
const ret = await submit_chat_gpt_prompt({
|
|
4871
|
+
uid,
|
|
4872
|
+
prompt: parts.join('\n'),
|
|
4873
|
+
model: _conf.release_notes?.model || _conf.default_ai_model,
|
|
4874
|
+
metadata: { func: 'generate_release_notes', app_id: app_ref, version },
|
|
4875
|
+
account_profile_info,
|
|
4876
|
+
});
|
|
4877
|
+
if (ret.code < 0) return { code: -1, data: ret.data };
|
|
4878
|
+
|
|
4879
|
+
const notes = String(ret.data || '').trim();
|
|
4880
|
+
if (!notes) return { code: -1, data: 'no notes generated' };
|
|
4881
|
+
return { code: 1, data: { notes, changed_count: changed.length, since_build: last_build, version } };
|
|
4882
|
+
};
|
|
4883
|
+
|
|
4741
4884
|
function getFirstNWords(text, n = 10) {
|
|
4742
4885
|
// Split on whitespace, keep punctuation attached to words
|
|
4743
4886
|
const words = text.match(/\S+/g) || [];
|
|
@@ -4919,7 +5062,6 @@ export const create_conversation = async function (req, job_id, headers) {
|
|
|
4919
5062
|
|
|
4920
5063
|
return save_ret;
|
|
4921
5064
|
} catch (err) {
|
|
4922
|
-
debugger;
|
|
4923
5065
|
|
|
4924
5066
|
return { code: -5, data: err.message || String(err) };
|
|
4925
5067
|
}
|
|
@@ -5176,7 +5318,6 @@ const update_conversation_mood_level = async function (uid, target_contacts = []
|
|
|
5176
5318
|
}
|
|
5177
5319
|
}
|
|
5178
5320
|
} catch (err) {
|
|
5179
|
-
debugger;
|
|
5180
5321
|
}
|
|
5181
5322
|
};
|
|
5182
5323
|
|
|
@@ -7144,7 +7285,6 @@ Hard restrictions:
|
|
|
7144
7285
|
}
|
|
7145
7286
|
|
|
7146
7287
|
try {
|
|
7147
|
-
debugger;
|
|
7148
7288
|
const api_allow_methods = Object.keys(_conf.cpi_methods);
|
|
7149
7289
|
for (const method_name of api_allow_methods || []) {
|
|
7150
7290
|
const method_prop = _conf.cpi_methods[method_name];
|
|
@@ -7199,7 +7339,6 @@ Hard restrictions:
|
|
|
7199
7339
|
inputSchema[key] = get_z_item(key, val);
|
|
7200
7340
|
}
|
|
7201
7341
|
} catch (error) {
|
|
7202
|
-
debugger;
|
|
7203
7342
|
}
|
|
7204
7343
|
}
|
|
7205
7344
|
try {
|
|
@@ -7231,11 +7370,9 @@ Hard restrictions:
|
|
|
7231
7370
|
}),
|
|
7232
7371
|
);
|
|
7233
7372
|
} catch (error) {
|
|
7234
|
-
debugger;
|
|
7235
7373
|
}
|
|
7236
7374
|
}
|
|
7237
7375
|
} catch (error) {
|
|
7238
|
-
debugger;
|
|
7239
7376
|
}
|
|
7240
7377
|
break;
|
|
7241
7378
|
}
|
|
@@ -7306,7 +7443,6 @@ Hard restrictions:
|
|
|
7306
7443
|
numGenerations: z.number().int().describe('Number generations to image create.').default(3),
|
|
7307
7444
|
}),
|
|
7308
7445
|
async execute(e, RunContext) {
|
|
7309
|
-
debugger;
|
|
7310
7446
|
const { prompt, numGenerations } = e;
|
|
7311
7447
|
|
|
7312
7448
|
try {
|
|
@@ -7690,7 +7826,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
7690
7826
|
});
|
|
7691
7827
|
|
|
7692
7828
|
agent.on('agent_tool_start', (context, tool, details) => {
|
|
7693
|
-
debugger;
|
|
7694
7829
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
7695
7830
|
emitToDashboard('stream_phase', `Starting ${tool?.name?.replaceAll('_', ' ')} tool`, { update: true });
|
|
7696
7831
|
});
|
|
@@ -7849,13 +7984,11 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
7849
7984
|
if (!prompt_suggestion_activated) {
|
|
7850
7985
|
// init_agent_hooks(agent);
|
|
7851
7986
|
agent.on('onToolStart', (context, tool, details) => {
|
|
7852
|
-
debugger;
|
|
7853
7987
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
7854
7988
|
// emitToDashboard('stream_phase', `Starting ${tool.name} tool`);
|
|
7855
7989
|
});
|
|
7856
7990
|
|
|
7857
7991
|
agent.on('onToolEnd', (context, tool, details) => {
|
|
7858
|
-
debugger;
|
|
7859
7992
|
// emitToDashboard('agent_tool_start', tool.name);
|
|
7860
7993
|
// emitToDashboard('stream_phase', `Starting ${tool.name} tool`);
|
|
7861
7994
|
});
|
|
@@ -8000,7 +8133,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8000
8133
|
emitToDashboard('stream_phase', 'Submitting chat', { update: true });
|
|
8001
8134
|
init_agent_hooks(_agent);
|
|
8002
8135
|
// const output = await runner.run(_agent, prompt, opt);
|
|
8003
|
-
debugger;
|
|
8004
8136
|
const output = await run_agent(_agent, prompt, opt);
|
|
8005
8137
|
const done = async function (output) {
|
|
8006
8138
|
try {
|
|
@@ -8048,7 +8180,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8048
8180
|
// }
|
|
8049
8181
|
const save_ret = await db_module.save_app_couch_doc_native(account_profile_info.app_id, in_conversation_item_obj);
|
|
8050
8182
|
|
|
8051
|
-
debugger;
|
|
8052
8183
|
|
|
8053
8184
|
let conversation_items = await client.conversations.items.list(conversation_doc.reference_conversation_id, { order: 'asc', after: last_conversation_item });
|
|
8054
8185
|
|
|
@@ -8070,7 +8201,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8070
8201
|
|
|
8071
8202
|
return save_ret;
|
|
8072
8203
|
} catch (error) {
|
|
8073
|
-
debugger;
|
|
8074
8204
|
}
|
|
8075
8205
|
// }
|
|
8076
8206
|
|
|
@@ -8135,7 +8265,6 @@ const ai_chat_conversation = async function (req, job_id, headers) {
|
|
|
8135
8265
|
};
|
|
8136
8266
|
// }
|
|
8137
8267
|
} catch (err) {
|
|
8138
|
-
debugger;
|
|
8139
8268
|
|
|
8140
8269
|
conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_id);
|
|
8141
8270
|
conversation_doc.ts = Date.now();
|
|
@@ -8239,6 +8368,11 @@ const auto_response = async function (uid, profile_id, contact_id, conversation_
|
|
|
8239
8368
|
|
|
8240
8369
|
let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
|
|
8241
8370
|
|
|
8371
|
+
// The main profile is the account's OWN identity: never auto-respond on it
|
|
8372
|
+
// (you don't auto-reply to yourself). Authoritative check via the account's
|
|
8373
|
+
// account_profile_id, independent of the stored auto_respond flag.
|
|
8374
|
+
if (account_doc?.account_profile_id && profile_id === account_doc.account_profile_id) return;
|
|
8375
|
+
|
|
8242
8376
|
if (account_profile_doc.auto_respond_mode === 'when_offline' && account_doc.socket_id) return;
|
|
8243
8377
|
if (!['always', 'when_offline'].includes(account_profile_doc.auto_respond_mode)) return;
|
|
8244
8378
|
|
package/index_ms.mjs
CHANGED
|
@@ -133,6 +133,10 @@ export const diagnose_vps_snapshot = async function (...args) {
|
|
|
133
133
|
return await broker.send_to_queue("diagnose_vps_snapshot", ...args);
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
+
export const generate_release_notes = async function (...args) {
|
|
137
|
+
return await broker.send_to_queue("generate_release_notes", ...args);
|
|
138
|
+
};
|
|
139
|
+
|
|
136
140
|
export const create_openai_conversation = async function (...args) {
|
|
137
141
|
return await broker.send_to_queue("create_openai_conversation", ...args);
|
|
138
142
|
};
|
package/index_msa.mjs
CHANGED
|
@@ -133,6 +133,10 @@ export const diagnose_vps_snapshot = function (...args) {
|
|
|
133
133
|
broker.send_to_queue_async("diagnose_vps_snapshot", ...args);
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
+
export const generate_release_notes = function (...args) {
|
|
137
|
+
broker.send_to_queue_async("generate_release_notes", ...args);
|
|
138
|
+
};
|
|
139
|
+
|
|
136
140
|
export const create_openai_conversation = function (...args) {
|
|
137
141
|
broker.send_to_queue_async("create_openai_conversation", ...args);
|
|
138
142
|
};
|
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
|