Skip to main content

ValkyrAI Agentic SWARM Protocol

Canonical contract

The durable cross-agent contract is now GrayMatter SWARM Protocol v0.1. This architecture page documents the current ValkyrAI/ValorIDE transport topology and the legacy compatibility profile used by the LCARS dashboard.

Unified messaging protocol for coordinating ValkyrAI workflows, ValorIDE agents, web clients, and distributed processes into a coherent multi-agent system.

Overview​

The SWARM protocol enables real-time coordination between:

  • ValkyrAI Server - Spring Boot backend with WebSocket broker (STOMP over SockJS)
  • ValorIDE Instances - VSCode extension instances acting as autonomous agents
  • Web Clients - React SPAs with SageChat and ServerConsole
  • Workflow Engine - ValkyrAI workflow orchestration with ExecModules

Channel Topology​

Public Broadcast Channels​

ChannelPurpose
/topic/messagesGeneral system messages, broadcasts to all connected clients
/topic/statusesSystem status updates, workflow progress, health checks
/topic/agentsActive agent registry, presence announcements
/topic/agent-commandsBroadcast commands to all agents
/topic/workflow-monitoringWorkflow execution events, metrics

Private/Direct Channels​

ChannelPurpose
/user/{principalId}/queue/privatePrivate messages for specific authenticated user
/queue/agents/{instanceId}/commandsDirect commands to specific ValorIDE instance
/user/{principalId}/queue/notificationsUser-specific notifications
/topic/workflow/{workflowId}Workflow-specific updates

Application Endpoints (Client → Server)​

EndpointPurpose
/app/chatClient sends messages to server
/app/agent/registerAgent registration/heartbeat
/app/agent/ackAcknowledgment responses
/app/agent/announceAgent capabilities/status announcement

Security & Access Control​

  • Authentication: WebSocket connections require JWT authentication through the Authorization header. Do not place bearer tokens in query strings.
  • Private channels: Validate Principal ownership via Spring Security ACL
  • Broadcast channels: Open to authenticated users
  • Admin channels: Require ROLE_ADMIN or ROLE_SYSTEM

All channels enforce Spring Security policies.

Message Envelope​

The normalized GrayMatter SwarmEvent envelope is canonical for agents. Autonomous agents create or refresh a durable Agent record first and include source.agentRecordId in every event. Existing ValkyrAI and ValorIDE code can accept the legacy SwarmMessage shape for dashboard visibility while mapping id -> eventId, from -> source, to -> target, ackId -> parentEventId, and ttl -> ttlMs.

Standard Format​

All messages follow this JSON schema:

{
"id": "uuid-v4",
"type": "command|response|broadcast|event|ack|nack",
"from": {
"instanceId": "valoride-abc123",
"type": "agent|server|workflow|user",
"principalId": "uuid-of-authenticated-principal",
"username": "john@example.com"
},
"to": {
"instanceId": "valoride-xyz789",
"type": "agent|server|broadcast",
"principalId": "uuid-target-principal"
},
"timestamp": "2025-10-27T12:34:56.789Z",
"ackId": "uuid-of-message-to-acknowledge",
"payload": {
"action": "execute|status|query|result",
"data": {
/* action-specific payload */
},
"metadata": {
"workflowId": "optional-workflow-uuid",
"sessionId": "optional-session-uuid",
"correlationId": "optional-correlation-uuid"
}
},
"security": {
"signature": "optional-hmac-sha256-signature",
"encrypted": false
},
"ttl": 300000,
"priority": "low|normal|high|urgent"
}

Field Reference​

FieldTypeDescription
idUUIDUnique message identifier
typeenumcommand, response, broadcast, event, ack, or nack
fromobjectSender identity (instanceId, type, principalId, username)
toobjectRecipient identity
timestampISO 8601Message creation time (UTC)
ackIdUUIDReference to message being acknowledged
payload.actionstringOperation to perform (e.g., "execute", "register")
payload.dataobjectAction-specific payload
payload.metadataobjectContextual IDs (workflow, session, correlation)
security.signaturestringOptional HMAC-SHA256 integrity signature
security.encryptedbooleanIndicates if payload is encrypted
ttlnumberTime-to-live in milliseconds (default 5 min)
priorityenumlow, normal, high, or urgent

Message Flows​

1. Agent Registration​

ValorIDE instance registers with server and broadcasts to swarm:

// ValorIDE → Server (/app/agent/register)
{
"id": "reg-001",
"type": "command",
"from": {
"instanceId": "valoride-abc123",
"type": "agent",
"principalId": "user-uuid",
"username": "john@example.com"
},
"to": { "type": "server" },
"timestamp": "2025-10-27T12:34:56.789Z",
"payload": {
"action": "register",
"data": {
"capabilities": ["code-generation", "file-operations", "git-commands"],
"version": "1.2.3",
"role": "worker",
"status": "idle"
}
}
}

// Server → All Agents (/topic/agents)
{
"id": "reg-ack-001",
"type": "broadcast",
"from": { "type": "server" },
"to": { "type": "broadcast" },
"timestamp": "2025-10-27T12:34:57.000Z",
"payload": {
"action": "agent-list-updated",
"data": {
"agents": [
{
"instanceId": "valoride-abc123",
"principalId": "user-uuid",
"username": "john@example.com",
"status": "idle",
"lastSeen": "2025-10-27T12:34:56.789Z",
"capabilities": ["code-generation", "file-operations"]
}
]
}
}
}

2. Command Execution with Ack/Nack​

Server sends command to agent and waits for acknowledgment:

// Server → Agent (/queue/agents/valoride-abc123/commands)
{
"id": "cmd-001",
"type": "command",
"from": { "type": "server", "principalId": "admin-uuid" },
"to": { "instanceId": "valoride-abc123", "type": "agent" },
"timestamp": "2025-10-27T12:35:00.000Z",
"payload": {
"action": "execute",
"data": {
"command": "generate-component",
"args": { "componentName": "UserProfile", "framework": "react" }
},
"metadata": {
"workflowId": "workflow-uuid-123",
"correlationId": "req-uuid-456"
}
},
"ttl": 60000,
"priority": "high"
}

// Agent → Server (/app/agent/ack)
{
"id": "ack-cmd-001",
"type": "ack",
"from": { "instanceId": "valoride-abc123", "type": "agent" },
"to": { "type": "server" },
"timestamp": "2025-10-27T12:35:01.000Z",
"ackId": "cmd-001",
"payload": {
"action": "acknowledged",
"data": { "status": "processing", "estimatedDuration": 5000 }
}
}

// Agent → Server (/app/chat) - Result
{
"id": "result-cmd-001",
"type": "response",
"from": { "instanceId": "valoride-abc123", "type": "agent" },
"to": { "type": "server" },
"timestamp": "2025-10-27T12:35:06.000Z",
"ackId": "cmd-001",
"payload": {
"action": "result",
"data": {
"success": true,
"filesCreated": [
"src/components/UserProfile.tsx",
"src/components/UserProfile.css"
],
"output": "Component generated successfully"
},
"metadata": {
"workflowId": "workflow-uuid-123",
"correlationId": "req-uuid-456"
}
}
}

3. Error Handling (Nack)​

Agent cannot execute command and sends negative acknowledgment:

{
"id": "nack-cmd-002",
"type": "nack",
"from": { "instanceId": "valoride-abc123", "type": "agent" },
"to": { "type": "server" },
"timestamp": "2025-10-27T12:36:00.000Z",
"ackId": "cmd-002",
"payload": {
"action": "rejected",
"data": {
"error": "InsufficientPermissions",
"message": "Agent lacks file write permissions in target directory",
"code": "ERR_PERMISSION_DENIED"
}
}
}

4. Workflow Coordination​

ValkyrAI workflow triggers ValorIDE agent:

{
"id": "wf-task-001",
"type": "command",
"from": { "type": "workflow", "principalId": "owner-uuid" },
"to": {
"instanceId": "valoride-abc123",
"type": "agent",
"principalId": "owner-uuid"
},
"timestamp": "2025-10-27T12:40:00.000Z",
"payload": {
"action": "execute-task",
"data": {
"task": "code-review",
"files": ["src/services/UserService.ts"],
"criteria": ["security", "performance", "maintainability"]
},
"metadata": {
"workflowId": "wf-uuid-789",
"taskId": "task-uuid-101"
}
}
}

Implementation​

Server-Side (Spring Boot)​

  1. Message Validation - Use @Valid annotations and custom validators
  2. ACL Checks - Verify Principal ownership on private channels via @PreAuthorize
  3. Persistence - Store command history in DB for audit trail
  4. Retry Logic - Implement exponential backoff for failed deliveries
  5. Rate Limiting - Apply per-Principal rate limits on /app/* endpoints

Client-Side (ValorIDE & Web)​

  1. Message Normalization - Use shared TypeScript helper to encode/decode
  2. Ack Tracking - Maintain pending ack map with timeout handling
  3. Reconnection - Implement exponential backoff with jitter
  4. State Sync - Re-announce presence on reconnect
  5. Local Queue - Buffer messages during disconnect, replay on connect

ExecModule Pattern​

Template for ValorIDE interaction ExecModule:

@Component("valorideExecModule")
@VModuleAware
public class ValorIDEExecModule extends VModule {

@Autowired
private SimpMessagingTemplate messagingTemplate;

@Autowired
private SwarmRegistryService swarmRegistry;

@Override
public Map<String, Object> execute(
Workflow workflow,
Task task,
ExecModule module,
Map<String, Object> input
) {
String targetInstanceId = (String) input.get("targetInstanceId");
String action = (String) input.get("action");
Map<String, Object> data = (Map) input.get("data");

// Build message envelope
Map<String, Object> message = Map.of(
"id", UUID.randomUUID().toString(),
"type", "command",
"from", Map.of("type", "workflow"),
"to", Map.of("instanceId", targetInstanceId, "type", "agent"),
"timestamp", Instant.now().toString(),
"payload", Map.of("action", action, "data", data)
);

// Send to agent
String destination = "/queue/agents/" + targetInstanceId + "/commands";
messagingTemplate.convertAndSend(destination, message);

return Map.of("status", "sent", "messageId", message.get("id"));
}
}

Migration Path​

  1. Phase 1 - Add envelope support to existing messages (backward compatible)
  2. Phase 2 - Update SwarmRegistryService and ValorBroadcastService to use envelopes
  3. Phase 3 - Implement ValorIDEExecModule and client-side handlers
  4. Phase 4 - Migrate all WebSocket messages to unified envelope
  5. Phase 5 - Deprecate legacy message formats

References​

  • GrayMatter SWARM Protocol v0.1
  • ValorIDE SWARM protocol - ValorIDE SWARM quickstart
  • valkyrai/src/main/java/com/valkyrlabs/valkyrai/config/WebSocketConfig.java - Server WebSocket configuration
  • docs/SWARM_ORCHESTRATOR_PROMPT.md - System prompt for orchestration agent

✅ PRODUCTION READY