diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ContextWorkspace.kt b/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ContextWorkspace.kt index 1e559e7f..00c12f13 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ContextWorkspace.kt +++ b/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ContextWorkspace.kt @@ -24,9 +24,9 @@ class ContextWorkspace { * 根据传入的 [ContextBlock.VisibleDomain] 列表,获取上下文块 * @param domains 需要获取上下文的域列表,顺序将决定权重优先级,按照列表排序将具备线性权重分层,最终反映到 blockContent 列表的排序上 */ - fun resolve(domains: List): List = lock.write { + fun resolve(domains: List): 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 { it.domainWeight } .thenBy { it.block.sourceKey.blockName } @@ -73,6 +73,7 @@ class ContextWorkspace { resolved.block.render() } } + ResolvedContext(blocks) } diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ResolvedContext.kt b/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ResolvedContext.kt new file mode 100644 index 00000000..5d7510dc --- /dev/null +++ b/Partner-Core/src/main/java/work/slhaf/partner/core/cognition/ResolvedContext.kt @@ -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 +) { + + fun encodeToContextMessage(): Message { + val content = if (blocks.isEmpty()) { + "" + } else { + buildContextXml(blocks) + } + return Message(Message.Character.USER, content) + } + + private fun buildContextXml(blocks: List): 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() + } + } +} diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java index fdb71c68..13cf4a7c 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java @@ -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 buildChatMessages(PartnerRunningFlowContext runningFlowContext) { - List communicationBlocks = cognitionCapability.contextWorkspace() + ResolvedContext resolvedContext = cognitionCapability.contextWorkspace() .resolve(List.of(ContextBlock.VisibleDomain.COMMUNICATION)); + List communicationBlocks = resolvedContext.getBlocks(); List historyMessages = snapshotConversationMessages(); List 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 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 communicationBlocks) { return new Message(Message.Character.USER, buildInputXml(runningFlowContext, communicationBlocks)); } - private String buildContextXml(List 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 communicationBlocks) { try { Document document = newDocument();