package com.smtaiserver.smtaiserver.core;
|
|
import java.io.File;
|
import java.net.URLEncoder;
|
import java.sql.Connection;
|
import java.sql.DriverManager;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.HashSet;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.Map.Entry;
|
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
import org.duckdb.DuckDBAppender;
|
import org.duckdb.DuckDBConnection;
|
import org.springframework.web.context.request.NativeWebRequest;
|
|
|
import com.smtservlet.core.SMTRequest;
|
import com.smtservlet.exception.SMTAuthorityException;
|
import com.smtservlet.util.Json;
|
import com.smtservlet.util.SMTJsonWriter;
|
import com.smtservlet.util.SMTStatic;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecords;
|
import com.smtaiserver.smtaiserver.javaai.qwen.SMTQwenApp;
|
import com.smtservlet.core.SMTApp.SMTRequestConfig;
|
|
public class SMTAIServerRequest extends SMTRequest
|
{
|
public static class AIAttachFile
|
{
|
public String _fileId;
|
public String _fileName;
|
public String _fileText;
|
|
public AIAttachFile(String fileId, String fileName, String fileText)
|
{
|
_fileId = fileId;
|
_fileName = fileName;
|
_fileText = fileText;
|
}
|
|
public String toAttachMessage()
|
{
|
return "附加文件 : " + _fileName + "\n" + _fileText + "\n";
|
}
|
|
public void addToJson(SMTJsonWriter jsonWr)
|
{
|
jsonWr.addKeyValue("file_id", _fileId);
|
jsonWr.addKeyValue("file_name", _fileName);
|
jsonWr.addKeyValue("file_content", _fileText);
|
}
|
}
|
|
private static Logger _logger = LogManager.getLogger(SMTAIServerRequest.class);
|
private static Set<String> _setPublicUrl;
|
private static List<String> _listPublicUrl;
|
|
|
static {
|
_listPublicUrl = new ArrayList<>();
|
_listPublicUrl.add("swagger-resources");
|
_listPublicUrl.add("v2/api-docs");
|
_listPublicUrl.add("swagger-json");
|
|
_setPublicUrl = new HashSet<String>();
|
|
}
|
|
private String _curGroupType = null;
|
private boolean _isChunked = false;
|
private String _chatHistoryId;
|
private String _aiQuestion;
|
private String _rawQuestion;
|
private String _asyncProcessId;
|
private StringBuilder _sbTraceQuestion;
|
private SMTJsonWriter _jsonWrParamJson;
|
private SMTJsonWriter _jsonWrExtCallJson;
|
private SMTJsonWriter _jsonWrAsyncQueryJson;
|
private List<Json> _listSupervisorJson;
|
private Map<String, Json> _mapId2CallFuncJson;
|
private boolean _isAgentCheckMode = false;
|
private List<Json> _listChatExecProcess = null;
|
private String[] _chatOrderDimName = null;
|
private List<String> _contentSampleQuestion = null;
|
private double[] _curQuestionPos;
|
private SMTDatabase _dbDuckResult = null;
|
private SMTJsonWriter _jsonWrResult = null;
|
private List<SMTJsonWriter> _listJsonWrResult = null;
|
private boolean _disableConclusion = false;
|
private List<AIAttachFile> _listAttchFile = null;
|
private Json _jsonAttachTables = null;
|
private Json _jsonAttachMetrics = null;
|
private long _lastSendChunkedStreamBlockTick = 0;
|
private boolean _sendStarStream = false; // 将输出文字变成*
|
|
|
@Override
|
public void initInstance(NativeWebRequest webRequest, String requestCode, SMTRequestConfig requestConfig) throws Exception
|
{
|
super.initInstance(webRequest, requestCode, requestConfig);
|
|
boolean isPublicUrl = false;
|
for(String url : _listPublicUrl)
|
{
|
if(requestCode.startsWith(url))
|
{
|
isPublicUrl = true;
|
break;
|
}
|
}
|
|
if(!isPublicUrl && !_setPublicUrl.contains(requestCode) &&
|
!requestConfig._jsonConfig.safeGetBoolean("no_shrio", false))
|
{
|
if(this.getLoginUserId() == null)
|
throw new SMTAuthorityException("无权限");
|
}
|
}
|
|
public boolean setSendStarStream(boolean isSetStartStream)
|
{
|
boolean org = _sendStarStream;
|
if("true".equals(System.getProperty("show_ai_stream")))
|
isSetStartStream = false;
|
_sendStarStream = isSetStartStream;
|
return org;
|
}
|
|
public void setAttachTables(Json jsonTables)
|
{
|
_jsonAttachTables = jsonTables;
|
}
|
|
public void setJsonAttachMetrics(Json attachMetrics)
|
{
|
_jsonAttachMetrics = attachMetrics;
|
}
|
public String[] getAttachMessage()
|
{
|
List<String> list = new ArrayList<>();
|
|
if(_listAttchFile != null)
|
{
|
for(AIAttachFile file : _listAttchFile)
|
{
|
list.add(file.toAttachMessage());
|
}
|
}
|
|
if(_jsonAttachTables != null)
|
{
|
for(Json jsonAttachTable : _jsonAttachTables.asJsonList())
|
{
|
StringBuilder sbText = new StringBuilder();
|
sbText.append("现有表格:" + jsonAttachTable.getJson("title").asString() + "\n");
|
List<Json> jsonColumns = jsonAttachTable.getJson("columns").asJsonList();
|
for(int i = 0; i < jsonColumns.size(); i ++)
|
{
|
if(i > 0)
|
sbText.append(",");
|
sbText.append(jsonColumns.get(i).asString());
|
}
|
sbText.append("\n");
|
for(Json jsonRecord : jsonAttachTable.getJson("values").asJsonList())
|
{
|
List<Json> listRec = jsonRecord.asJsonList();
|
for(int i = 0; i < listRec.size(); i ++)
|
{
|
if(i > 0)
|
sbText.append(",");
|
if(listRec.get(i).isNull())
|
sbText.append("");
|
else
|
sbText.append(listRec.get(i).asString());
|
}
|
sbText.append("\n");
|
}
|
sbText.append("\n");
|
list.add(sbText.toString());
|
}
|
}
|
|
if(_jsonAttachMetrics != null)
|
{
|
for(Json jsonAttachTable : _jsonAttachMetrics.asJsonList())
|
{
|
StringBuilder sbText = new StringBuilder();
|
sbText.append("现有表格:" + jsonAttachTable.getJson("title").asString() + "\n");
|
List<Json> jsonColumns = jsonAttachTable.getJson("columns").asJsonList();
|
for(int i = 0; i < jsonColumns.size(); i ++)
|
{
|
if(i > 0)
|
sbText.append(",");
|
sbText.append(jsonColumns.get(i).asString());
|
}
|
sbText.append("\n");
|
for(Json jsonRecord : jsonAttachTable.getJson("values").asJsonList())
|
{
|
List<Json> listRec = jsonRecord.asJsonList();
|
for(int i = 0; i < listRec.size(); i ++)
|
{
|
if(i > 0)
|
sbText.append(",");
|
if(listRec.get(i).isNull())
|
sbText.append("");
|
else
|
sbText.append(listRec.get(i).asString());
|
}
|
sbText.append("\n");
|
}
|
sbText.append("\n");
|
list.add(sbText.toString());
|
}
|
}
|
|
|
return list.size() == 0 ? null : list.toArray(new String[list.size()]);
|
}
|
|
public void addAttachMessageToJson(Json jsonResult)
|
{
|
if(_listAttchFile != null)
|
{
|
SMTJsonWriter jsonWr = new SMTJsonWriter(true);
|
for(AIAttachFile file : _listAttchFile)
|
{
|
jsonWr.beginMap(null);
|
file.addToJson(jsonWr);
|
jsonWr.endMap();
|
}
|
|
jsonResult.set("attach_files", jsonWr.getRootJson());
|
}
|
|
if(_jsonAttachTables != null)
|
{
|
jsonResult.set("attach_tables", _jsonAttachTables);
|
}
|
if(_jsonAttachMetrics != null)
|
{
|
jsonResult.set("attach_metrics", _jsonAttachMetrics);
|
}
|
}
|
|
public void addAttachFile(AIAttachFile attachFile)
|
{
|
if(_listAttchFile == null)
|
_listAttchFile = new ArrayList<>();
|
|
_listAttchFile.add(attachFile);
|
}
|
|
public void setDisableConclusion(boolean set)
|
{
|
_disableConclusion = set;
|
}
|
|
public boolean isDisableConclusion()
|
{
|
return _disableConclusion;
|
}
|
|
public SMTJsonWriter finishResultJsonWr()
|
{
|
SMTJsonWriter jsonWrResult = _jsonWrResult;
|
_jsonWrResult = null;
|
|
if(jsonWrResult == null || jsonWrResult.getRootJson().asJsonMap().size() == 0)
|
{
|
_listChatExecProcess = null;
|
_mapId2CallFuncJson = null;
|
return null;
|
}
|
|
if(_listJsonWrResult == null)
|
_listJsonWrResult = new ArrayList<>();
|
|
// "exec_process"输出,并清空
|
if(_listChatExecProcess != null)
|
{
|
Object[] array = new Object[_listChatExecProcess.size()];
|
for(int i = 0; i < _listChatExecProcess.size(); i ++)
|
{
|
array[i] = _listChatExecProcess.get(i);
|
}
|
|
jsonWrResult.addKeyRaw("exec_process", Json.array(array));
|
_listChatExecProcess = null;
|
}
|
|
// call_func不在此处
|
if(_mapId2CallFuncJson != null)
|
{
|
jsonWrResult.beginMap("call_func");
|
for(Entry<String, Json> entry : _mapId2CallFuncJson.entrySet())
|
{
|
jsonWrResult.addKeyRaw(entry.getKey(), entry.getValue());
|
}
|
jsonWrResult.endMap();
|
|
_mapId2CallFuncJson = null;
|
}
|
|
_listJsonWrResult.add(jsonWrResult);
|
|
return jsonWrResult;
|
}
|
|
public List<SMTJsonWriter> getResultJsonWrList()
|
{
|
return _listJsonWrResult;
|
}
|
|
public SMTJsonWriter getResultJsonWr()
|
{
|
if(_jsonWrResult == null)
|
_jsonWrResult = new SMTJsonWriter(false);
|
|
return _jsonWrResult;
|
}
|
|
public void clearChatStreamReplyValue() throws Exception
|
{
|
SMTAIServerApp.getApp().clearChatStreamReply(this.getSessionId());
|
}
|
|
public void setChatStreamReplyValue(String replyId, Json jsonReply) throws Exception
|
{
|
SMTAIServerApp.getApp().setChatStreamReply(this.getSessionId(), replyId, jsonReply);
|
}
|
|
public Json getChatStreamReplyValue(String replyId) throws Exception
|
{
|
Json jsonReply = SMTAIServerApp.getApp().getChatStreamReply(this.getSessionId(), replyId);
|
return jsonReply;
|
}
|
|
public void timeBucketTable(String tableName, String timeField, String aggSQL, String aggField, int stepUnit, int stepValue) throws Exception
|
{
|
SMTDatabase dbResult = this.getResultDB();
|
|
String oldTableName = "d_" + SMTStatic.newUUID();
|
String newTableName = tableName;
|
dbResult.executeSQL("ALTER TABLE " + tableName + " RENAME TO " + oldTableName, null);
|
|
String sql =
|
" SELECT _BUCKET_OTIME_ AS " + timeField + ", " + aggField + " FROM ("
|
+ " SELECT time_bucket(INTERVAL '" + SMTStatic.toString(stepValue) + " " + (stepUnit == 0 ? "minute" : "month") + "'," + timeField + ") AS _BUCKET_OTIME_, "
|
+ aggSQL + " AS " + aggField
|
+ " FROM " + oldTableName
|
+ " GROUP BY _BUCKET_OTIME_"
|
+ " ) T"
|
+ " ORDER BY OTIME"
|
;
|
|
DuckDBAppender[] appender = new DuckDBAppender[1];
|
try
|
{
|
_logger.info("timeBucketTable SQL:\n" + sql);
|
dbResult.querySQLNotify(sql, null, new SMTDatabase.DBQueryNotifyMeta()
|
{
|
@Override
|
public boolean onMetaInfo(DBRecords metaInfo, String[] colTypes) throws Exception
|
{
|
SMTDatabase dbResult = createResultTable(newTableName, metaInfo, colTypes);
|
appender[0] = ((DuckDBConnection)dbResult.getConnection()).createAppender(DuckDBConnection.DEFAULT_SCHEMA, newTableName);
|
|
return true;
|
}
|
|
@Override
|
public boolean onNextRecord(DBRecord rec) throws Exception
|
{
|
Object[] values = rec.getValues();
|
appender[0].beginRow();
|
for(Object value : values)
|
{
|
if(value == null)
|
appender[0].append(null);
|
else
|
appender[0].append(SMTStatic.toString(value));
|
}
|
appender[0].endRow();
|
return true;
|
}
|
});
|
}
|
finally
|
{
|
if(appender[0] != null)
|
{
|
appender[0].close();
|
appender[0] = null;
|
}
|
}
|
dbResult.executeSQL("DROP TABLE " + oldTableName, null);
|
}
|
|
public SMTDatabase createResultTable(String tableName, DBRecords metaInfo, String[] sColTypes) throws Exception
|
{
|
// 生成创建结果表的SQL,并创建结果表
|
StringBuilder sbFields = new StringBuilder();
|
for(Entry<String, Integer> entry : metaInfo.getFieldMap().entrySet())
|
{
|
if(sbFields.length() > 0)
|
sbFields.append(",");
|
sbFields.append(entry.getKey() + " " + sColTypes[entry.getValue()]);
|
}
|
|
SMTDatabase dbResult = this.getResultDB();
|
dbResult.executeSQL("CREATE TABLE " + tableName + "(" + sbFields.toString() + ")", null);
|
|
return dbResult;
|
}
|
|
public SMTDatabase getResultDB() throws Exception
|
{
|
if(_dbDuckResult == null)
|
{
|
String fileName = System.getProperty("result_duckdb", "");
|
if(!SMTStatic.isNullOrEmpty(fileName))
|
{
|
File file = new File(fileName);
|
file.delete();
|
}
|
Connection conn = DriverManager.getConnection("jdbc:duckdb:" + fileName);
|
_dbDuckResult = new SMTDatabase(conn);
|
}
|
return _dbDuckResult;
|
}
|
|
public void closeQuestionResource() throws Exception
|
{
|
this.clearChatStreamReplyValue();
|
|
if(_dbDuckResult != null)
|
{
|
_dbDuckResult.close();
|
_dbDuckResult = null;
|
}
|
}
|
|
public void setCurQuestionPos(double[] pos) throws Exception
|
{
|
if(pos != null)
|
_curQuestionPos = SMTAIServerApp.getApp().convGisToMapTransform(pos);
|
else
|
_curQuestionPos = null;
|
}
|
|
public double[] getCurQuestionPos()
|
{
|
return _curQuestionPos;
|
}
|
|
public int getContentSampleQuestionCount()
|
{
|
return _contentSampleQuestion == null ? 0 : _contentSampleQuestion.size();
|
}
|
|
public void setCurGroupType(String groupType)
|
{
|
_curGroupType = groupType;
|
}
|
|
public String getCurGroupType()
|
{
|
return _curGroupType;
|
}
|
|
|
public void setAgentGroupSet(Set<String> setAgentGroup) throws Exception
|
{
|
setSessionAttribute("login_agent_group", setAgentGroup);
|
}
|
|
@SuppressWarnings("unchecked")
|
public Set<String> getAgentGroupSet() throws Exception
|
{
|
Set<String> setResult = (Set<String>) this.getSessionAttribute("login_agent_group");
|
if(setResult == null)
|
return new HashSet<>();
|
|
return setResult;
|
}
|
|
public void addContentSampleQuestion(String question)
|
{
|
if(_contentSampleQuestion == null)
|
_contentSampleQuestion = new ArrayList<>();
|
|
_contentSampleQuestion.add(question);
|
}
|
|
public void limitContentSampleQuestion(int limit)
|
{
|
while(_contentSampleQuestion.size() > limit)
|
_contentSampleQuestion.remove(_contentSampleQuestion.size() - 1);
|
|
}
|
|
public List<String> getContentSampleQuestion()
|
{
|
return _contentSampleQuestion;
|
}
|
|
public void setChatOrderDimName(String dimName, String orderDir)
|
{
|
_chatOrderDimName = new String[] {dimName.toLowerCase(), orderDir.toUpperCase()};
|
}
|
|
public String[] getChatOrderDimName()
|
{
|
return _chatOrderDimName;
|
}
|
|
public List<Json> getChatExecProcessList()
|
{
|
return _listChatExecProcess;
|
}
|
|
public void setChunkedMode(boolean set)
|
{
|
_isChunked = set;
|
}
|
|
public Json sendReplyChunkedBlock(String replyId, Json jsonAsk) throws Exception
|
{
|
if(!_isChunked)
|
return null;
|
|
sendChunkedBlock("question", jsonAsk);
|
this.setChatStreamReplyValue(replyId, Json.object());
|
|
while(true)
|
{
|
Json jsonReply = this.getChatStreamReplyValue(replyId);
|
if(jsonReply == null)
|
return null;
|
if(jsonReply.safeGetBoolean("json_reply", false))
|
return jsonReply;
|
|
Thread.sleep(1000);
|
}
|
}
|
|
public void sendChunkedResultBlock() throws Exception
|
{
|
SMTJsonWriter jsonWrResult = finishResultJsonWr();
|
if(jsonWrResult != null)
|
{
|
sendChunkedBlock("result", jsonWrResult.getRootJson());
|
}
|
}
|
|
public void sendChunkedStreamBlock(String stream) throws Exception
|
{
|
if(_sendStarStream)
|
{
|
if((System.currentTimeMillis() - _lastSendChunkedStreamBlockTick) < 2000)
|
return;
|
|
_lastSendChunkedStreamBlockTick = System.currentTimeMillis();
|
|
stream = "#";
|
if(stream.indexOf("\n") >= 0)
|
stream += "\n";
|
}
|
sendChunkedBlock("send_stream", stream);
|
}
|
|
public void sendChunkedBlock(String mode, Object value) throws Exception
|
{
|
Json jsonResult;
|
|
if(value == null)
|
{
|
jsonResult = Json.object("mode", mode, "type", "null");
|
}
|
else if(value instanceof String)
|
{
|
jsonResult = Json.object("mode", mode, "type", "string", "value", value);
|
}
|
else if(value instanceof Json)
|
{
|
jsonResult = Json.object("mode", mode, "type", "json", "value", value);
|
}
|
else if(value instanceof SMTJsonWriter)
|
{
|
jsonResult = Json.object("mode", mode, "type", "json", "value", ((SMTJsonWriter)value).getRootJson());
|
}
|
else
|
{
|
throw new Exception("unknow chunked value type : " + value.getClass().toString());
|
}
|
|
if(!"result".equals(mode))
|
{
|
if(_listChatExecProcess == null)
|
_listChatExecProcess = new ArrayList<>();
|
_listChatExecProcess.add(jsonResult);
|
}
|
|
if(!_isChunked)
|
{
|
_logger.info("NO sendChunkedBlock:" + jsonResult.toString());
|
}
|
else
|
{
|
_logger.info("sendChunkedBlock:" + jsonResult.toString());
|
String text = URLEncoder.encode(jsonResult.toString(), "UTF-8").replace("+", "%20") + "\n";
|
|
this.getResponse().getOutputStream().write(text.getBytes("UTF-8"));
|
|
// this.getResponse().getWriter().print(String.format(
|
// "%d\r\n%s\r\n", text.length(), text
|
// ));
|
this.getResponse().flushBuffer();
|
}
|
}
|
|
public String getClientAddr()
|
{
|
return SMTStatic.getClientAddr(this.getRequest());
|
}
|
|
public void appendOperateLog(SMTDatabase db, String type, String note) throws Exception
|
{
|
db.executeSQL("INSERT INTO sys_operate_log(op_id, op_type, op_time, op_user, op_note, client_ip)VALUES(?,?,?,?,?,?)", new Object[] {
|
SMTStatic.newUUID(),
|
type,
|
new Date(),
|
this.getLoginUserId(),
|
note,
|
getClientAddr()
|
});
|
}
|
|
public boolean isAgentCheckMode()
|
{
|
return _isAgentCheckMode;
|
}
|
|
public void setAgentCheckMode(boolean set)
|
{
|
_isAgentCheckMode = set;
|
}
|
|
public void appendCallFuncJson(String key, Json jsonCallFunc)
|
{
|
if(_mapId2CallFuncJson == null)
|
_mapId2CallFuncJson = new LinkedHashMap<>();
|
_mapId2CallFuncJson.put(key, jsonCallFunc);
|
}
|
|
public void appendSupervisorJson(List<Json> jsonSupervisorList)
|
{
|
_listSupervisorJson = jsonSupervisorList;
|
}
|
|
public List<Json> getSupervisorJsonList()
|
{
|
return _listSupervisorJson;
|
}
|
|
public Map<String, Json> getCallFuncJsonMap()
|
{
|
return _mapId2CallFuncJson;
|
}
|
|
public String getChatHistoryId()
|
{
|
if(_chatHistoryId == null)
|
_chatHistoryId = SMTStatic.newUUID();
|
return _chatHistoryId;
|
}
|
|
public SMTJsonWriter prepareAsyncQueryJson()
|
{
|
if(_jsonWrAsyncQueryJson == null)
|
_jsonWrAsyncQueryJson = new SMTJsonWriter(false);
|
|
return _jsonWrAsyncQueryJson;
|
}
|
|
public SMTJsonWriter getAsyncQueryJson()
|
{
|
if(_jsonWrAsyncQueryJson == null)
|
return null;
|
return _jsonWrAsyncQueryJson;
|
}
|
|
public SMTJsonWriter prepareExtCallJsonWriter()
|
{
|
if(_jsonWrExtCallJson == null)
|
_jsonWrExtCallJson = new SMTJsonWriter(true);
|
|
return _jsonWrExtCallJson;
|
}
|
|
public Json getExtCallJsonWriter()
|
{
|
if(_jsonWrExtCallJson == null)
|
return null;
|
Json json = _jsonWrExtCallJson.getRootJson();
|
if(json.asJsonList().size() == 0)
|
return null;
|
|
return json;
|
}
|
|
public SMTJsonWriter prepareParamJsonWriter()
|
{
|
if(_jsonWrParamJson == null)
|
_jsonWrParamJson = new SMTJsonWriter(false);
|
|
return _jsonWrParamJson;
|
}
|
|
public Json getParamJson()
|
{
|
if(_jsonWrParamJson == null)
|
return null;
|
|
Json json = _jsonWrParamJson.getRootJson();
|
if(json.asJsonMap().size() == 0)
|
return null;
|
|
return json;
|
}
|
|
public void setRawQuestion(String rawQuestion)
|
{
|
_rawQuestion = rawQuestion;
|
}
|
|
public void setAIQuestion(String aiQuestion)
|
{
|
_aiQuestion = aiQuestion;
|
}
|
|
public String getAIQuestion()
|
{
|
return _aiQuestion;
|
}
|
|
public String getRawQuestion()
|
{
|
return _rawQuestion;
|
}
|
|
|
public void clearSession() throws Exception
|
{
|
this.getSession().removeAttribute(_requestUserIdKey);
|
}
|
|
public void setAsynProcessId(String processId)
|
{
|
_asyncProcessId = processId;
|
}
|
|
public void removeAsynProcessId() throws Exception
|
{
|
if(_asyncProcessId == null)
|
return;
|
SMTAIServerApp.getApp().removeAsyncProcessText(this.getSessionId(), _asyncProcessId);
|
}
|
|
public void setAsynProcessText(String text) throws Exception
|
{
|
if(_asyncProcessId == null)
|
return;
|
|
SMTAIServerApp.getApp().setAsyncProcessText(this.getSessionId(), _asyncProcessId, text);
|
}
|
|
public String getTraceLLMDebug()
|
{
|
if(_sbTraceQuestion == null)
|
return null;
|
|
return _sbTraceQuestion.toString();
|
}
|
|
public void traceLLMDebug(String trace)
|
{
|
if(_sbTraceQuestion == null)
|
_sbTraceQuestion = new StringBuilder();
|
_sbTraceQuestion.append(SMTStatic.toString(new Date()) + " - " + trace + "\n");
|
|
if(SMTQwenApp.getApp().isTraceLLM())
|
_logger.info(trace);
|
}
|
|
public void traceLLMPrompt(String trace)
|
{
|
_logger.info("大模型提示词:\n[=======================\n" + trace + "\n=======================]\n");
|
}
|
}
|