diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java index f9407007..46939da2 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java @@ -69,7 +69,7 @@ public class ActionPlanner extends AbstractAgentModule.Running result = actionExtractor.execute(input) .onFailure(exp -> { ExceptionReporterHandler.INSTANCE.report(exp, ContextExceptionReporter.REPORTER_NAME); diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/communication/CommunicationProducer.java b/Partner-Core/src/main/java/work/slhaf/partner/module/communication/CommunicationProducer.java index b590ed57..46b94169 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/communication/CommunicationProducer.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/communication/CommunicationProducer.java @@ -129,7 +129,7 @@ public class CommunicationProducer extends AbstractAgentModule.Running entry : runningFlowContext.getAdditionalUserInfo().entrySet()) { appendTextElement(document, root, sanitizeTagName(entry.getKey()), entry.getValue()); diff --git a/Partner-Core/src/main/java/work/slhaf/partner/runtime/PartnerRunningFlowContext.kt b/Partner-Core/src/main/java/work/slhaf/partner/runtime/PartnerRunningFlowContext.kt index 34164537..4f1f1c8f 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/runtime/PartnerRunningFlowContext.kt +++ b/Partner-Core/src/main/java/work/slhaf/partner/runtime/PartnerRunningFlowContext.kt @@ -1,15 +1,15 @@ package work.slhaf.partner.runtime +import org.w3c.dom.Document +import org.w3c.dom.Element +import work.slhaf.partner.common.base.Block import work.slhaf.partner.framework.agent.interaction.flow.RunningFlowContext class PartnerRunningFlowContext private constructor( override val source: String, inputs: List, - firstInputEpochMillis: Long, - additionalUserInfo: Map = emptyMap(), - skippedModules: Set = emptySet(), - target: String = source -) : RunningFlowContext(inputs, firstInputEpochMillis, additionalUserInfo, skippedModules, target) { + firstInputEpochMillis: Long +) : RunningFlowContext(inputs, firstInputEpochMillis) { companion object { @@ -31,6 +31,7 @@ class PartnerRunningFlowContext private constructor( } @JvmStatic + @JvmOverloads fun fromUser(userId: String, input: String, receivedAtMillis: Long = System.currentTimeMillis()) = PartnerRunningFlowContext( SourceTag.buildUserSource(userId), @@ -39,6 +40,7 @@ class PartnerRunningFlowContext private constructor( ) @JvmStatic + @JvmOverloads fun fromSelf(input: String, receivedAtMillis: Long = System.currentTimeMillis()) = PartnerRunningFlowContext( SourceTag.buildAgentSource(), @@ -50,20 +52,21 @@ class PartnerRunningFlowContext private constructor( } } - override fun copyWith( - inputs: List, - firstInputEpochMillis: Long, - additionalUserInfo: Map, - skippedModules: Set, - target: String - ): RunningFlowContext { + override fun recreate(inputs: List): RunningFlowContext { return PartnerRunningFlowContext( source = source, inputs = inputs, - firstInputEpochMillis = firstInputEpochMillis, - additionalUserInfo = additionalUserInfo, - skippedModules = skippedModules, - target = target + firstInputEpochMillis = System.currentTimeMillis() ) } + + fun encodeInputsBlock(): Block = object : Block("inputs") { + override fun fillXml(document: Document, root: Element) { + appendRepeatedElements(document, root, "input", inputs) { + this.setAttribute("interval-to-first", it.offsetMillis.toString()) + this.textContent = it.content + } + } + } + } diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/interaction/flow/RunningFlowContext.kt b/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/interaction/flow/RunningFlowContext.kt index 5e4d5a23..e0330d3f 100644 --- a/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/interaction/flow/RunningFlowContext.kt +++ b/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/interaction/flow/RunningFlowContext.kt @@ -1,8 +1,6 @@ package work.slhaf.partner.framework.agent.interaction.flow import com.alibaba.fastjson2.JSONObject -import org.w3c.dom.Document -import org.w3c.dom.Element import java.time.Instant import java.time.LocalDateTime import java.time.ZoneId @@ -14,10 +12,7 @@ import kotlin.math.min */ abstract class RunningFlowContext protected constructor( inputs: List, - val firstInputEpochMillis: Long, - additionalUserInfo: Map = emptyMap(), - skippedModules: Set = emptySet(), - target: String = "" + private var firstInputEpochMillis: Long ) { /** * 消息来源: 由谁发出 @@ -38,13 +33,18 @@ abstract class RunningFlowContext protected constructor( /** * 消息回应对象,默认与 source 一致 */ - var target: String = target + private var _target: String? = null + var target: String + get() = _target ?: source + set(value) { + _target = value + } - private val _additionalUserInfo = additionalUserInfo.toMutableMap() + private val _additionalUserInfo = mutableMapOf() val additionalUserInfo: Map get() = _additionalUserInfo - private val _skippedModules = skippedModules.toMutableSet() + private val _skippedModules = mutableSetOf() val skippedModules: Set get() = _skippedModules @@ -73,37 +73,6 @@ abstract class RunningFlowContext protected constructor( fun formatInputsForHistory(): String = inputs.joinToString("\n") { it.content } - @JvmOverloads - fun appendInputsXml( - document: Document, - parent: Element, - containerTagName: String = "inputs", - inputTagName: String = "input", - intervalAttributeName: String = "interval-to-first" - ) { - val inputsElement = document.createElement(containerTagName) - parent.appendChild(inputsElement) - inputs.forEach { entry -> - val inputElement = document.createElement(inputTagName) - inputElement.setAttribute(intervalAttributeName, entry.offsetMillis.toString()) - inputElement.textContent = entry.content - inputsElement.appendChild(inputElement) - } - } - - fun encodeInputsXml(): String { - val builder = StringBuilder() - builder.append("") - inputs.forEach { entry -> - builder.append("") - .append(escapeXml(entry.content)) - .append("") - } - builder.append("") - return builder.toString() - } fun mergedWith(other: RunningFlowContext): RunningFlowContext { require(source == other.source) { @@ -115,28 +84,17 @@ abstract class RunningFlowContext protected constructor( addAll(normalizeInputs(other, mergedFirstEpochMillis)) }.sortedBy { it.offsetMillis } - val mergedAdditionalUserInfo = LinkedHashMap(_additionalUserInfo) - mergedAdditionalUserInfo.putAll(other.additionalUserInfo) - - val mergedSkippedModules = LinkedHashSet(_skippedModules) - mergedSkippedModules.addAll(other.skippedModules) - - return copyWith( - inputs = mergedInputs, - firstInputEpochMillis = mergedFirstEpochMillis, - additionalUserInfo = mergedAdditionalUserInfo, - skippedModules = mergedSkippedModules, - target = other.target.ifBlank { target } - ) + val mergedContext = recreate(mergedInputs) + mergedContext.firstInputEpochMillis = mergedFirstEpochMillis + mergedContext.target = other.target.ifBlank { target } + mergedContext._additionalUserInfo.putAll(_additionalUserInfo) + mergedContext._additionalUserInfo.putAll(other.additionalUserInfo) + mergedContext._skippedModules.addAll(_skippedModules) + mergedContext._skippedModules.addAll(other.skippedModules) + return mergedContext } - protected abstract fun copyWith( - inputs: List, - firstInputEpochMillis: Long, - additionalUserInfo: Map, - skippedModules: Set, - target: String - ): RunningFlowContext + protected abstract fun recreate(inputs: List): RunningFlowContext private fun normalizeInputs(context: RunningFlowContext, firstEpochMillis: Long): List { return context.inputs.map { entry -> @@ -147,15 +105,6 @@ abstract class RunningFlowContext protected constructor( } } - private fun escapeXml(value: String): String { - return value - .replace("&", "&") - .replace("<", "<") - .replace(">", ">") - .replace("\"", """) - .replace("'", "'") - } - data class InputEntry( val offsetMillis: Long, val content: String @@ -163,7 +112,6 @@ abstract class RunningFlowContext protected constructor( class Info { val uuid = UUID.randomUUID().toString() - val dateTime: LocalDateTime = LocalDateTime.now() } class Status { diff --git a/Partner-Framework/src/test/java/work/slhaf/partner/framework/agent/interaction/AgentRuntimeTest.kt b/Partner-Framework/src/test/java/work/slhaf/partner/framework/agent/interaction/AgentRuntimeTest.kt index ef8c3052..71bc9a3e 100644 --- a/Partner-Framework/src/test/java/work/slhaf/partner/framework/agent/interaction/AgentRuntimeTest.kt +++ b/Partner-Framework/src/test/java/work/slhaf/partner/framework/agent/interaction/AgentRuntimeTest.kt @@ -29,21 +29,6 @@ class AgentRuntimeTest { clearModules() } - @Test - fun `running flow context preserves offsets and xml encoding`() { - val first = TestRunningFlowContext.of("source-a", "first", 1_000L) - val second = TestRunningFlowContext.of("source-a", "second", 1_250L) - - val merged = first.mergedWith(second) - - assertEquals(listOf(0L, 250L), merged.inputs.map { it.offsetMillis }) - assertEquals("first\nsecond", merged.input) - assertEquals( - "firstsecond", - merged.encodeInputsXml() - ) - } - @Test fun `agent runtime keeps source queue in first arrival order`() { val recorder = RecordingModule(order = 1, expectedExecutions = 2) @@ -185,9 +170,8 @@ class AgentRuntimeTest { private class TestRunningFlowContext private constructor( override val source: String, inputs: List, - firstInputEpochMillis: Long, - target: String = source - ) : RunningFlowContext(inputs, firstInputEpochMillis, target = target) { + firstInputEpochMillis: Long + ) : RunningFlowContext(inputs, firstInputEpochMillis) { companion object { fun of( @@ -203,22 +187,12 @@ class AgentRuntimeTest { } } - override fun copyWith( - inputs: List, - firstInputEpochMillis: Long, - additionalUserInfo: Map, - skippedModules: Set, - target: String - ): RunningFlowContext { + override fun recreate(inputs: List): RunningFlowContext { return TestRunningFlowContext( source = source, inputs = inputs, - firstInputEpochMillis = firstInputEpochMillis, - target = target - ).apply { - additionalUserInfo.forEach(::putUserInfo) - skippedModules.forEach(::addSkippedModule) - } + firstInputEpochMillis = System.currentTimeMillis() + ) } } }