package com.smtaiserver.smtaiserver.javaai.qwen.agent; import java.util.LinkedHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dom4j.Document; import org.mozilla.javascript.Context; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeObject; import com.smtaiserver.smtaiserver.core.SMTAIServerApp; import com.smtaiserver.smtaiserver.core.SMTAIServerRequest; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord; import com.smtaiserver.smtaiserver.javaai.SMTJavaAIError; import com.smtaiserver.smtaiserver.javaai.ast.ASTDBMap; import com.smtaiserver.smtaiserver.javaai.llm.core.SMTLLMConnect; import com.smtaiserver.smtaiserver.javaai.qwen.agent.SMTQwenAgentJavascriptDevQuota.ColumnDefine; import com.smtaiserver.smtaiserver.javaai.qwen.agent.script.SMTQwenAgentScriptJet; import com.smtaiserver.smtaiserver.javaai.qwen.agent.script.SMTQwenAgentScriptScopeMCP; import com.smtservlet.util.Json; import com.smtservlet.util.SMTStatic; public abstract class SMTQwenAgentJavascript extends SMTQwenAgent { private static Logger _logger = LogManager.getLogger(SMTQwenAgentJavascript.class); protected String _prompt; protected abstract void initInstanceDoc(Document doc) throws Exception; protected abstract SMTQwenAgentScriptScopeMCP getMCPInterface(); @Override public void initInstance(DBRecord rec) throws Exception { super.initInstance(rec); try { Document doc = SMTStatic.convStrToXmlDoc("" + rec.getString("clz_arguments") + ""); initInstanceDoc(doc); } catch(Exception ex) { throw new Exception("init mertic agent error : " + this._agentId, ex); } } @Override public SMTJavaAIError callAgents(String jsonPath, Json jsonArgs, SMTLLMConnect llm, String question, SMTAIServerRequest tranReq) throws Exception { int maxCount = 3; // 失败最多尝试3次 for(int j = 1; j <= maxCount; j ++) { // 分析生成js代码 String jsCode = llm.callWithMessage(new String[] {_prompt}, question, tranReq).replace("\r", ""); tranReq.traceLLMDebug(jsCode); jsCode = SMTStatic.convLLMAnswerToJavascript(jsCode); jsCode = "function ffffff(){" + jsCode + "};ffffff();"; //String jsCode = "var arr = testRS(); var l = arr[0]; for(var i in arr){}"; try(ASTDBMap dbMap = new ASTDBMap()) { // 执行脚本 SMTQwenAgentScriptJet scriptJet = new SMTQwenAgentScriptJet(jsonArgs, dbMap, getMCPInterface(), tranReq); try { Context cx = scriptJet.entryContext(); try { scriptJet.executeScript(cx, jsCode); break; } finally { Context.exit(); } } catch(Exception ex) { StringBuilder sbCode = new StringBuilder(); String[] lines = jsCode.replace("\r", "").split("\n"); for(int i = 0; i < lines.length; i ++) { sbCode.append(String.format("%04d %s", i + 1, lines[i]) + "\n"); _logger.fatal(String.format("%04d %s", i + 1, lines[i])); } tranReq.sendChunkedBlock("begin", "解析失败(" + ex.getMessage() + "),重新解析"); if(j < maxCount) _logger.fatal("execute js agent error : " + this.getAgentId() + "\n" + sbCode, ex); else throw new Exception("execute js agent error : " + this.getAgentId() + "\n" + sbCode + "\n" + SMTStatic.toString(ex)); } } } return null; } protected String parseQueryRecordColumDef(NativeArray arrColumns, LinkedHashMap[] arrColumneDefine) { // 加入字段 StringBuilder sbColumn = new StringBuilder(); for(int i = 0; i < arrColumns.size(); i ++) { String colName = SMTStatic.toString(SMTAIServerApp.unwrapObject(arrColumns.get(i))); boolean isExist = false; for(LinkedHashMap mapName2ColumnDefine : arrColumneDefine) { if(mapName2ColumnDefine.containsKey(colName)) { isExist = true; break; } } if(!isExist) continue; if(sbColumn.length() > 0) sbColumn.append(","); sbColumn.append(colName); } return sbColumn.toString(); } protected String parseQueryRecordLimit(NativeObject nvLimit) throws Exception { // 加入limit StringBuilder sbLimit = new StringBuilder(); if(nvLimit != null) { SMTAIServerApp.getApp(); Object oLimit = SMTAIServerApp.getJSValue(nvLimit, "limit", null); if(oLimit != null) { int limit = SMTStatic.toInt(oLimit); sbLimit.append("LIMIT " + limit); Object oStart = SMTAIServerApp.getJSValue(nvLimit, "start", null); if(oStart != null) sbLimit.append(" OFFSET " + SMTStatic.toInt(oStart)); } } return sbLimit.toString(); } protected String parseQueryRecordOrder(NativeArray arrOrderColumns, LinkedHashMap[] arrColumneDefine) throws Exception { StringBuilder sbOrder = new StringBuilder(); if(arrOrderColumns != null) { for(int i = 0; i < arrOrderColumns.size(); i ++) { NativeObject nvOrderColumn = (NativeObject) SMTAIServerApp.unwrapObject(arrOrderColumns.get(i)); String colName = (String) SMTAIServerApp.getJSValue(nvOrderColumn, "col"); String orderDir= (String) SMTAIServerApp.getJSValue(nvOrderColumn, "order"); boolean isExist = false; for(LinkedHashMap mapName2ColumnDefine : arrColumneDefine) { if(mapName2ColumnDefine.containsKey(colName)) { isExist = true; break; } } if(!isExist) continue; if(sbOrder.length() > 0) sbOrder.append(","); sbOrder.append(colName + " " + orderDir); } } return sbOrder.toString(); } protected String parseQueryRecordFilterDef(NativeArray arrFilters, LinkedHashMap[] arrColumneDefine) throws Exception { // 加入过滤条件 StringBuilder sbWhere = new StringBuilder(); if(arrFilters != null && arrFilters.size() > 0) { for(int i = 0; i < arrFilters.size(); i ++) { NativeObject nvFilter = (NativeObject) SMTAIServerApp.unwrapObject(arrFilters.get(i)); String colName = (String)SMTAIServerApp.getJSValue(nvFilter, "col"); String filterOP = (String)SMTAIServerApp.getJSValue(nvFilter, "op"); ColumnDefine colDefine = null; for(LinkedHashMap mapName2Columns : arrColumneDefine) { colDefine = mapName2Columns.get(colName); if(colDefine != null) break; } if(colDefine == null) continue; if(sbWhere.length() > 0) sbWhere.append(" AND "); if("=".equals(filterOP)) { String value = SMTStatic.toString(SMTAIServerApp.getJSValue(nvFilter, "value")); if("=".equals(colDefine._colFilter)) { sbWhere.append(colName + "='" + value.replace("'", "''") + "'"); } else if("like".equals(colDefine._colFilter)) { sbWhere.append(colName + " like '%" + value.replace("'", "''") + "%'"); } else { throw new Exception("unknow column filter : " + colDefine._colFilter); } } else if("BETWEEN".equalsIgnoreCase(filterOP)) { sbWhere.append(colName + " BETWEEN "); NativeArray arrValues = (NativeArray)SMTAIServerApp.getJSValue(nvFilter, "value"); sbWhere.append("'" + SMTStatic.toString(SMTAIServerApp.unwrapObject(arrValues.get(0))).replace("'", "''") + "'"); sbWhere.append(" AND "); sbWhere.append("'" + SMTStatic.toString(SMTAIServerApp.unwrapObject(arrValues.get(1))).replace("'", "''") + "'"); } else if("IN".equalsIgnoreCase(filterOP)) { NativeArray arrValues = (NativeArray)SMTAIServerApp.getJSValue(nvFilter, "value"); if("=".equals(filterOP)) { sbWhere.append(colName + " IN ("); for(int ii = 0; ii < arrValues.size(); ii ++) { if(ii > 0) sbWhere.append(","); sbWhere.append("'" + SMTStatic.toString(SMTAIServerApp.unwrapObject(arrValues.get(ii))).replace("'", "''") + "'"); } sbWhere.append(")"); } else if("like".equals(colDefine._colFilter)) { sbWhere.append("("); for(int ii = 0; ii < arrValues.size(); ii ++) { if(ii > 0) sbWhere.append(" OR "); sbWhere.append(colName + " LIKE '%"); sbWhere.append(SMTStatic.toString(SMTAIServerApp.unwrapObject(arrValues.get(ii))).replace("'", "''")); sbWhere.append("%'"); } sbWhere.append(")"); } } else { String value = SMTStatic.toString(SMTAIServerApp.getJSValue(nvFilter, "value")); sbWhere.append(colName + " " + filterOP + " '" + value.replace("'", "''") + "'"); } } } return sbWhere.toString(); } }