| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /**
- * 从 LobsterEnginePromptCatalog.java 提取 reg(...) 并生成 SQL 初始化脚本。
- * 用法: node java/fs-service/scripts/generate-lobster-engine-prompt-sql.js
- */
- const fs = require('fs');
- const path = require('path');
- const catalogPath = path.join(__dirname, '../src/main/java/com/fs/company/service/workflow/prompt/LobsterEnginePromptCatalog.java');
- const guardrailsPath = path.join(__dirname, '../src/main/java/com/fs/company/service/workflow/prompt/LobsterPromptGuardrails.java');
- const outPath = path.join(__dirname, '../../sql/lobster_engine_prompt_init.sql');
- const src = fs.readFileSync(catalogPath, 'utf8');
- const guardrailsSrc = fs.readFileSync(guardrailsPath, 'utf8');
- function loadGuardrailConstants() {
- const map = {};
- const re = /public static final String (\w+) = ([\s\S]*?);/g;
- let m;
- while ((m = re.exec(guardrailsSrc)) !== null) {
- try {
- map[m[1]] = evalConcat(m[2]);
- } catch (_) {
- /* skip non-string constants */
- }
- }
- return map;
- }
- const GUARDRAILS = loadGuardrailConstants();
- function unescapeJavaString(s) {
- return s
- .replace(/\\n/g, '\n')
- .replace(/\\t/g, '\t')
- .replace(/\\"/g, '"')
- .replace(/\\\\/g, '\\');
- }
- function evalConcat(expr) {
- const parts = [];
- let rest = expr.trim();
- while (rest.length > 0) {
- while (rest.length && /\s/.test(rest[0])) rest = rest.slice(1);
- if (!rest.length) break;
- if (rest[0] === '+') {
- rest = rest.slice(1).trim();
- continue;
- }
- if (rest[0] === '"') {
- let j = 1;
- let buf = '';
- while (j < rest.length) {
- if (rest[j] === '\\' && j + 1 < rest.length) {
- const esc = rest[j + 1];
- if (esc === 'n') buf += '\n';
- else if (esc === 't') buf += '\t';
- else if (esc === 'r') buf += '\r';
- else if (esc === '"') buf += '"';
- else if (esc === '\\') buf += '\\';
- else buf += esc;
- j += 2;
- continue;
- }
- if (rest[j] === '"') break;
- buf += rest[j++];
- }
- parts.push(buf);
- rest = rest.slice(j + 1).trim();
- continue;
- }
- if (rest.startsWith('null')) {
- parts.push('');
- rest = rest.slice(4).trim();
- continue;
- }
- const guardMatch = rest.match(/^LobsterPromptGuardrails\.(\w+)/);
- if (guardMatch) {
- parts.push(GUARDRAILS[guardMatch[1]] || '');
- rest = rest.slice(guardMatch[0].length).trim();
- continue;
- }
- throw new Error('Cannot parse expr fragment: ' + rest.slice(0, 60));
- }
- return parts.join('');
- }
- function sqlEscape(s) {
- if (s == null) return null;
- return s
- .replace(/\\/g, '\\\\')
- .replace(/'/g, "''")
- .replace(/\n/g, '\\n')
- .replace(/\r/g, '\\r');
- }
- const regRe = /reg\(\s*"([^"]+)"\s*,\s*"([^"]+)"\s*,\s*"([^"]+)"\s*,\s*([\s\S]*?)\s*,\s*(null|"[^"]*"|LobsterPromptGuardrails\.\w+)\s*,\s*(null|"[^"]*")\s*,\s*(null|"[^"]*")\s*,\s*(?:\+\+o|\d+)\s*\)\s*;/g;
- const rows = [];
- let m;
- while ((m = regRe.exec(src)) !== null) {
- const [, key, name, category, contentExpr, systemRoleExpr, modelExpr] = m;
- const content = evalConcat(contentExpr);
- let systemRole = null;
- if (systemRoleExpr.startsWith('LobsterPromptGuardrails.')) {
- const gName = systemRoleExpr.replace('LobsterPromptGuardrails.', '');
- systemRole = GUARDRAILS[gName] || null;
- } else if (systemRoleExpr !== 'null') {
- systemRole = unescapeJavaString(systemRoleExpr.slice(1, -1));
- }
- const modelName = modelExpr === 'null' ? null : unescapeJavaString(modelExpr.slice(1, -1));
- rows.push({ key, name, category, content, systemRole, modelName, sort: rows.length + 1 });
- }
- if (rows.length === 0) {
- console.error('No prompts parsed from catalog');
- process.exit(1);
- }
- const lines = [];
- lines.push('-- 数字员工级提示词初始化(平台默认,company_id=NULL)');
- lines.push('-- 生成自 LobsterEnginePromptCatalog,共 ' + rows.length + ' 条');
- lines.push('-- 执行: mysql -u用户 -p 数据库名 < lobster_engine_prompt_init.sql');
- lines.push('-- 已存在相同 prompt_key 时跳过(不覆盖已编辑内容)');
- lines.push('');
- for (const r of rows) {
- const sys = r.systemRole != null ? `'${sqlEscape(r.systemRole)}'` : 'NULL';
- const model = r.modelName != null ? `'${sqlEscape(r.modelName)}'` : 'NULL';
- lines.push(`INSERT IGNORE INTO lobster_system_prompt (`);
- lines.push(` prompt_key, prompt_name, prompt_category, prompt_content,`);
- lines.push(` model_name, system_role, company_id, industry_type, enabled, sort_order, create_by`);
- lines.push(`) VALUES (`);
- lines.push(` '${sqlEscape(r.key)}',`);
- lines.push(` '${sqlEscape(r.name)}',`);
- lines.push(` '${sqlEscape(r.category)}',`);
- lines.push(" '" + sqlEscape(r.content) + "',");
- lines.push(` ${model},`);
- lines.push(` ${sys},`);
- lines.push(` NULL, NULL, 1, ${r.sort}, 'system'`);
- lines.push(`);`);
- lines.push('');
- }
- fs.writeFileSync(outPath, lines.join('\n'), 'utf8');
- console.log('Wrote ' + rows.length + ' prompts -> ' + outPath);
|