mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
推进行动干预模块
- 完善了 ActionInterventor 中的具体逻辑以及不同情况下的prompt填充内容; - 调整了 PreRunningModule 中的 getPromptDataMap 方法; - 在 ActionCapability 中新增了检查 actionKey 是否存在的逻辑
This commit is contained in:
@@ -4,6 +4,7 @@ import lombok.NonNull;
|
|||||||
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
|
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
|
||||||
import work.slhaf.partner.core.action.entity.ActionData;
|
import work.slhaf.partner.core.action.entity.ActionData;
|
||||||
import work.slhaf.partner.core.action.entity.MetaAction;
|
import work.slhaf.partner.core.action.entity.MetaAction;
|
||||||
|
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||||
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
|
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -41,4 +42,7 @@ public interface ActionCapability {
|
|||||||
|
|
||||||
MetaAction loadMetaAction(@NonNull String actionKey);
|
MetaAction loadMetaAction(@NonNull String actionKey);
|
||||||
|
|
||||||
|
MetaActionInfo loadMetaActionInfo(@NonNull String actionKey);
|
||||||
|
|
||||||
|
boolean checkExists(String... actionKeys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,20 @@ public class ActionCore extends PartnerCore<ActionCore> {
|
|||||||
return phaserRecords;
|
return phaserRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CapabilityMethod
|
||||||
|
public MetaActionInfo loadMetaActionInfo(@NonNull String actionKey) {
|
||||||
|
MetaActionInfo info = existedMetaActions.get(actionKey);
|
||||||
|
if (info == null) {
|
||||||
|
throw new MetaActionNotFoundException("未找到对应的行动程序描述信息: " + actionKey);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@CapabilityMethod
|
||||||
|
public boolean checkExists(String... actionKeys) {
|
||||||
|
return existedMetaActions.keySet().containsAll(Arrays.asList(actionKeys));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 命中缓存且评估通过时
|
* 命中缓存且评估通过时
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import work.slhaf.partner.api.common.entity.PersistableObject;
|
import work.slhaf.partner.api.common.entity.PersistableObject;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.util.HashMap;
|
import java.util.Map;
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@@ -15,5 +15,5 @@ public class AppendPromptData extends PersistableObject {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String moduleName;
|
private String moduleName;
|
||||||
private HashMap<String,String> appendedPrompt;
|
private Map<String, String> appendedPrompt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunn
|
|||||||
import work.slhaf.partner.module.common.entity.AppendPromptData;
|
import work.slhaf.partner.module.common.entity.AppendPromptData;
|
||||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前置模块抽象类
|
* 前置模块抽象类
|
||||||
@@ -15,7 +15,7 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
|
|||||||
private synchronized void setAppendedPrompt(PartnerRunningFlowContext context) {
|
private synchronized void setAppendedPrompt(PartnerRunningFlowContext context) {
|
||||||
AppendPromptData data = new AppendPromptData();
|
AppendPromptData data = new AppendPromptData();
|
||||||
data.setModuleName(moduleName());
|
data.setModuleName(moduleName());
|
||||||
HashMap<String, String> map = getPromptDataMap(context);
|
Map<String, String> map = getPromptDataMap(context);
|
||||||
data.setAppendedPrompt(map);
|
data.setAppendedPrompt(map);
|
||||||
context.setAppendedPrompt(data);
|
context.setAppendedPrompt(data);
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
|
|||||||
context.getCoreContext().addActiveModule(moduleName());
|
context.getCoreContext().addActiveModule(moduleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context);
|
protected abstract Map<String, String> getPromptDataMap(PartnerRunningFlowContext context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于在CoreModule接收到的模块Prompt中标识模块名称
|
* 用于在CoreModule接收到的模块Prompt中标识模块名称
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package work.slhaf.partner.module.modules.action.identifier;
|
package work.slhaf.partner.module.modules.action.identifier;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||||
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
|
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
|
||||||
@@ -21,10 +22,8 @@ import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.Rec
|
|||||||
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerResult;
|
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerResult;
|
||||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +37,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
|
|||||||
@InjectModule
|
@InjectModule
|
||||||
private InterventionEvaluator interventionEvaluator;
|
private InterventionEvaluator interventionEvaluator;
|
||||||
@InjectModule
|
@InjectModule
|
||||||
private InterventionHandler InterventionHandler;
|
private InterventionHandler interventionHandler;
|
||||||
|
|
||||||
@InjectCapability
|
@InjectCapability
|
||||||
private ActionCapability actionCapability;
|
private ActionCapability actionCapability;
|
||||||
@@ -51,7 +50,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
|
|||||||
* 键: 本次调用uuid;
|
* 键: 本次调用uuid;
|
||||||
* 值:本次调用对应的prompt;
|
* 值:本次调用对应的prompt;
|
||||||
*/
|
*/
|
||||||
private Map<String, HashMap<String, String>> interventionPrompt = new HashMap<>();
|
private final Map<String, Map<String, String>> interventionPrompt = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doExecute(PartnerRunningFlowContext context) {
|
protected void doExecute(PartnerRunningFlowContext context) {
|
||||||
@@ -72,20 +71,39 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
|
|||||||
EvaluatorResult evaluatorResult = interventionEvaluator
|
EvaluatorResult evaluatorResult = interventionEvaluator
|
||||||
.execute(buildEvaluatorInput(recognizedInterventions.keySet(), userId));
|
.execute(buildEvaluatorInput(recognizedInterventions.keySet(), userId));
|
||||||
List<EvaluatedInterventionData> interventions = evaluatorResult.getDataList();
|
List<EvaluatedInterventionData> interventions = evaluatorResult.getDataList();
|
||||||
if (evaluatorResult.isOk()) {
|
if (evaluatorResult.isOk() && isActionKeysExist(interventions)) {
|
||||||
|
setupErrorInterventionPrompt(uuid);
|
||||||
|
} else if (evaluatorResult.isOk()) {
|
||||||
// 同步写入prompt,异步处理干预行为
|
// 同步写入prompt,异步处理干预行为
|
||||||
setupInterventionPrompt(uuid, interventions);
|
setupInterventionPrompt(uuid, interventions);
|
||||||
InterventionHandler.execute(buildHandlerInput(interventions));
|
interventionHandler.execute(buildHandlerInput(interventions));
|
||||||
} else {
|
} else {
|
||||||
// 同步写入prompt
|
// 同步写入prompt
|
||||||
setupInterventionIgnoredPrompt(uuid, interventions);
|
setupInterventionIgnoredPrompt(uuid, interventions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupErrorInterventionPrompt(String uuid) {
|
||||||
|
interventionPrompt.put(uuid, Map.of(
|
||||||
|
"[识别状态] <是否识别到干预已存在行动的意图>", "识别出,但出现了不存在的行动单元key",
|
||||||
|
"[干预行动] <将对已存在行动做出的行为>", "无行为"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isActionKeysExist(List<EvaluatedInterventionData> interventions) {
|
||||||
|
for (EvaluatedInterventionData intervention : interventions) {
|
||||||
|
String[] array = intervention.getActions().values().toArray(new String[0]);
|
||||||
|
if (!actionCapability.checkExists(array)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private HandlerInput buildHandlerInput(List<EvaluatedInterventionData> interventions) {
|
private HandlerInput buildHandlerInput(List<EvaluatedInterventionData> interventions) {
|
||||||
HandlerInput input = new HandlerInput();
|
HandlerInput input = new HandlerInput();
|
||||||
List<HandlerInputData> inputDataList = input.getData();
|
List<HandlerInputData> inputDataList = input.getData();
|
||||||
for(EvaluatedInterventionData interventionData: interventions){
|
for (EvaluatedInterventionData interventionData : interventions) {
|
||||||
HandlerInputData inputData = new HandlerInputData();
|
HandlerInputData inputData = new HandlerInputData();
|
||||||
inputData.setTendency(interventionData.getTendency());
|
inputData.setTendency(interventionData.getTendency());
|
||||||
inputData.setDescription(interventionData.getDescription());
|
inputData.setDescription(interventionData.getDescription());
|
||||||
@@ -97,15 +115,55 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupInterventionIgnoredPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
|
private void setupInterventionIgnoredPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
|
||||||
|
String s = dataList.stream()
|
||||||
|
.map(data -> JSONObject.of(
|
||||||
|
"[干预倾向]", data.getTendency(),
|
||||||
|
"[未采用原因]", data.getDescription()).toString())
|
||||||
|
.collect(Collectors.joining(",", "[", "]"));
|
||||||
|
interventionPrompt.put(uuid, Map.of(
|
||||||
|
"[识别状态] <是否识别到干预已存在行动的意图>", "识别到,但都未采用",
|
||||||
|
"[忽略原因] <各个意图被忽略的原因>", s,
|
||||||
|
"[干预行动] <将对已存在行动做出的行为>", "无行为"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupInterventionPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
|
private void setupInterventionPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
|
||||||
|
List<Map<String, String>> contents = new ArrayList<>();
|
||||||
|
List<String> actions = new ArrayList<>();
|
||||||
|
for (EvaluatedInterventionData data : dataList) {
|
||||||
|
if (!data.isOk()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String tendency = data.getTendency();
|
||||||
|
contents.add(Map.of(
|
||||||
|
"[干预倾向]", tendency,
|
||||||
|
"[干预类型]", data.getType().toString(),
|
||||||
|
"[行动链变动情况]", getActionChainStr(data.getActions())
|
||||||
|
));
|
||||||
|
actions.add(tendency);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interventionPrompt.put(uuid, Map.of(
|
||||||
|
"[识别状态] <是否识别到干预已存在行动的意图>", "识别到,将采用",
|
||||||
|
"[具体内容] <各个干预意图对应的具体信息>", contents.toString(),
|
||||||
|
"[干预行动] <将对已存在行动做出的行为>", actions.toString()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getActionChainStr(LinkedHashMap<Integer, String> actions) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
//虽说actionCapability那边做了异常抛出,但说实话很明显放在这里不好处理啊🤔,还是在前边统一检查一下吧
|
||||||
|
actions.forEach((order, actionKey) -> {
|
||||||
|
list.add(order + ":" + actionCapability.loadMetaActionInfo(actionKey).getDescription());
|
||||||
|
});
|
||||||
|
return list.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupNoInterventionPrompt(String uuid) {
|
private void setupNoInterventionPrompt(String uuid) {
|
||||||
|
interventionPrompt.put(uuid, Map.of(
|
||||||
|
"[识别状态] <是否识别到干预已存在行动的意图>", "未识别到干预意图",
|
||||||
|
"[干预行动] <将对已存在行动做出的行为>", "无行动"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private EvaluatorInput buildEvaluatorInput(Set<String> interventionTendencies, String userId) {
|
private EvaluatorInput buildEvaluatorInput(Set<String> interventionTendencies, String userId) {
|
||||||
@@ -137,8 +195,8 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
||||||
return interventionPrompt.get(context.getUuid());
|
return interventionPrompt.remove(context.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public class ActionPlanner extends PreRunningModule {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
String userId = context.getUserId();
|
String userId = context.getUserId();
|
||||||
setupPendingActions(map, userId);
|
setupPendingActions(map, userId);
|
||||||
@@ -170,22 +170,22 @@ public class ActionPlanner extends PreRunningModule {
|
|||||||
private void setupPendingActions(HashMap<String, String> map, String userId) {
|
private void setupPendingActions(HashMap<String, String> map, String userId) {
|
||||||
List<ActionData> actionData = actionCapability.listPendingAction(userId);
|
List<ActionData> actionData = actionCapability.listPendingAction(userId);
|
||||||
if (actionData == null || actionData.isEmpty()) {
|
if (actionData == null || actionData.isEmpty()) {
|
||||||
map.put("[待确认行动] <待确认行动信息>", "无待确认行动");
|
map.put("[待确认行动] <等待用户确认的行动信息>", "无待确认行动");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < actionData.size(); i++) {
|
for (int i = 0; i < actionData.size(); i++) {
|
||||||
map.put("[待确认行动 " + (i + 1) + " ]", generateActionStr(actionData.get(i)));
|
map.put("[待确认行动 " + (i + 1) + " ] <等待用户确认的行动信息>", generateActionStr(actionData.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupPreparedActions(HashMap<String, String> map, String userId) {
|
private void setupPreparedActions(HashMap<String, String> map, String userId) {
|
||||||
List<ActionData> actionData = actionCapability.listPreparedAction(userId);
|
List<ActionData> actionData = actionCapability.listPreparedAction(userId);
|
||||||
if (actionData == null || actionData.isEmpty()) {
|
if (actionData == null || actionData.isEmpty()) {
|
||||||
map.put("[预备行动] <预备行动信息>", "无预备行动");
|
map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < actionData.size(); i++) {
|
for (int i = 0; i < actionData.size(); i++) {
|
||||||
map.put("[预备行动 " + (i + 1) + " ]", generateActionStr(actionData.get(i)));
|
map.put("[预备行动 " + (i + 1) + " ] <预备执行或放入计划池的行动信息>", generateActionStr(actionData.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,7 @@ import work.slhaf.partner.module.modules.memory.selector.extractor.entity.Extrac
|
|||||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@@ -133,7 +130,7 @@ public class MemorySelector extends PreRunningModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
String userId = context.getUserId();
|
String userId = context.getUserId();
|
||||||
String dialogMapStr = memoryCapability.getDialogMapStr();
|
String dialogMapStr = memoryCapability.getDialogMapStr();
|
||||||
@@ -148,7 +145,7 @@ public class MemorySelector extends PreRunningModule {
|
|||||||
|
|
||||||
String sliceStr = memoryCapability.getActivatedSlicesStr(userId);
|
String sliceStr = memoryCapability.getActivatedSlicesStr(userId);
|
||||||
if (sliceStr != null && !sliceStr.isEmpty()) {
|
if (sliceStr != null && !sliceStr.isEmpty()) {
|
||||||
map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来()>", sliceStr);
|
map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来>", sliceStr);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import work.slhaf.partner.module.common.module.PreRunningModule;
|
|||||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Setter
|
@Setter
|
||||||
@@ -24,7 +25,7 @@ public class PerceiveSelector extends PreRunningModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
User user = perceiveCapability.getUser(context.getUserId());
|
User user = perceiveCapability.getUser(context.getUserId());
|
||||||
map.put("[关系] <你与最新聊天用户的关系>", user.getRelation());
|
map.put("[关系] <你与最新聊天用户的关系>", user.getRelation());
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import work.slhaf.partner.runtime.interaction.data.context.subcontext.CoreContex
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@@ -58,7 +59,7 @@ public class PreprocessExecutor extends PreRunningModule {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
map.put("text", "这部分才是真正的用户输入内容, 就像你之前收到过的输入一样。但...不会是'同一个人'。");
|
map.put("text", "这部分才是真正的用户输入内容, 就像你之前收到过的输入一样。但...不会是'同一个人'。");
|
||||||
map.put("datetime", "本次用户输入对应的当前时间");
|
map.put("datetime", "本次用户输入对应的当前时间");
|
||||||
|
|||||||
Reference in New Issue
Block a user