agentic-qe 3.6.0 → 3.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/v3/qe-devils-advocate.md +218 -0
- package/.claude/agents/v3/qe-quality-criteria-recommender.md +2 -2
- package/.claude/skills/qe-iterative-loop/SKILL.md +1 -1
- package/.claude/skills/release/SKILL.md +17 -31
- package/.claude/skills/skills-manifest.json +1 -1
- package/README.md +38 -35
- package/package.json +1 -1
- package/scripts/cloud-db-config.json +1 -1
- package/v3/CHANGELOG.md +44 -0
- package/v3/README.md +7 -7
- package/v3/assets/agents/v3/qe-devils-advocate.md +218 -0
- package/v3/assets/agents/v3/qe-quality-criteria-recommender.md +2 -2
- package/v3/assets/skills/qe-iterative-loop/SKILL.md +1 -1
- package/v3/dist/agents/devils-advocate/agent.d.ts +103 -0
- package/v3/dist/agents/devils-advocate/agent.d.ts.map +1 -0
- package/v3/dist/agents/devils-advocate/agent.js +240 -0
- package/v3/dist/agents/devils-advocate/agent.js.map +1 -0
- package/v3/dist/agents/devils-advocate/index.d.ts +60 -0
- package/v3/dist/agents/devils-advocate/index.d.ts.map +1 -0
- package/v3/dist/agents/devils-advocate/index.js +72 -0
- package/v3/dist/agents/devils-advocate/index.js.map +1 -0
- package/v3/dist/agents/devils-advocate/strategies.d.ts +59 -0
- package/v3/dist/agents/devils-advocate/strategies.d.ts.map +1 -0
- package/v3/dist/agents/devils-advocate/strategies.js +438 -0
- package/v3/dist/agents/devils-advocate/strategies.js.map +1 -0
- package/v3/dist/agents/devils-advocate/types.d.ts +182 -0
- package/v3/dist/agents/devils-advocate/types.d.ts.map +1 -0
- package/v3/dist/agents/devils-advocate/types.js +96 -0
- package/v3/dist/agents/devils-advocate/types.js.map +1 -0
- package/v3/dist/agents/index.d.ts +20 -0
- package/v3/dist/agents/index.d.ts.map +1 -0
- package/v3/dist/agents/index.js +20 -0
- package/v3/dist/agents/index.js.map +1 -0
- package/v3/dist/cli/bundle.js +4489 -119
- package/v3/dist/coordination/agent-teams/adapter.d.ts +108 -0
- package/v3/dist/coordination/agent-teams/adapter.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/adapter.js +316 -0
- package/v3/dist/coordination/agent-teams/adapter.js.map +1 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.d.ts +164 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.js +342 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.js.map +1 -0
- package/v3/dist/coordination/agent-teams/index.d.ts +53 -0
- package/v3/dist/coordination/agent-teams/index.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/index.js +61 -0
- package/v3/dist/coordination/agent-teams/index.js.map +1 -0
- package/v3/dist/coordination/agent-teams/mailbox.d.ts +142 -0
- package/v3/dist/coordination/agent-teams/mailbox.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/mailbox.js +395 -0
- package/v3/dist/coordination/agent-teams/mailbox.js.map +1 -0
- package/v3/dist/coordination/agent-teams/tracing.d.ts +199 -0
- package/v3/dist/coordination/agent-teams/tracing.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/tracing.js +308 -0
- package/v3/dist/coordination/agent-teams/tracing.js.map +1 -0
- package/v3/dist/coordination/agent-teams/types.d.ts +121 -0
- package/v3/dist/coordination/agent-teams/types.d.ts.map +1 -0
- package/v3/dist/coordination/agent-teams/types.js +17 -0
- package/v3/dist/coordination/agent-teams/types.js.map +1 -0
- package/v3/dist/coordination/circuit-breaker/breaker-registry.d.ts +146 -0
- package/v3/dist/coordination/circuit-breaker/breaker-registry.d.ts.map +1 -0
- package/v3/dist/coordination/circuit-breaker/breaker-registry.js +368 -0
- package/v3/dist/coordination/circuit-breaker/breaker-registry.js.map +1 -0
- package/v3/dist/coordination/circuit-breaker/domain-circuit-breaker.d.ts +134 -0
- package/v3/dist/coordination/circuit-breaker/domain-circuit-breaker.d.ts.map +1 -0
- package/v3/dist/coordination/circuit-breaker/domain-circuit-breaker.js +337 -0
- package/v3/dist/coordination/circuit-breaker/domain-circuit-breaker.js.map +1 -0
- package/v3/dist/coordination/circuit-breaker/index.d.ts +46 -0
- package/v3/dist/coordination/circuit-breaker/index.d.ts.map +1 -0
- package/v3/dist/coordination/circuit-breaker/index.js +51 -0
- package/v3/dist/coordination/circuit-breaker/index.js.map +1 -0
- package/v3/dist/coordination/circuit-breaker/types.d.ts +112 -0
- package/v3/dist/coordination/circuit-breaker/types.d.ts.map +1 -0
- package/v3/dist/coordination/circuit-breaker/types.js +10 -0
- package/v3/dist/coordination/circuit-breaker/types.js.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/hypothesis-manager.d.ts +122 -0
- package/v3/dist/coordination/competing-hypotheses/hypothesis-manager.d.ts.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/hypothesis-manager.js +377 -0
- package/v3/dist/coordination/competing-hypotheses/hypothesis-manager.js.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/index.d.ts +34 -0
- package/v3/dist/coordination/competing-hypotheses/index.d.ts.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/index.js +39 -0
- package/v3/dist/coordination/competing-hypotheses/index.js.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/types.d.ts +134 -0
- package/v3/dist/coordination/competing-hypotheses/types.d.ts.map +1 -0
- package/v3/dist/coordination/competing-hypotheses/types.js +20 -0
- package/v3/dist/coordination/competing-hypotheses/types.js.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts +173 -0
- package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js +368 -0
- package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/index.d.ts +38 -0
- package/v3/dist/coordination/dynamic-scaling/index.d.ts.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/index.js +39 -0
- package/v3/dist/coordination/dynamic-scaling/index.js.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/types.d.ts +147 -0
- package/v3/dist/coordination/dynamic-scaling/types.d.ts.map +1 -0
- package/v3/dist/coordination/dynamic-scaling/types.js +40 -0
- package/v3/dist/coordination/dynamic-scaling/types.js.map +1 -0
- package/v3/dist/coordination/federation/federation-mailbox.d.ts +215 -0
- package/v3/dist/coordination/federation/federation-mailbox.d.ts.map +1 -0
- package/v3/dist/coordination/federation/federation-mailbox.js +442 -0
- package/v3/dist/coordination/federation/federation-mailbox.js.map +1 -0
- package/v3/dist/coordination/federation/index.d.ts +38 -0
- package/v3/dist/coordination/federation/index.d.ts.map +1 -0
- package/v3/dist/coordination/federation/index.js +39 -0
- package/v3/dist/coordination/federation/index.js.map +1 -0
- package/v3/dist/coordination/federation/types.d.ts +103 -0
- package/v3/dist/coordination/federation/types.d.ts.map +1 -0
- package/v3/dist/coordination/federation/types.js +20 -0
- package/v3/dist/coordination/federation/types.js.map +1 -0
- package/v3/dist/coordination/fleet-tiers/index.d.ts +39 -0
- package/v3/dist/coordination/fleet-tiers/index.d.ts.map +1 -0
- package/v3/dist/coordination/fleet-tiers/index.js +44 -0
- package/v3/dist/coordination/fleet-tiers/index.js.map +1 -0
- package/v3/dist/coordination/fleet-tiers/tier-config.d.ts +60 -0
- package/v3/dist/coordination/fleet-tiers/tier-config.d.ts.map +1 -0
- package/v3/dist/coordination/fleet-tiers/tier-config.js +242 -0
- package/v3/dist/coordination/fleet-tiers/tier-config.js.map +1 -0
- package/v3/dist/coordination/fleet-tiers/tier-selector.d.ts +134 -0
- package/v3/dist/coordination/fleet-tiers/tier-selector.d.ts.map +1 -0
- package/v3/dist/coordination/fleet-tiers/tier-selector.js +373 -0
- package/v3/dist/coordination/fleet-tiers/tier-selector.js.map +1 -0
- package/v3/dist/coordination/fleet-tiers/types.d.ts +137 -0
- package/v3/dist/coordination/fleet-tiers/types.d.ts.map +1 -0
- package/v3/dist/coordination/fleet-tiers/types.js +20 -0
- package/v3/dist/coordination/fleet-tiers/types.js.map +1 -0
- package/v3/dist/coordination/index.d.ts +16 -0
- package/v3/dist/coordination/index.d.ts.map +1 -1
- package/v3/dist/coordination/index.js +29 -0
- package/v3/dist/coordination/index.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +79 -0
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +363 -0
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/coordination/task-dag/dag.d.ts +93 -0
- package/v3/dist/coordination/task-dag/dag.d.ts.map +1 -0
- package/v3/dist/coordination/task-dag/dag.js +496 -0
- package/v3/dist/coordination/task-dag/dag.js.map +1 -0
- package/v3/dist/coordination/task-dag/index.d.ts +54 -0
- package/v3/dist/coordination/task-dag/index.d.ts.map +1 -0
- package/v3/dist/coordination/task-dag/index.js +62 -0
- package/v3/dist/coordination/task-dag/index.js.map +1 -0
- package/v3/dist/coordination/task-dag/scheduler.d.ts +123 -0
- package/v3/dist/coordination/task-dag/scheduler.d.ts.map +1 -0
- package/v3/dist/coordination/task-dag/scheduler.js +262 -0
- package/v3/dist/coordination/task-dag/scheduler.js.map +1 -0
- package/v3/dist/coordination/task-dag/types.d.ts +103 -0
- package/v3/dist/coordination/task-dag/types.d.ts.map +1 -0
- package/v3/dist/coordination/task-dag/types.js +9 -0
- package/v3/dist/coordination/task-dag/types.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/odata-service.js +3 -3
- package/v3/dist/domains/enterprise-integration/services/odata-service.js.map +1 -1
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.d.ts.map +1 -1
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.js +9 -4
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.js.map +1 -1
- package/v3/dist/domains/requirements-validation/services/quality-criteria/quality-criteria-service.js +1 -1
- package/v3/dist/domains/requirements-validation/services/quality-criteria/quality-criteria-service.js.map +1 -1
- package/v3/dist/hooks/index.d.ts +8 -1
- package/v3/dist/hooks/index.d.ts.map +1 -1
- package/v3/dist/hooks/index.js +8 -1
- package/v3/dist/hooks/index.js.map +1 -1
- package/v3/dist/hooks/quality-gate-enforcer.d.ts +134 -0
- package/v3/dist/hooks/quality-gate-enforcer.d.ts.map +1 -0
- package/v3/dist/hooks/quality-gate-enforcer.js +265 -0
- package/v3/dist/hooks/quality-gate-enforcer.js.map +1 -0
- package/v3/dist/hooks/reasoning-bank-pattern-store.d.ts +60 -0
- package/v3/dist/hooks/reasoning-bank-pattern-store.d.ts.map +1 -0
- package/v3/dist/hooks/reasoning-bank-pattern-store.js +179 -0
- package/v3/dist/hooks/reasoning-bank-pattern-store.js.map +1 -0
- package/v3/dist/hooks/task-completed-hook.d.ts +174 -0
- package/v3/dist/hooks/task-completed-hook.d.ts.map +1 -0
- package/v3/dist/hooks/task-completed-hook.js +330 -0
- package/v3/dist/hooks/task-completed-hook.js.map +1 -0
- package/v3/dist/hooks/teammate-idle-hook.d.ts +167 -0
- package/v3/dist/hooks/teammate-idle-hook.d.ts.map +1 -0
- package/v3/dist/hooks/teammate-idle-hook.js +332 -0
- package/v3/dist/hooks/teammate-idle-hook.js.map +1 -0
- package/v3/dist/index.d.ts +3 -0
- package/v3/dist/index.d.ts.map +1 -1
- package/v3/dist/index.js +4 -0
- package/v3/dist/index.js.map +1 -1
- package/v3/dist/init/agents-installer.d.ts +5 -1
- package/v3/dist/init/agents-installer.d.ts.map +1 -1
- package/v3/dist/init/agents-installer.js +13 -5
- package/v3/dist/init/agents-installer.js.map +1 -1
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -1
- package/v3/dist/init/phases/12-verification.js +13 -1
- package/v3/dist/init/phases/12-verification.js.map +1 -1
- package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
- package/v3/dist/kernel/unified-memory.js +303 -18
- package/v3/dist/kernel/unified-memory.js.map +1 -1
- package/v3/dist/learning/pattern-store.js +1 -1
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/qe-patterns.d.ts +2 -0
- package/v3/dist/learning/qe-patterns.d.ts.map +1 -1
- package/v3/dist/learning/qe-patterns.js.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.js +16 -3
- package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
- package/v3/dist/mcp/bundle.js +4473 -133
- package/v3/dist/sync/cloud/tunnel-manager.d.ts.map +1 -1
- package/v3/dist/sync/cloud/tunnel-manager.js +11 -0
- package/v3/dist/sync/cloud/tunnel-manager.js.map +1 -1
- package/v3/package.json +1 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Agent Teams Mailbox Service
|
|
3
|
+
* ADR-064: Per-agent message queue management
|
|
4
|
+
*
|
|
5
|
+
* Manages in-memory mailboxes for inter-agent communication.
|
|
6
|
+
* Each agent gets a dedicated mailbox that supports:
|
|
7
|
+
* - Direct message delivery (point-to-point)
|
|
8
|
+
* - Domain-wide broadcasts
|
|
9
|
+
* - TTL-based message expiration
|
|
10
|
+
* - Unread tracking with peek support
|
|
11
|
+
* - Event callbacks for message arrival
|
|
12
|
+
*/
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Mailbox Service
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Service managing per-agent message queues with in-memory storage.
|
|
18
|
+
* Provides thread-safe message delivery, broadcast support, and TTL expiration.
|
|
19
|
+
*/
|
|
20
|
+
export class MailboxService {
|
|
21
|
+
/** Agent mailboxes keyed by agent ID */
|
|
22
|
+
mailboxes = new Map();
|
|
23
|
+
/** Message delivery listeners keyed by agent ID */
|
|
24
|
+
messageHandlers = new Map();
|
|
25
|
+
/** Broadcast listeners keyed by domain */
|
|
26
|
+
broadcastHandlers = new Map();
|
|
27
|
+
/** Index of agents by domain for efficient broadcast */
|
|
28
|
+
domainAgents = new Map();
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Mailbox Lifecycle
|
|
31
|
+
// ============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Create a mailbox for an agent. If a mailbox already exists for this
|
|
34
|
+
* agent ID, the existing mailbox is returned unchanged.
|
|
35
|
+
*
|
|
36
|
+
* @param agentId - Unique agent identifier
|
|
37
|
+
* @param domain - Domain the agent belongs to
|
|
38
|
+
* @returns The created or existing mailbox snapshot
|
|
39
|
+
*/
|
|
40
|
+
createMailbox(agentId, domain) {
|
|
41
|
+
const existing = this.mailboxes.get(agentId);
|
|
42
|
+
if (existing) {
|
|
43
|
+
return this.toSnapshot(existing);
|
|
44
|
+
}
|
|
45
|
+
const mailbox = {
|
|
46
|
+
agentId,
|
|
47
|
+
domain,
|
|
48
|
+
messages: [],
|
|
49
|
+
unreadCount: 0,
|
|
50
|
+
lastRead: Date.now(),
|
|
51
|
+
};
|
|
52
|
+
this.mailboxes.set(agentId, mailbox);
|
|
53
|
+
// Track agent in domain index
|
|
54
|
+
let agents = this.domainAgents.get(domain);
|
|
55
|
+
if (!agents) {
|
|
56
|
+
agents = new Set();
|
|
57
|
+
this.domainAgents.set(domain, agents);
|
|
58
|
+
}
|
|
59
|
+
agents.add(agentId);
|
|
60
|
+
return this.toSnapshot(mailbox);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the full mailbox state for an agent.
|
|
64
|
+
*
|
|
65
|
+
* @param agentId - Agent whose mailbox to retrieve
|
|
66
|
+
* @returns Mailbox snapshot or undefined if agent has no mailbox
|
|
67
|
+
*/
|
|
68
|
+
getMailbox(agentId) {
|
|
69
|
+
const mailbox = this.mailboxes.get(agentId);
|
|
70
|
+
if (!mailbox)
|
|
71
|
+
return undefined;
|
|
72
|
+
return this.toSnapshot(mailbox);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Delete an agent's mailbox and remove the agent from domain tracking.
|
|
76
|
+
*
|
|
77
|
+
* @param agentId - Agent whose mailbox to delete
|
|
78
|
+
* @returns True if a mailbox was deleted, false if none existed
|
|
79
|
+
*/
|
|
80
|
+
deleteMailbox(agentId) {
|
|
81
|
+
const mailbox = this.mailboxes.get(agentId);
|
|
82
|
+
if (!mailbox)
|
|
83
|
+
return false;
|
|
84
|
+
// Remove from domain index
|
|
85
|
+
const agents = this.domainAgents.get(mailbox.domain);
|
|
86
|
+
if (agents) {
|
|
87
|
+
agents.delete(agentId);
|
|
88
|
+
if (agents.size === 0) {
|
|
89
|
+
this.domainAgents.delete(mailbox.domain);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Remove handlers
|
|
93
|
+
this.messageHandlers.delete(agentId);
|
|
94
|
+
// Remove mailbox
|
|
95
|
+
this.mailboxes.delete(agentId);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// ============================================================================
|
|
99
|
+
// Message Delivery
|
|
100
|
+
// ============================================================================
|
|
101
|
+
/**
|
|
102
|
+
* Send a message to a specific agent's mailbox.
|
|
103
|
+
* If the target is 'broadcast', use the `broadcast()` method instead.
|
|
104
|
+
*
|
|
105
|
+
* @param message - The message to deliver
|
|
106
|
+
* @throws Error if the target agent has no mailbox
|
|
107
|
+
*/
|
|
108
|
+
send(message) {
|
|
109
|
+
if (message.to === 'broadcast') {
|
|
110
|
+
this.broadcast(message.domain, message);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const mailbox = this.mailboxes.get(message.to);
|
|
114
|
+
if (!mailbox) {
|
|
115
|
+
throw new Error(`No mailbox found for agent '${message.to}'. ` +
|
|
116
|
+
`Create a mailbox first with createMailbox().`);
|
|
117
|
+
}
|
|
118
|
+
mailbox.messages.push(message);
|
|
119
|
+
mailbox.unreadCount++;
|
|
120
|
+
// Notify listeners
|
|
121
|
+
const handlers = this.messageHandlers.get(message.to);
|
|
122
|
+
if (handlers) {
|
|
123
|
+
for (const handler of handlers) {
|
|
124
|
+
try {
|
|
125
|
+
handler(message);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Swallow handler errors to avoid breaking delivery
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Broadcast a message to all agents in a domain.
|
|
135
|
+
* The sender (if they have a mailbox in the domain) is excluded.
|
|
136
|
+
*
|
|
137
|
+
* @param domain - Domain to broadcast to
|
|
138
|
+
* @param message - The message to broadcast
|
|
139
|
+
*/
|
|
140
|
+
broadcast(domain, message) {
|
|
141
|
+
const agents = this.domainAgents.get(domain);
|
|
142
|
+
if (!agents)
|
|
143
|
+
return;
|
|
144
|
+
for (const agentId of agents) {
|
|
145
|
+
// Skip the sender
|
|
146
|
+
if (agentId === message.from)
|
|
147
|
+
continue;
|
|
148
|
+
const mailbox = this.mailboxes.get(agentId);
|
|
149
|
+
if (mailbox) {
|
|
150
|
+
mailbox.messages.push(message);
|
|
151
|
+
mailbox.unreadCount++;
|
|
152
|
+
// Notify per-agent listeners
|
|
153
|
+
const handlers = this.messageHandlers.get(agentId);
|
|
154
|
+
if (handlers) {
|
|
155
|
+
for (const handler of handlers) {
|
|
156
|
+
try {
|
|
157
|
+
handler(message);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Swallow handler errors
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Notify broadcast listeners
|
|
167
|
+
const broadcastListeners = this.broadcastHandlers.get(domain);
|
|
168
|
+
if (broadcastListeners) {
|
|
169
|
+
for (const handler of broadcastListeners) {
|
|
170
|
+
try {
|
|
171
|
+
handler(domain, message);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Swallow handler errors
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ============================================================================
|
|
180
|
+
// Message Retrieval
|
|
181
|
+
// ============================================================================
|
|
182
|
+
/**
|
|
183
|
+
* Retrieve unread messages for an agent, marking them as read.
|
|
184
|
+
*
|
|
185
|
+
* @param agentId - Agent whose messages to retrieve
|
|
186
|
+
* @param options - Optional filtering and limiting
|
|
187
|
+
* @returns Array of unread messages (empty if no mailbox or no unread)
|
|
188
|
+
*/
|
|
189
|
+
receive(agentId, options) {
|
|
190
|
+
const mailbox = this.mailboxes.get(agentId);
|
|
191
|
+
if (!mailbox || mailbox.unreadCount === 0)
|
|
192
|
+
return [];
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
const readIndex = mailbox.messages.length - mailbox.unreadCount;
|
|
195
|
+
// Get unread messages
|
|
196
|
+
let unread = mailbox.messages.slice(readIndex);
|
|
197
|
+
// Filter expired messages
|
|
198
|
+
unread = unread.filter(msg => !this.isExpired(msg, now));
|
|
199
|
+
// Apply type filter
|
|
200
|
+
if (options?.type) {
|
|
201
|
+
unread = unread.filter(msg => msg.type === options.type);
|
|
202
|
+
}
|
|
203
|
+
// Apply since filter
|
|
204
|
+
if (options?.since !== undefined) {
|
|
205
|
+
unread = unread.filter(msg => msg.timestamp >= options.since);
|
|
206
|
+
}
|
|
207
|
+
// Apply limit
|
|
208
|
+
if (options?.limit !== undefined && options.limit > 0) {
|
|
209
|
+
unread = unread.slice(0, options.limit);
|
|
210
|
+
}
|
|
211
|
+
// Mark all as read (regardless of filters, reading marks the mailbox)
|
|
212
|
+
mailbox.unreadCount = 0;
|
|
213
|
+
mailbox.lastRead = now;
|
|
214
|
+
return unread;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Check unread message count without marking any as read.
|
|
218
|
+
*
|
|
219
|
+
* @param agentId - Agent whose unread count to check
|
|
220
|
+
* @returns Number of unread messages (0 if no mailbox)
|
|
221
|
+
*/
|
|
222
|
+
peek(agentId) {
|
|
223
|
+
const mailbox = this.mailboxes.get(agentId);
|
|
224
|
+
if (!mailbox)
|
|
225
|
+
return 0;
|
|
226
|
+
// Count non-expired unread messages
|
|
227
|
+
const now = Date.now();
|
|
228
|
+
const readIndex = mailbox.messages.length - mailbox.unreadCount;
|
|
229
|
+
let validCount = 0;
|
|
230
|
+
for (let i = readIndex; i < mailbox.messages.length; i++) {
|
|
231
|
+
if (!this.isExpired(mailbox.messages[i], now)) {
|
|
232
|
+
validCount++;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return validCount;
|
|
236
|
+
}
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Cleanup
|
|
239
|
+
// ============================================================================
|
|
240
|
+
/**
|
|
241
|
+
* Remove expired messages from all mailboxes.
|
|
242
|
+
* Messages older than `maxAge` milliseconds are removed regardless of TTL.
|
|
243
|
+
* Messages with TTL that have expired are also removed.
|
|
244
|
+
*
|
|
245
|
+
* @param maxAge - Maximum message age in milliseconds
|
|
246
|
+
* @returns Number of messages removed
|
|
247
|
+
*/
|
|
248
|
+
cleanup(maxAge) {
|
|
249
|
+
const now = Date.now();
|
|
250
|
+
const cutoff = now - maxAge;
|
|
251
|
+
let removed = 0;
|
|
252
|
+
for (const mailbox of this.mailboxes.values()) {
|
|
253
|
+
const before = mailbox.messages.length;
|
|
254
|
+
const readIndex = mailbox.messages.length - mailbox.unreadCount;
|
|
255
|
+
mailbox.messages = mailbox.messages.filter((msg, index) => {
|
|
256
|
+
// Remove if older than max age
|
|
257
|
+
if (msg.timestamp < cutoff)
|
|
258
|
+
return false;
|
|
259
|
+
// Remove if TTL expired
|
|
260
|
+
if (this.isExpired(msg, now))
|
|
261
|
+
return false;
|
|
262
|
+
return true;
|
|
263
|
+
});
|
|
264
|
+
const removedFromMailbox = before - mailbox.messages.length;
|
|
265
|
+
removed += removedFromMailbox;
|
|
266
|
+
// Recalculate unread count
|
|
267
|
+
if (removedFromMailbox > 0) {
|
|
268
|
+
// The unread messages are at the tail. After filtering, we need
|
|
269
|
+
// to recalculate based on the new message array and lastRead.
|
|
270
|
+
mailbox.unreadCount = mailbox.messages.filter(msg => msg.timestamp > mailbox.lastRead).length;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return removed;
|
|
274
|
+
}
|
|
275
|
+
// ============================================================================
|
|
276
|
+
// Event Subscriptions
|
|
277
|
+
// ============================================================================
|
|
278
|
+
/**
|
|
279
|
+
* Register a handler for messages delivered to a specific agent.
|
|
280
|
+
*
|
|
281
|
+
* @param agentId - Agent whose messages to listen for
|
|
282
|
+
* @param handler - Callback invoked on each message delivery
|
|
283
|
+
* @returns Unsubscribe function
|
|
284
|
+
*/
|
|
285
|
+
onMessage(agentId, handler) {
|
|
286
|
+
let handlers = this.messageHandlers.get(agentId);
|
|
287
|
+
if (!handlers) {
|
|
288
|
+
handlers = [];
|
|
289
|
+
this.messageHandlers.set(agentId, handlers);
|
|
290
|
+
}
|
|
291
|
+
handlers.push(handler);
|
|
292
|
+
return () => {
|
|
293
|
+
const list = this.messageHandlers.get(agentId);
|
|
294
|
+
if (list) {
|
|
295
|
+
const idx = list.indexOf(handler);
|
|
296
|
+
if (idx >= 0)
|
|
297
|
+
list.splice(idx, 1);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Register a handler for broadcasts to a specific domain.
|
|
303
|
+
*
|
|
304
|
+
* @param domain - Domain to listen for broadcasts on
|
|
305
|
+
* @param handler - Callback invoked on each broadcast
|
|
306
|
+
* @returns Unsubscribe function
|
|
307
|
+
*/
|
|
308
|
+
onBroadcast(domain, handler) {
|
|
309
|
+
let handlers = this.broadcastHandlers.get(domain);
|
|
310
|
+
if (!handlers) {
|
|
311
|
+
handlers = [];
|
|
312
|
+
this.broadcastHandlers.set(domain, handlers);
|
|
313
|
+
}
|
|
314
|
+
handlers.push(handler);
|
|
315
|
+
return () => {
|
|
316
|
+
const list = this.broadcastHandlers.get(domain);
|
|
317
|
+
if (list) {
|
|
318
|
+
const idx = list.indexOf(handler);
|
|
319
|
+
if (idx >= 0)
|
|
320
|
+
list.splice(idx, 1);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
// ============================================================================
|
|
325
|
+
// Query Methods
|
|
326
|
+
// ============================================================================
|
|
327
|
+
/**
|
|
328
|
+
* Get all agent IDs that have mailboxes in a given domain.
|
|
329
|
+
*
|
|
330
|
+
* @param domain - Domain to query
|
|
331
|
+
* @returns Array of agent IDs
|
|
332
|
+
*/
|
|
333
|
+
getAgentsInDomain(domain) {
|
|
334
|
+
const agents = this.domainAgents.get(domain);
|
|
335
|
+
return agents ? Array.from(agents) : [];
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Get all registered domains.
|
|
339
|
+
*
|
|
340
|
+
* @returns Array of domain names
|
|
341
|
+
*/
|
|
342
|
+
getDomains() {
|
|
343
|
+
return Array.from(this.domainAgents.keys());
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Get total number of mailboxes.
|
|
347
|
+
*/
|
|
348
|
+
get size() {
|
|
349
|
+
return this.mailboxes.size;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Clear all mailboxes, handlers, and domain indexes.
|
|
353
|
+
*/
|
|
354
|
+
clear() {
|
|
355
|
+
this.mailboxes.clear();
|
|
356
|
+
this.messageHandlers.clear();
|
|
357
|
+
this.broadcastHandlers.clear();
|
|
358
|
+
this.domainAgents.clear();
|
|
359
|
+
}
|
|
360
|
+
// ============================================================================
|
|
361
|
+
// Private Helpers
|
|
362
|
+
// ============================================================================
|
|
363
|
+
/**
|
|
364
|
+
* Check if a message has expired based on its TTL.
|
|
365
|
+
*/
|
|
366
|
+
isExpired(message, now) {
|
|
367
|
+
if (!message.ttl || message.ttl <= 0)
|
|
368
|
+
return false;
|
|
369
|
+
return now > message.timestamp + message.ttl;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Create an immutable snapshot of a mutable mailbox.
|
|
373
|
+
*/
|
|
374
|
+
toSnapshot(mailbox) {
|
|
375
|
+
return {
|
|
376
|
+
agentId: mailbox.agentId,
|
|
377
|
+
domain: mailbox.domain,
|
|
378
|
+
messages: [...mailbox.messages],
|
|
379
|
+
unreadCount: mailbox.unreadCount,
|
|
380
|
+
lastRead: mailbox.lastRead,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// ============================================================================
|
|
385
|
+
// Factory Function
|
|
386
|
+
// ============================================================================
|
|
387
|
+
/**
|
|
388
|
+
* Create a new MailboxService instance.
|
|
389
|
+
*
|
|
390
|
+
* @returns A fresh MailboxService
|
|
391
|
+
*/
|
|
392
|
+
export function createMailboxService() {
|
|
393
|
+
return new MailboxService();
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=mailbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailbox.js","sourceRoot":"","sources":["../../../src/coordination/agent-teams/mailbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Distributed Tracing for Agent Teams
|
|
3
|
+
* ADR-064 Phase 3: Learning & Observability
|
|
4
|
+
*
|
|
5
|
+
* Provides trace context propagation across agent messages, enabling
|
|
6
|
+
* end-to-end visibility into multi-agent workflows. Trace contexts are
|
|
7
|
+
* encoded into the existing `correlationId` field on AgentMessage so
|
|
8
|
+
* no schema changes are required.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createTraceCollector, encodeTraceContext } from './tracing.js';
|
|
13
|
+
*
|
|
14
|
+
* const collector = createTraceCollector();
|
|
15
|
+
*
|
|
16
|
+
* // Start a root trace for an incoming request
|
|
17
|
+
* const { context, span } = collector.startTrace({
|
|
18
|
+
* operationName: 'generate-tests',
|
|
19
|
+
* agentId: 'lead-1',
|
|
20
|
+
* domain: 'test-generation',
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Propagate context via correlationId
|
|
24
|
+
* adapter.sendMessage('lead-1', 'agent-a', 'task-assignment', payload, {
|
|
25
|
+
* correlationId: encodeTraceContext(context),
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // On the receiving side, extract and continue the trace
|
|
29
|
+
* const parentCtx = extractTraceContext(message.correlationId);
|
|
30
|
+
* const child = collector.startSpan({
|
|
31
|
+
* operationName: 'execute-task',
|
|
32
|
+
* agentId: 'agent-a',
|
|
33
|
+
* domain: 'test-generation',
|
|
34
|
+
* parentContext: parentCtx,
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Complete or fail the span
|
|
38
|
+
* collector.completeSpan(child.span.spanId);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Trace context propagated across agent messages.
|
|
43
|
+
* Follows W3C Trace Context semantics adapted for in-process agent messaging.
|
|
44
|
+
*/
|
|
45
|
+
export interface TraceContext {
|
|
46
|
+
/** Root trace ID (same across all spans in a trace) */
|
|
47
|
+
readonly traceId: string;
|
|
48
|
+
/** Current span ID */
|
|
49
|
+
readonly spanId: string;
|
|
50
|
+
/** Parent span ID (undefined for root spans) */
|
|
51
|
+
readonly parentSpanId?: string;
|
|
52
|
+
/** Baggage: key-value pairs propagated through the trace */
|
|
53
|
+
readonly baggage?: Record<string, string>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A recorded span in the trace, representing a single unit of work
|
|
57
|
+
* performed by an agent within a domain.
|
|
58
|
+
*/
|
|
59
|
+
export interface TraceSpan {
|
|
60
|
+
readonly traceId: string;
|
|
61
|
+
readonly spanId: string;
|
|
62
|
+
readonly parentSpanId?: string;
|
|
63
|
+
readonly operationName: string;
|
|
64
|
+
readonly agentId: string;
|
|
65
|
+
readonly domain: string;
|
|
66
|
+
readonly startTime: number;
|
|
67
|
+
endTime?: number;
|
|
68
|
+
readonly tags: Record<string, string | number | boolean>;
|
|
69
|
+
readonly status: 'active' | 'completed' | 'error';
|
|
70
|
+
readonly errorMessage?: string;
|
|
71
|
+
}
|
|
72
|
+
/** Options for starting a new span */
|
|
73
|
+
export interface StartSpanOptions {
|
|
74
|
+
/** Name of the operation being traced */
|
|
75
|
+
readonly operationName: string;
|
|
76
|
+
/** Agent performing the operation */
|
|
77
|
+
readonly agentId: string;
|
|
78
|
+
/** Domain the operation belongs to */
|
|
79
|
+
readonly domain: string;
|
|
80
|
+
/** Parent trace context (omit to start a root span via startTrace) */
|
|
81
|
+
readonly parentContext?: TraceContext;
|
|
82
|
+
/** Optional tags to attach to the span */
|
|
83
|
+
readonly tags?: Record<string, string | number | boolean>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Collects, stores, and queries trace spans across agent workflows.
|
|
87
|
+
* Spans are stored in memory with configurable capacity and automatic
|
|
88
|
+
* purging of completed traces.
|
|
89
|
+
*/
|
|
90
|
+
export declare class TraceCollector {
|
|
91
|
+
private readonly spans;
|
|
92
|
+
private readonly traceIndex;
|
|
93
|
+
private readonly maxSpans;
|
|
94
|
+
constructor(maxSpans?: number);
|
|
95
|
+
/**
|
|
96
|
+
* Start a new root trace. Creates a fresh traceId and root span.
|
|
97
|
+
*
|
|
98
|
+
* @param options - Operation metadata (parentContext is ignored)
|
|
99
|
+
* @returns The new trace context and root span
|
|
100
|
+
*/
|
|
101
|
+
startTrace(options: Omit<StartSpanOptions, 'parentContext'>): {
|
|
102
|
+
context: TraceContext;
|
|
103
|
+
span: TraceSpan;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Start a child span within an existing trace.
|
|
107
|
+
* If `parentContext` is provided, the child inherits the traceId and
|
|
108
|
+
* records the parent's spanId as its parentSpanId.
|
|
109
|
+
* If no parentContext is provided, a new root trace is started.
|
|
110
|
+
*
|
|
111
|
+
* @param options - Operation metadata including optional parent context
|
|
112
|
+
* @returns The new trace context and child span
|
|
113
|
+
*/
|
|
114
|
+
startSpan(options: StartSpanOptions): {
|
|
115
|
+
context: TraceContext;
|
|
116
|
+
span: TraceSpan;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Mark a span as successfully completed.
|
|
120
|
+
*
|
|
121
|
+
* @param spanId - The span to complete
|
|
122
|
+
*/
|
|
123
|
+
completeSpan(spanId: string): void;
|
|
124
|
+
/**
|
|
125
|
+
* Mark a span as failed with an error message.
|
|
126
|
+
*
|
|
127
|
+
* @param spanId - The span to fail
|
|
128
|
+
* @param errorMessage - Description of the failure
|
|
129
|
+
*/
|
|
130
|
+
failSpan(spanId: string, errorMessage: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Get all spans belonging to a trace, ordered by start time.
|
|
133
|
+
*
|
|
134
|
+
* @param traceId - The trace to retrieve
|
|
135
|
+
* @returns Spans sorted by startTime (empty if trace not found)
|
|
136
|
+
*/
|
|
137
|
+
getTrace(traceId: string): TraceSpan[];
|
|
138
|
+
/**
|
|
139
|
+
* Get a single span by its ID.
|
|
140
|
+
*
|
|
141
|
+
* @param spanId - The span to retrieve
|
|
142
|
+
* @returns The span or undefined if not found
|
|
143
|
+
*/
|
|
144
|
+
getSpan(spanId: string): TraceSpan | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Get all currently active (not yet completed or failed) spans.
|
|
147
|
+
*
|
|
148
|
+
* @returns Array of active spans
|
|
149
|
+
*/
|
|
150
|
+
getActiveSpans(): TraceSpan[];
|
|
151
|
+
/**
|
|
152
|
+
* Get summary statistics about the collector's state.
|
|
153
|
+
*
|
|
154
|
+
* @returns Counts of total spans, active traces, and completed traces
|
|
155
|
+
*/
|
|
156
|
+
getStats(): {
|
|
157
|
+
totalSpans: number;
|
|
158
|
+
activeTraces: number;
|
|
159
|
+
completedTraces: number;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Purge completed traces whose spans are all older than `maxAge` ms.
|
|
163
|
+
* Only removes traces where every span has finished (completed or error)
|
|
164
|
+
* and all end/start timestamps are past the cutoff.
|
|
165
|
+
*
|
|
166
|
+
* @param maxAge - Maximum age in milliseconds
|
|
167
|
+
* @returns Number of spans removed
|
|
168
|
+
*/
|
|
169
|
+
purge(maxAge: number): number;
|
|
170
|
+
/**
|
|
171
|
+
* Dispose the collector, clearing all stored spans and indexes.
|
|
172
|
+
*/
|
|
173
|
+
dispose(): void;
|
|
174
|
+
private createSpan;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Extract a TraceContext from an AgentMessage's correlationId field.
|
|
178
|
+
* Returns undefined if the correlationId is not trace-encoded or is malformed.
|
|
179
|
+
*
|
|
180
|
+
* @param correlationId - The correlationId string from an AgentMessage
|
|
181
|
+
* @returns Parsed TraceContext or undefined
|
|
182
|
+
*/
|
|
183
|
+
export declare function extractTraceContext(correlationId?: string): TraceContext | undefined;
|
|
184
|
+
/**
|
|
185
|
+
* Encode a TraceContext into a correlationId string that can be set on
|
|
186
|
+
* an AgentMessage. The encoding uses a `trace:` prefix followed by JSON.
|
|
187
|
+
*
|
|
188
|
+
* @param context - The trace context to encode
|
|
189
|
+
* @returns Encoded correlationId string
|
|
190
|
+
*/
|
|
191
|
+
export declare function encodeTraceContext(context: TraceContext): string;
|
|
192
|
+
/**
|
|
193
|
+
* Create a new TraceCollector instance.
|
|
194
|
+
*
|
|
195
|
+
* @param maxSpans - Maximum number of spans to retain (default 10,000)
|
|
196
|
+
* @returns A fresh TraceCollector
|
|
197
|
+
*/
|
|
198
|
+
export declare function createTraceCollector(maxSpans?: number): TraceCollector;
|
|
199
|
+
//# sourceMappingURL=tracing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../../src/coordination/agent-teams/tracing.ts"],"names":[],"mappings":"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"}
|