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();
}
}