Implement Reliable Agent Architecture using CommunicationEvent thread logic
- Update AgentServices.xml: Single-turn state machine (process one turn, re-queue if tool called) - Add Agent.secas.xml: Trigger Agent Turn on new CommunicationEvent to Agent Party - Update AgentEntities.xml: Add rootCommEventId to SystemMessage for thread tracking - Update AgentData.xml: Define Agent Party, Role, and default VLLM config
Showing
4 changed files
with
50 additions
and
12 deletions
| ... | @@ -2,20 +2,18 @@ | ... | @@ -2,20 +2,18 @@ |
| 2 | <entity-facade-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 2 | <entity-facade-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 3 | xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/entity-facade-3.xsd" type="seed"> | 3 | xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/entity-facade-3.xsd" type="seed"> |
| 4 | 4 | ||
| 5 | <!-- ========================================================= --> | 5 | <moqui.security.UserGroup userGroupId="AgentUsers" description="AI Agent Users"/> |
| 6 | <!-- Agent User Account (for authentication) --> | ||
| 7 | <!-- ========================================================= --> | ||
| 8 | 6 | ||
| 9 | <moqui.security.UserAccount | 7 | <!-- Agent Party --> |
| 10 | userId="AGENT_CLAUDE" | 8 | <mantle.party.Party partyId="AGENT_CLAUDE_PARTY" partyTypeEnumId="PtyPerson"/> |
| 11 | username="agent-claude" | 9 | <mantle.party.Person partyId="AGENT_CLAUDE_PARTY" firstName="Claude" lastName="Agent"/> |
| 12 | currentPassword="16ac58bbfa332c1c55bd98b53e60720bfa90d394" | 10 | <mantle.party.PartyRole partyId="AGENT_CLAUDE_PARTY" roleTypeId="Agent"/> |
| 13 | passwordHashType="SHA"/> | ||
| 14 | 11 | ||
| 15 | <moqui.security.UserGroup userGroupId="AgentUsers" description="AI Agent Users"/> | 12 | <moqui.security.UserAccount userId="AGENT_CLAUDE" username="agent-claude" partyId="AGENT_CLAUDE_PARTY" |
| 13 | currentPassword="16ac58bbfa332c1c55bd98b53e60720bfa90d394" passwordHashType="SHA"/> | ||
| 16 | <moqui.security.UserGroupMember userGroupId="AgentUsers" userId="AGENT_CLAUDE" fromDate="2026-02-04 00:00:00.000"/> | 14 | <moqui.security.UserGroupMember userGroupId="AgentUsers" userId="AGENT_CLAUDE" fromDate="2026-02-04 00:00:00.000"/> |
| 17 | 15 | ||
| 18 | <!-- Agent users have permission to execute the delegation service --> | 16 | <!-- Agent users have permission to execute delegation service --> |
| 19 | <moqui.security.ArtifactGroup artifactGroupId="AgentDelegationServices" description="Agent Tool Delegation Services"/> | 17 | <moqui.security.ArtifactGroup artifactGroupId="AgentDelegationServices" description="Agent Tool Delegation Services"/> |
| 20 | <moqui.security.ArtifactGroupMember artifactGroupId="AgentDelegationServices" artifactName="AgentServices.call#McpToolWithDelegation" artifactTypeEnumId="AT_SERVICE"/> | 18 | <moqui.security.ArtifactGroupMember artifactGroupId="AgentDelegationServices" artifactName="AgentServices.call#McpToolWithDelegation" artifactTypeEnumId="AT_SERVICE"/> |
| 21 | <moqui.security.ArtifactAuthz userGroupId="AgentUsers" artifactGroupId="AgentDelegationServices" authzTypeEnumId="AUTHZT_ALLOW" authzActionEnumId="AUTHZA_ALL"/> | 19 | <moqui.security.ArtifactAuthz userGroupId="AgentUsers" artifactGroupId="AgentDelegationServices" authzTypeEnumId="AUTHZT_ALLOW" authzActionEnumId="AUTHZA_ALL"/> |
| ... | @@ -27,7 +25,13 @@ | ... | @@ -27,7 +25,13 @@ |
| 27 | <!-- Agent Task Message Type --> | 25 | <!-- Agent Task Message Type --> |
| 28 | <moqui.service.message.SystemMessageType systemMessageTypeId="SmtyAgentTask" description="Agent Task" | 26 | <moqui.service.message.SystemMessageType systemMessageTypeId="SmtyAgentTask" description="Agent Task" |
| 29 | contentType="application/json" | 27 | contentType="application/json" |
| 30 | consumeServiceName="AgentServices.poll#AgentQueue" | 28 | consumeServiceName="AgentServices.poll#AgentQueue"/> |
| 31 | receiveServiceName=""/> | 29 | |
| 30 | <!-- Default AI Config (Brainfood VLLM) --> | ||
| 31 | <moqui.mcp.agent.ProductStoreAiConfig | ||
| 32 | productStoreId="POPC_DEFAULT" aiConfigId="DEFAULT" | ||
| 33 | serviceTypeEnumId="AistVllm" description="Brainfood VLLM" | ||
| 34 | endpointUrl="http://crunchy.private.brainfood.com:11434/v1" apiKey="brainfood" | ||
| 35 | modelName="bf-ai" temperature="0.7" maxTokens="4096"/> | ||
| 32 | 36 | ||
| 33 | </entity-facade-xml> | 37 | </entity-facade-xml> | ... | ... |
| ... | @@ -19,6 +19,9 @@ | ... | @@ -19,6 +19,9 @@ |
| 19 | <field name="aiConfigId" type="id"> | 19 | <field name="aiConfigId" type="id"> |
| 20 | <description>Specific AI configuration used for this task.</description> | 20 | <description>Specific AI configuration used for this task.</description> |
| 21 | </field> | 21 | </field> |
| 22 | <field name="rootCommEventId" type="id"> | ||
| 23 | <description>The root CommunicationEvent ID for the conversation thread.</description> | ||
| 24 | </field> | ||
| 22 | 25 | ||
| 23 | <relationship type="one" title="RequestedBy" related="mantle.party.Party"> | 26 | <relationship type="one" title="RequestedBy" related="mantle.party.Party"> |
| 24 | <key-map field-name="requestedByPartyId" related="partyId"/> | 27 | <key-map field-name="requestedByPartyId" related="partyId"/> | ... | ... |
service/Agent.secas.xml
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <secas xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-eca-3.xsd"> | ||
| 3 | <seca id="AgentTriggerOnCommunication" service="create#mantle.party.communication.CommunicationEvent" when="post-service"> | ||
| 4 | <condition> | ||
| 5 | <expression>toPartyId == 'AGENT_CLAUDE_PARTY'</expression> | ||
| 6 | </condition> | ||
| 7 | <actions> | ||
| 8 | <!-- Ensure rootCommEventId is set (thread tracking) --> | ||
| 9 | <script><![CDATA[ | ||
| 10 | def rootId = rootCommEventId ?: communicationEventId | ||
| 11 | if (!rootCommEventId) { | ||
| 12 | ec.service.sync().name("update#mantle.party.communication.CommunicationEvent") | ||
| 13 | .parameters([communicationEventId: communicationEventId, rootCommEventId: rootId]) | ||
| 14 | .call() | ||
| 15 | } | ||
| 16 | |||
| 17 | // Trigger Agent Turn | ||
| 18 | ec.service.sync().name("create#moqui.service.message.SystemMessage").parameters([ | ||
| 19 | systemMessageTypeId: 'SmtyAgentTask', | ||
| 20 | statusId: 'SmsgReceived', | ||
| 21 | requestedByPartyId: fromPartyId, | ||
| 22 | effectiveUserId: ec.user.userId, // Use the actual human user ID for RBAC | ||
| 23 | productStoreId: 'POPC_DEFAULT', | ||
| 24 | aiConfigId: 'DEFAULT', | ||
| 25 | rootCommEventId: rootId, | ||
| 26 | isOutgoing: 'N' | ||
| 27 | ]).call() | ||
| 28 | ]]></script> | ||
| 29 | </actions> | ||
| 30 | </seca> | ||
| 31 | </secas> |
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment