mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
refactor(context): add ResolvedContext as response of ContextWorkspace#resolve, integrated with Message encoding
This commit is contained in:
@@ -24,9 +24,9 @@ class ContextWorkspace {
|
||||
* 根据传入的 [ContextBlock.VisibleDomain] 列表,获取上下文块
|
||||
* @param domains 需要获取上下文的域列表,顺序将决定权重优先级,按照列表排序将具备线性权重分层,最终反映到 blockContent 列表的排序上
|
||||
*/
|
||||
fun resolve(domains: List<ContextBlock.VisibleDomain>): List<BlockContent> = lock.write {
|
||||
fun resolve(domains: List<ContextBlock.VisibleDomain>): ResolvedContext = lock.write {
|
||||
if (domains.isEmpty()) {
|
||||
return@write emptyList()
|
||||
return@write ResolvedContext(emptyList())
|
||||
}
|
||||
val primaryDomain = domains.first()
|
||||
|
||||
@@ -58,7 +58,7 @@ class ContextWorkspace {
|
||||
)
|
||||
}
|
||||
|
||||
activeBlocks
|
||||
val blocks = activeBlocks
|
||||
.sortedWith(
|
||||
compareBy<ResolvedContextBlock> { it.domainWeight }
|
||||
.thenBy { it.block.sourceKey.blockName }
|
||||
@@ -73,6 +73,7 @@ class ContextWorkspace {
|
||||
resolved.block.render()
|
||||
}
|
||||
}
|
||||
ResolvedContext(blocks)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package work.slhaf.partner.core.cognition
|
||||
|
||||
import org.w3c.dom.Document
|
||||
import work.slhaf.partner.api.chat.pojo.Message
|
||||
import java.io.StringWriter
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.transform.OutputKeys
|
||||
import javax.xml.transform.TransformerFactory
|
||||
import javax.xml.transform.dom.DOMSource
|
||||
import javax.xml.transform.stream.StreamResult
|
||||
|
||||
data class ResolvedContext(
|
||||
val blocks: List<BlockContent>
|
||||
) {
|
||||
|
||||
fun encodeToContextMessage(): Message {
|
||||
val content = if (blocks.isEmpty()) {
|
||||
"<no_context></no_context>"
|
||||
} else {
|
||||
buildContextXml(blocks)
|
||||
}
|
||||
return Message(Message.Character.USER, content)
|
||||
}
|
||||
|
||||
private fun buildContextXml(blocks: List<BlockContent>): String {
|
||||
return try {
|
||||
val document = newDocument()
|
||||
val root = document.createElement("context")
|
||||
document.appendChild(root)
|
||||
|
||||
blocks.stream()
|
||||
.map(BlockContent::encodeToXml)
|
||||
.forEach { blockElement ->
|
||||
root.appendChild(document.importNode(blockElement, true))
|
||||
}
|
||||
|
||||
toXmlString(document)
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException("构建 context 区段失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun newDocument(): Document {
|
||||
return DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder()
|
||||
.newDocument()
|
||||
}
|
||||
|
||||
private fun toXmlString(document: Document): String {
|
||||
val transformer = TransformerFactory.newInstance().newTransformer().apply {
|
||||
setOutputProperty(OutputKeys.INDENT, "yes")
|
||||
setOutputProperty(OutputKeys.ENCODING, "UTF-8")
|
||||
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
|
||||
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
|
||||
}
|
||||
return StringWriter().use { writer ->
|
||||
transformer.transform(DOMSource(document), StreamResult(writer))
|
||||
writer.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
|
||||
import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData;
|
||||
import work.slhaf.partner.core.cognition.CognitionCapability;
|
||||
import work.slhaf.partner.core.memory.MemoryCapability;
|
||||
import work.slhaf.partner.core.perceive.PerceiveCapability;
|
||||
import work.slhaf.partner.module.modules.action.executor.ActionExecutor;
|
||||
import work.slhaf.partner.module.modules.action.planner.confirmer.ActionConfirmer;
|
||||
import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerInput;
|
||||
@@ -54,8 +53,6 @@ public class ActionPlanner extends AbstractAgentModule.Running<PartnerRunningFlo
|
||||
@InjectCapability
|
||||
private ActionCapability actionCapability;
|
||||
@InjectCapability
|
||||
private PerceiveCapability perceiveCapability;
|
||||
@InjectCapability
|
||||
private MemoryCapability memoryCapability;
|
||||
|
||||
@InjectModule
|
||||
|
||||
@@ -11,10 +11,7 @@ import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentMod
|
||||
import work.slhaf.partner.api.agent.factory.component.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.factory.component.annotation.Init;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
import work.slhaf.partner.core.cognition.BlockContent;
|
||||
import work.slhaf.partner.core.cognition.CognitionCapability;
|
||||
import work.slhaf.partner.core.cognition.CommunicationBlockContent;
|
||||
import work.slhaf.partner.core.cognition.ContextBlock;
|
||||
import work.slhaf.partner.core.cognition.*;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -105,14 +102,12 @@ public class CommunicationProducer extends AbstractAgentModule.Running<PartnerRu
|
||||
}
|
||||
|
||||
private List<Message> buildChatMessages(PartnerRunningFlowContext runningFlowContext) {
|
||||
List<BlockContent> communicationBlocks = cognitionCapability.contextWorkspace()
|
||||
ResolvedContext resolvedContext = cognitionCapability.contextWorkspace()
|
||||
.resolve(List.of(ContextBlock.VisibleDomain.COMMUNICATION));
|
||||
List<BlockContent> communicationBlocks = resolvedContext.getBlocks();
|
||||
List<Message> historyMessages = snapshotConversationMessages();
|
||||
List<Message> temp = new ArrayList<>(historyMessages.size() + 2);
|
||||
Message contextMessage = buildContextMessage(communicationBlocks);
|
||||
if (contextMessage != null) {
|
||||
temp.add(contextMessage);
|
||||
}
|
||||
temp.add(buildContextMessage(communicationBlocks));
|
||||
temp.addAll(historyMessages);
|
||||
temp.add(buildInputMessage(runningFlowContext, communicationBlocks));
|
||||
return temp;
|
||||
@@ -145,34 +140,13 @@ public class CommunicationProducer extends AbstractAgentModule.Running<PartnerRu
|
||||
List<BlockContent> contextBlocks = communicationBlocks.stream()
|
||||
.filter(this::belongsToContextSection)
|
||||
.toList();
|
||||
if (contextBlocks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new Message(Message.Character.USER, buildContextXml(contextBlocks));
|
||||
return new ResolvedContext(contextBlocks).encodeToContextMessage();
|
||||
}
|
||||
|
||||
private Message buildInputMessage(PartnerRunningFlowContext runningFlowContext, List<BlockContent> communicationBlocks) {
|
||||
return new Message(Message.Character.USER, buildInputXml(runningFlowContext, communicationBlocks));
|
||||
}
|
||||
|
||||
private String buildContextXml(List<BlockContent> contextBlocks) {
|
||||
try {
|
||||
Document document = newDocument();
|
||||
Element root = document.createElement("context");
|
||||
document.appendChild(root);
|
||||
|
||||
contextBlocks.stream()
|
||||
.map(BlockContent::encodeToXml)
|
||||
.forEach(blockElement -> {
|
||||
root.appendChild(document.importNode(blockElement, true));
|
||||
});
|
||||
|
||||
return toXmlString(document);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("构建 context 区段失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildInputXml(PartnerRunningFlowContext runningFlowContext, List<BlockContent> communicationBlocks) {
|
||||
try {
|
||||
Document document = newDocument();
|
||||
|
||||
Reference in New Issue
Block a user