agentic-qe 3.5.4 → 3.6.0
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/README.md +1 -1
- package/.claude/agents/v3/qe-message-broker-tester.md +380 -0
- package/.claude/agents/v3/qe-middleware-validator.md +423 -0
- package/.claude/agents/v3/qe-odata-contract-tester.md +484 -0
- package/.claude/agents/v3/qe-pentest-validator.md +359 -0
- package/.claude/agents/v3/qe-qx-partner.md +85 -3
- package/.claude/agents/v3/qe-sap-idoc-tester.md +407 -0
- package/.claude/agents/v3/qe-sap-rfc-tester.md +357 -0
- package/.claude/agents/v3/qe-soap-tester.md +340 -0
- package/.claude/agents/v3/qe-sod-analyzer.md +528 -0
- package/.claude/agents/v3/templates/qx-report-template.html +437 -0
- package/.claude/skills/debug-loop/SKILL.md +61 -0
- package/.claude/skills/enterprise-integration-testing/SKILL.md +735 -0
- package/.claude/skills/middleware-testing-patterns/SKILL.md +798 -0
- package/.claude/skills/observability-testing-patterns/SKILL.md +930 -0
- package/.claude/skills/pentest-validation/SKILL.md +268 -0
- package/.claude/skills/pentest-validation/evals/pentest-validation.yaml +708 -0
- package/.claude/skills/pentest-validation/schemas/output.json +281 -0
- package/.claude/skills/pentest-validation/scripts/validate.sh +402 -0
- package/.claude/skills/pr-review/SKILL.md +61 -0
- package/.claude/skills/qcsd-cicd-swarm/SKILL.md +315 -13
- package/.claude/skills/qcsd-development-swarm/SKILL.md +331 -16
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +258 -9
- package/.claude/skills/qcsd-refinement-swarm/SKILL.md +344 -22
- package/.claude/skills/release/SKILL.md +333 -0
- package/.claude/skills/skills-manifest.json +5 -4
- package/.claude/skills/wms-testing-patterns/SKILL.md +949 -0
- package/README.md +30 -21
- package/package.json +2 -2
- package/v3/CHANGELOG.md +57 -0
- package/v3/README.md +23 -20
- package/v3/assets/agents/v3/qe-message-broker-tester.md +380 -0
- package/v3/assets/agents/v3/qe-middleware-validator.md +423 -0
- package/v3/assets/agents/v3/qe-odata-contract-tester.md +484 -0
- package/v3/assets/agents/v3/qe-pentest-validator.md +359 -0
- package/v3/assets/agents/v3/qe-qx-partner.md +90 -12
- package/v3/assets/agents/v3/qe-sap-idoc-tester.md +407 -0
- package/v3/assets/agents/v3/qe-sap-rfc-tester.md +357 -0
- package/v3/assets/agents/v3/qe-soap-tester.md +340 -0
- package/v3/assets/agents/v3/qe-sod-analyzer.md +528 -0
- package/v3/assets/agents/v3/templates/qx-report-template.html +437 -0
- package/v3/assets/skills/debug-loop/SKILL.md +61 -0
- package/v3/assets/skills/enterprise-integration-testing/SKILL.md +735 -0
- package/v3/assets/skills/middleware-testing-patterns/SKILL.md +798 -0
- package/v3/assets/skills/observability-testing-patterns/SKILL.md +930 -0
- package/v3/assets/skills/pentest-validation/SKILL.md +268 -0
- package/v3/assets/skills/pentest-validation/evals/pentest-validation.yaml +708 -0
- package/v3/assets/skills/pentest-validation/schemas/output.json +281 -0
- package/v3/assets/skills/pentest-validation/scripts/validate.sh +402 -0
- package/v3/assets/skills/pr-review/SKILL.md +61 -0
- package/v3/assets/skills/qcsd-cicd-swarm/SKILL.md +2206 -0
- package/v3/assets/skills/qcsd-development-swarm/SKILL.md +2154 -0
- package/v3/assets/skills/qcsd-ideation-swarm/SKILL.md +2008 -1753
- package/v3/assets/skills/qcsd-refinement-swarm/SKILL.md +2398 -0
- package/v3/assets/skills/security-visual-testing/SKILL.md +223 -0
- package/v3/assets/skills/security-visual-testing/evals/security-visual-testing.yaml +163 -0
- package/v3/assets/skills/security-visual-testing/schemas/output.json +486 -0
- package/v3/assets/skills/security-visual-testing/scripts/validate.sh +748 -0
- package/v3/assets/skills/sfdipot-product-factors/SKILL.md +239 -0
- package/v3/assets/skills/test-idea-rewriting/SKILL.md +229 -0
- package/v3/assets/skills/wms-testing-patterns/SKILL.md +949 -0
- package/v3/dist/cli/bundle.js +10816 -4625
- package/v3/dist/cli/commands/coverage.d.ts.map +1 -1
- package/v3/dist/cli/commands/coverage.js +29 -0
- package/v3/dist/cli/commands/coverage.js.map +1 -1
- package/v3/dist/cli/commands/learning.d.ts.map +1 -1
- package/v3/dist/cli/commands/learning.js +9 -0
- package/v3/dist/cli/commands/learning.js.map +1 -1
- package/v3/dist/cli/commands/token-usage.d.ts.map +1 -1
- package/v3/dist/cli/commands/token-usage.js +6 -2
- package/v3/dist/cli/commands/token-usage.js.map +1 -1
- package/v3/dist/coordination/protocols/learning-consolidation.d.ts.map +1 -1
- package/v3/dist/coordination/protocols/learning-consolidation.js +1 -0
- package/v3/dist/coordination/protocols/learning-consolidation.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/coordinator.d.ts +8 -0
- package/v3/dist/domains/coverage-analysis/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/coordinator.js +67 -0
- package/v3/dist/domains/coverage-analysis/coordinator.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/interfaces.d.ts +33 -0
- package/v3/dist/domains/coverage-analysis/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/plugin.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/plugin.js +17 -0
- package/v3/dist/domains/coverage-analysis/plugin.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.d.ts +125 -0
- package/v3/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.d.ts.map +1 -0
- package/v3/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.js +317 -0
- package/v3/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.js.map +1 -0
- package/v3/dist/domains/coverage-analysis/services/index.d.ts +1 -0
- package/v3/dist/domains/coverage-analysis/services/index.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/index.js +4 -0
- package/v3/dist/domains/coverage-analysis/services/index.js.map +1 -1
- package/v3/dist/domains/enterprise-integration/coordinator.d.ts +91 -0
- package/v3/dist/domains/enterprise-integration/coordinator.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/coordinator.js +672 -0
- package/v3/dist/domains/enterprise-integration/coordinator.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/index.d.ts +14 -0
- package/v3/dist/domains/enterprise-integration/index.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/index.js +18 -0
- package/v3/dist/domains/enterprise-integration/index.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/interfaces.d.ts +376 -0
- package/v3/dist/domains/enterprise-integration/interfaces.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/interfaces.js +11 -0
- package/v3/dist/domains/enterprise-integration/interfaces.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/plugin.d.ts +88 -0
- package/v3/dist/domains/enterprise-integration/plugin.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/plugin.js +515 -0
- package/v3/dist/domains/enterprise-integration/plugin.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/esb-middleware-service.d.ts +67 -0
- package/v3/dist/domains/enterprise-integration/services/esb-middleware-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/esb-middleware-service.js +670 -0
- package/v3/dist/domains/enterprise-integration/services/esb-middleware-service.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/index.d.ts +13 -0
- package/v3/dist/domains/enterprise-integration/services/index.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/index.js +13 -0
- package/v3/dist/domains/enterprise-integration/services/index.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/message-broker-service.d.ts +88 -0
- package/v3/dist/domains/enterprise-integration/services/message-broker-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/message-broker-service.js +560 -0
- package/v3/dist/domains/enterprise-integration/services/message-broker-service.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/odata-service.d.ts +75 -0
- package/v3/dist/domains/enterprise-integration/services/odata-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/odata-service.js +618 -0
- package/v3/dist/domains/enterprise-integration/services/odata-service.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/sap-integration-service.d.ts +73 -0
- package/v3/dist/domains/enterprise-integration/services/sap-integration-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/sap-integration-service.js +513 -0
- package/v3/dist/domains/enterprise-integration/services/sap-integration-service.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.d.ts +84 -0
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.js +639 -0
- package/v3/dist/domains/enterprise-integration/services/soap-wsdl-service.js.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/sod-analysis-service.d.ts +90 -0
- package/v3/dist/domains/enterprise-integration/services/sod-analysis-service.d.ts.map +1 -0
- package/v3/dist/domains/enterprise-integration/services/sod-analysis-service.js +389 -0
- package/v3/dist/domains/enterprise-integration/services/sod-analysis-service.js.map +1 -0
- package/v3/dist/domains/index.d.ts +1 -0
- package/v3/dist/domains/index.d.ts.map +1 -1
- package/v3/dist/domains/index.js +1 -0
- package/v3/dist/domains/index.js.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.js +1 -0
- package/v3/dist/domains/learning-optimization/coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.js +1 -0
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/services/transfer-specialist.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/services/transfer-specialist.js +1 -0
- package/v3/dist/domains/learning-optimization/services/transfer-specialist.js.map +1 -1
- package/v3/dist/domains/test-execution/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/coordinator.js +34 -0
- package/v3/dist/domains/test-execution/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/services/test-data-generator.d.ts +7 -1
- package/v3/dist/domains/test-generation/services/test-data-generator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/test-data-generator.js +116 -98
- package/v3/dist/domains/test-generation/services/test-data-generator.js.map +1 -1
- package/v3/dist/init/agents-installer.d.ts +4 -0
- package/v3/dist/init/agents-installer.d.ts.map +1 -1
- package/v3/dist/init/agents-installer.js +32 -3
- package/v3/dist/init/agents-installer.js.map +1 -1
- package/v3/dist/init/skills-installer.d.ts.map +1 -1
- package/v3/dist/init/skills-installer.js +4 -1
- package/v3/dist/init/skills-installer.js.map +1 -1
- package/v3/dist/init/types.d.ts.map +1 -1
- package/v3/dist/init/types.js +1 -0
- package/v3/dist/init/types.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/budget-enforcer.d.ts +16 -0
- package/v3/dist/integrations/agentic-flow/model-router/budget-enforcer.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/budget-enforcer.js +41 -0
- package/v3/dist/integrations/agentic-flow/model-router/budget-enforcer.js.map +1 -1
- package/v3/dist/integrations/ruvector/provider.d.ts.map +1 -1
- package/v3/dist/integrations/ruvector/provider.js +1 -0
- package/v3/dist/integrations/ruvector/provider.js.map +1 -1
- package/v3/dist/kernel/anti-drift-middleware.d.ts +160 -0
- package/v3/dist/kernel/anti-drift-middleware.d.ts.map +1 -0
- package/v3/dist/kernel/anti-drift-middleware.js +376 -0
- package/v3/dist/kernel/anti-drift-middleware.js.map +1 -0
- package/v3/dist/kernel/event-bus.d.ts +29 -1
- package/v3/dist/kernel/event-bus.d.ts.map +1 -1
- package/v3/dist/kernel/event-bus.js +69 -6
- package/v3/dist/kernel/event-bus.js.map +1 -1
- package/v3/dist/kernel/interfaces.d.ts +35 -0
- package/v3/dist/kernel/interfaces.d.ts.map +1 -1
- package/v3/dist/kernel/kernel.d.ts.map +1 -1
- package/v3/dist/kernel/kernel.js +14 -17
- package/v3/dist/kernel/kernel.js.map +1 -1
- package/v3/dist/kernel/unified-memory.d.ts +5 -0
- package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
- package/v3/dist/kernel/unified-memory.js +28 -0
- package/v3/dist/kernel/unified-memory.js.map +1 -1
- package/v3/dist/learning/asymmetric-learning.d.ts +133 -0
- package/v3/dist/learning/asymmetric-learning.d.ts.map +1 -0
- package/v3/dist/learning/asymmetric-learning.js +170 -0
- package/v3/dist/learning/asymmetric-learning.js.map +1 -0
- package/v3/dist/learning/pattern-lifecycle.d.ts +26 -0
- package/v3/dist/learning/pattern-lifecycle.d.ts.map +1 -1
- package/v3/dist/learning/pattern-lifecycle.js +83 -0
- package/v3/dist/learning/pattern-lifecycle.js.map +1 -1
- package/v3/dist/learning/qe-patterns.d.ts +8 -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/real-qe-reasoning-bank.d.ts +28 -0
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.js +72 -4
- package/v3/dist/learning/real-qe-reasoning-bank.js.map +1 -1
- package/v3/dist/learning/token-tracker.d.ts +22 -0
- package/v3/dist/learning/token-tracker.d.ts.map +1 -1
- package/v3/dist/learning/token-tracker.js +67 -0
- package/v3/dist/learning/token-tracker.js.map +1 -1
- package/v3/dist/mcp/bundle.js +11099 -4879
- package/v3/dist/mcp/tool-registry.d.ts.map +1 -1
- package/v3/dist/mcp/tool-registry.js +4 -0
- package/v3/dist/mcp/tool-registry.js.map +1 -1
- package/v3/dist/mcp/tools/analysis/token-usage.d.ts +1 -1
- package/v3/dist/mcp/tools/analysis/token-usage.d.ts.map +1 -1
- package/v3/dist/mcp/tools/analysis/token-usage.js +23 -3
- package/v3/dist/mcp/tools/analysis/token-usage.js.map +1 -1
- package/v3/dist/mcp/tools/base.d.ts.map +1 -1
- package/v3/dist/mcp/tools/base.js +1 -15
- package/v3/dist/mcp/tools/base.js.map +1 -1
- package/v3/dist/mcp/tools/coverage-analysis/index.d.ts +7 -0
- package/v3/dist/mcp/tools/coverage-analysis/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/coverage-analysis/index.js +30 -0
- package/v3/dist/mcp/tools/coverage-analysis/index.js.map +1 -1
- package/v3/dist/optimization/token-optimizer-service.d.ts +7 -0
- package/v3/dist/optimization/token-optimizer-service.d.ts.map +1 -1
- package/v3/dist/optimization/token-optimizer-service.js +10 -1
- package/v3/dist/optimization/token-optimizer-service.js.map +1 -1
- package/v3/dist/shared/types/index.d.ts +20 -1
- package/v3/dist/shared/types/index.d.ts.map +1 -1
- package/v3/dist/shared/types/index.js +1 -0
- package/v3/dist/shared/types/index.js.map +1 -1
- package/v3/dist/strange-loop/healing-controller.d.ts.map +1 -1
- package/v3/dist/strange-loop/healing-controller.js +12 -0
- package/v3/dist/strange-loop/healing-controller.js.map +1 -1
- package/v3/dist/strange-loop/strange-loop.d.ts +14 -0
- package/v3/dist/strange-loop/strange-loop.d.ts.map +1 -1
- package/v3/dist/strange-loop/strange-loop.js +24 -0
- package/v3/dist/strange-loop/strange-loop.js.map +1 -1
- package/v3/dist/strange-loop/types.d.ts +2 -2
- package/v3/dist/strange-loop/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/types.js.map +1 -1
- package/v3/dist/sync/claude-flow-bridge.d.ts.map +1 -1
- package/v3/dist/sync/claude-flow-bridge.js +3 -24
- package/v3/dist/sync/claude-flow-bridge.js.map +1 -1
- package/v3/package.json +12 -9
- /package/{v3/assets/skills/sfdipot-product-factors/skill.md → .claude/skills/sfdipot-product-factors/SKILL.md} +0 -0
- /package/{v3/assets/skills/test-idea-rewriting/skill.md → .claude/skills/test-idea-rewriting/SKILL.md} +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Semantic Anti-Drift Middleware (ADR-060)
|
|
3
|
+
*
|
|
4
|
+
* AISP 5.1 Anti-Drift Protocol: for-all s in Sigma: Mean(s) === Mean_0(s).
|
|
5
|
+
* Attaches a semantic fingerprint (embedding vector) to each domain event at
|
|
6
|
+
* emission time, verifies cosine similarity at each receiving boundary.
|
|
7
|
+
* Falls back to deterministic hash-based pseudo-embeddings when the transformer
|
|
8
|
+
* model is unavailable (test/lightweight environments).
|
|
9
|
+
*/
|
|
10
|
+
import type { DomainEvent, Result } from '../shared/types/index.js';
|
|
11
|
+
/** Signature of a single tool call for loop detection. */
|
|
12
|
+
export interface ToolCallSignature {
|
|
13
|
+
readonly hash: string;
|
|
14
|
+
readonly toolName: string;
|
|
15
|
+
readonly argsFingerprint: string;
|
|
16
|
+
readonly timestamp: number;
|
|
17
|
+
}
|
|
18
|
+
/** Configuration for the loop detection system. */
|
|
19
|
+
export interface LoopDetectionConfig {
|
|
20
|
+
readonly maxIdenticalCalls: number;
|
|
21
|
+
readonly windowMs: number;
|
|
22
|
+
readonly steeringMessage: string;
|
|
23
|
+
readonly enableFleetLearning: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Result of a loop detection check. */
|
|
26
|
+
export interface LoopDetectionResult {
|
|
27
|
+
readonly isLoop: boolean;
|
|
28
|
+
readonly callCount: number;
|
|
29
|
+
readonly signature: ToolCallSignature;
|
|
30
|
+
readonly action: 'allow' | 'warn' | 'steer';
|
|
31
|
+
readonly steeringMessage?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Metrics from the loop detection tracker. */
|
|
34
|
+
export interface LoopDetectionMetrics {
|
|
35
|
+
readonly totalCallsTracked: number;
|
|
36
|
+
readonly loopsDetected: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* ToolCallSignatureTracker - ADR-062 Loop Detection
|
|
40
|
+
*
|
|
41
|
+
* Maintains a sliding window of recent tool calls per agent and detects
|
|
42
|
+
* repetitive loops using a 3-strike rule:
|
|
43
|
+
* - Strike 1: allow (logged internally)
|
|
44
|
+
* - Strike 2: warn
|
|
45
|
+
* - Strike 3+: steer (inject steering message)
|
|
46
|
+
*
|
|
47
|
+
* Feature flag: `process.env.AQE_LOOP_DETECTION_ENABLED !== 'false'`
|
|
48
|
+
*/
|
|
49
|
+
export declare class ToolCallSignatureTracker {
|
|
50
|
+
private readonly config;
|
|
51
|
+
private readonly callHistory;
|
|
52
|
+
private totalCallsTracked;
|
|
53
|
+
private loopsDetected;
|
|
54
|
+
constructor(config?: Partial<LoopDetectionConfig>);
|
|
55
|
+
/**
|
|
56
|
+
* Track a tool call and check for loops.
|
|
57
|
+
*
|
|
58
|
+
* @param agentId - The agent making the call
|
|
59
|
+
* @param toolName - Name of the tool being called
|
|
60
|
+
* @param args - Arguments to the tool call
|
|
61
|
+
* @returns Loop detection result with action recommendation
|
|
62
|
+
*/
|
|
63
|
+
trackCall(agentId: string, toolName: string, args: unknown): LoopDetectionResult;
|
|
64
|
+
/**
|
|
65
|
+
* Get metrics about loop detection activity.
|
|
66
|
+
*/
|
|
67
|
+
getMetrics(): LoopDetectionMetrics;
|
|
68
|
+
/**
|
|
69
|
+
* Clear all tracking state.
|
|
70
|
+
*/
|
|
71
|
+
clear(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Create a ToolCallSignature from tool name and arguments.
|
|
74
|
+
*/
|
|
75
|
+
private createSignature;
|
|
76
|
+
}
|
|
77
|
+
/** Generic middleware contract for the EventBus pipeline. */
|
|
78
|
+
export interface EventMiddleware {
|
|
79
|
+
readonly name: string;
|
|
80
|
+
readonly priority: number;
|
|
81
|
+
/** Called before an event is published. May augment the event. */
|
|
82
|
+
onEmit?(event: DomainEvent): Promise<DomainEvent>;
|
|
83
|
+
/** Called on receive. Returning null drops the event. */
|
|
84
|
+
onReceive?(event: DomainEvent): Promise<DomainEvent | null>;
|
|
85
|
+
}
|
|
86
|
+
/** Configuration for the anti-drift middleware. */
|
|
87
|
+
export interface AntiDriftConfig {
|
|
88
|
+
/** Per-category cosine-distance thresholds (1 - similarity). */
|
|
89
|
+
readonly thresholds: Record<string, number>;
|
|
90
|
+
/** Identifier of the agent that owns this middleware instance. */
|
|
91
|
+
readonly agentId: string;
|
|
92
|
+
/** Maximum drift-check results to retain. */
|
|
93
|
+
readonly maxHistorySize: number;
|
|
94
|
+
/** Embedding vector dimensionality for the hash-based fallback. */
|
|
95
|
+
readonly fallbackDimension: number;
|
|
96
|
+
/** Optional callback invoked when drift is detected. */
|
|
97
|
+
readonly onDriftDetected?: (event: DomainEvent) => Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
/** Outcome of a single drift check performed by `onReceive`. */
|
|
100
|
+
export interface DriftCheckResult {
|
|
101
|
+
readonly drifted: boolean;
|
|
102
|
+
readonly cosineSimilarity: number;
|
|
103
|
+
readonly threshold: number;
|
|
104
|
+
readonly eventType: string;
|
|
105
|
+
readonly hopCount: number;
|
|
106
|
+
readonly checkedAt: number;
|
|
107
|
+
}
|
|
108
|
+
/** Aggregated statistics about middleware activity. */
|
|
109
|
+
export interface AntiDriftStats {
|
|
110
|
+
readonly totalChecked: number;
|
|
111
|
+
readonly driftCount: number;
|
|
112
|
+
readonly averageSimilarity: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Middleware enforcing semantic stability of domain events across agent-hop
|
|
116
|
+
* boundaries. `onEmit` computes an embedding and attaches a SemanticFingerprint;
|
|
117
|
+
* `onReceive` re-embeds and checks cosine distance, dropping drifted events.
|
|
118
|
+
*/
|
|
119
|
+
export declare class SemanticAntiDriftMiddleware implements EventMiddleware {
|
|
120
|
+
readonly name = "semantic-anti-drift";
|
|
121
|
+
readonly priority = 10;
|
|
122
|
+
private readonly config;
|
|
123
|
+
private readonly history;
|
|
124
|
+
private totalChecked;
|
|
125
|
+
private driftCount;
|
|
126
|
+
private similaritySum;
|
|
127
|
+
constructor(config?: Partial<AntiDriftConfig>);
|
|
128
|
+
/**
|
|
129
|
+
* Compute the semantic embedding of the event payload and attach a
|
|
130
|
+
* {@link SemanticFingerprint} before publication.
|
|
131
|
+
* @param event - The domain event about to be published.
|
|
132
|
+
* @returns The event augmented with a `semanticFingerprint` field.
|
|
133
|
+
*/
|
|
134
|
+
onEmit(event: DomainEvent): Promise<DomainEvent>;
|
|
135
|
+
/**
|
|
136
|
+
* Re-embed the payload and compare with the original fingerprint.
|
|
137
|
+
* If drift exceeds threshold the event is dropped (returns null) and a
|
|
138
|
+
* SemanticDriftDetectedEvent is emitted. Events without a fingerprint
|
|
139
|
+
* pass through unchanged.
|
|
140
|
+
* @param event - The incoming domain event.
|
|
141
|
+
* @returns The event with incremented hopCount, or null if drifted.
|
|
142
|
+
*/
|
|
143
|
+
onReceive(event: DomainEvent): Promise<DomainEvent | null>;
|
|
144
|
+
/** Returns recent drift check results (bounded by maxHistorySize). */
|
|
145
|
+
getDriftHistory(): readonly DriftCheckResult[];
|
|
146
|
+
/** Aggregated statistics about drift checks performed so far. */
|
|
147
|
+
getStats(): AntiDriftStats;
|
|
148
|
+
/**
|
|
149
|
+
* Validate the middleware configuration.
|
|
150
|
+
* @returns ok(void) if valid, err(Error) otherwise.
|
|
151
|
+
*/
|
|
152
|
+
validateConfig(): Result<void, Error>;
|
|
153
|
+
/** Compute embedding, preferring transformer pipeline with hash fallback. */
|
|
154
|
+
private embed;
|
|
155
|
+
/** Map event type to threshold category via substring matching. */
|
|
156
|
+
private resolveCategory;
|
|
157
|
+
/** Fire a SemanticDriftDetectedEvent via the configured callback. */
|
|
158
|
+
private emitDriftEvent;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=anti-drift-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anti-drift-middleware.d.ts","sourceRoot":"","sources":["../../src/kernel/anti-drift-middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Semantic Anti-Drift Middleware (ADR-060)
|
|
3
|
+
*
|
|
4
|
+
* AISP 5.1 Anti-Drift Protocol: for-all s in Sigma: Mean(s) === Mean_0(s).
|
|
5
|
+
* Attaches a semantic fingerprint (embedding vector) to each domain event at
|
|
6
|
+
* emission time, verifies cosine similarity at each receiving boundary.
|
|
7
|
+
* Falls back to deterministic hash-based pseudo-embeddings when the transformer
|
|
8
|
+
* model is unavailable (test/lightweight environments).
|
|
9
|
+
*/
|
|
10
|
+
import { ok, err } from '../shared/types/index.js';
|
|
11
|
+
import { cosineSimilarity } from '../shared/utils/vector-math.js';
|
|
12
|
+
/** Default loop detection configuration. */
|
|
13
|
+
const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
14
|
+
maxIdenticalCalls: 3,
|
|
15
|
+
windowMs: 30000,
|
|
16
|
+
steeringMessage: 'Loop detected: the same tool call has been repeated multiple times. Consider an alternative approach or different parameters.',
|
|
17
|
+
enableFleetLearning: false,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* FNV-1a hash implementation for tool call signature hashing.
|
|
21
|
+
* Produces a deterministic 32-bit hash as a hex string.
|
|
22
|
+
*
|
|
23
|
+
* @param input - The string to hash
|
|
24
|
+
* @returns Hex string representation of the FNV-1a hash
|
|
25
|
+
*/
|
|
26
|
+
function fnv1aHash(input) {
|
|
27
|
+
let hash = 0x811c9dc5; // FNV offset basis
|
|
28
|
+
for (let i = 0; i < input.length; i++) {
|
|
29
|
+
hash ^= input.charCodeAt(i);
|
|
30
|
+
hash = Math.imul(hash, 0x01000193); // FNV prime
|
|
31
|
+
}
|
|
32
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* ToolCallSignatureTracker - ADR-062 Loop Detection
|
|
36
|
+
*
|
|
37
|
+
* Maintains a sliding window of recent tool calls per agent and detects
|
|
38
|
+
* repetitive loops using a 3-strike rule:
|
|
39
|
+
* - Strike 1: allow (logged internally)
|
|
40
|
+
* - Strike 2: warn
|
|
41
|
+
* - Strike 3+: steer (inject steering message)
|
|
42
|
+
*
|
|
43
|
+
* Feature flag: `process.env.AQE_LOOP_DETECTION_ENABLED !== 'false'`
|
|
44
|
+
*/
|
|
45
|
+
export class ToolCallSignatureTracker {
|
|
46
|
+
config;
|
|
47
|
+
callHistory = new Map();
|
|
48
|
+
totalCallsTracked = 0;
|
|
49
|
+
loopsDetected = 0;
|
|
50
|
+
constructor(config) {
|
|
51
|
+
this.config = { ...DEFAULT_LOOP_DETECTION_CONFIG, ...config };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Track a tool call and check for loops.
|
|
55
|
+
*
|
|
56
|
+
* @param agentId - The agent making the call
|
|
57
|
+
* @param toolName - Name of the tool being called
|
|
58
|
+
* @param args - Arguments to the tool call
|
|
59
|
+
* @returns Loop detection result with action recommendation
|
|
60
|
+
*/
|
|
61
|
+
trackCall(agentId, toolName, args) {
|
|
62
|
+
// Feature flag check
|
|
63
|
+
if (process.env.AQE_LOOP_DETECTION_ENABLED === 'false') {
|
|
64
|
+
const signature = this.createSignature(toolName, args);
|
|
65
|
+
return {
|
|
66
|
+
isLoop: false,
|
|
67
|
+
callCount: 1,
|
|
68
|
+
signature,
|
|
69
|
+
action: 'allow',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const signature = this.createSignature(toolName, args);
|
|
73
|
+
this.totalCallsTracked++;
|
|
74
|
+
// Get or create history for this agent
|
|
75
|
+
if (!this.callHistory.has(agentId)) {
|
|
76
|
+
this.callHistory.set(agentId, []);
|
|
77
|
+
}
|
|
78
|
+
const history = this.callHistory.get(agentId);
|
|
79
|
+
// Add current call to history
|
|
80
|
+
history.push(signature);
|
|
81
|
+
// Prune calls outside the sliding window
|
|
82
|
+
const cutoff = Date.now() - this.config.windowMs;
|
|
83
|
+
const pruneIndex = history.findIndex(s => s.timestamp >= cutoff);
|
|
84
|
+
if (pruneIndex > 0) {
|
|
85
|
+
history.splice(0, pruneIndex);
|
|
86
|
+
}
|
|
87
|
+
else if (pruneIndex === -1) {
|
|
88
|
+
// All entries are expired
|
|
89
|
+
history.length = 0;
|
|
90
|
+
history.push(signature);
|
|
91
|
+
}
|
|
92
|
+
// Count identical calls within the window
|
|
93
|
+
const identicalCount = history.filter(s => s.hash === signature.hash).length;
|
|
94
|
+
// Determine action based on strike count
|
|
95
|
+
if (identicalCount >= this.config.maxIdenticalCalls) {
|
|
96
|
+
this.loopsDetected++;
|
|
97
|
+
return {
|
|
98
|
+
isLoop: true,
|
|
99
|
+
callCount: identicalCount,
|
|
100
|
+
signature,
|
|
101
|
+
action: 'steer',
|
|
102
|
+
steeringMessage: this.config.steeringMessage,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (identicalCount === this.config.maxIdenticalCalls - 1) {
|
|
106
|
+
return {
|
|
107
|
+
isLoop: false,
|
|
108
|
+
callCount: identicalCount,
|
|
109
|
+
signature,
|
|
110
|
+
action: 'warn',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
isLoop: false,
|
|
115
|
+
callCount: identicalCount,
|
|
116
|
+
signature,
|
|
117
|
+
action: 'allow',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get metrics about loop detection activity.
|
|
122
|
+
*/
|
|
123
|
+
getMetrics() {
|
|
124
|
+
return {
|
|
125
|
+
totalCallsTracked: this.totalCallsTracked,
|
|
126
|
+
loopsDetected: this.loopsDetected,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Clear all tracking state.
|
|
131
|
+
*/
|
|
132
|
+
clear() {
|
|
133
|
+
this.callHistory.clear();
|
|
134
|
+
this.totalCallsTracked = 0;
|
|
135
|
+
this.loopsDetected = 0;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create a ToolCallSignature from tool name and arguments.
|
|
139
|
+
*/
|
|
140
|
+
createSignature(toolName, args) {
|
|
141
|
+
const serializedArgs = JSON.stringify(args ?? '');
|
|
142
|
+
const argsFingerprint = fnv1aHash(serializedArgs);
|
|
143
|
+
const combinedInput = `${toolName}:${serializedArgs}`;
|
|
144
|
+
const hash = fnv1aHash(combinedInput);
|
|
145
|
+
return {
|
|
146
|
+
hash,
|
|
147
|
+
toolName,
|
|
148
|
+
argsFingerprint,
|
|
149
|
+
timestamp: Date.now(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** Default cosine-distance thresholds per event category. */
|
|
154
|
+
const DEFAULT_THRESHOLDS = {
|
|
155
|
+
'quality-gate': 0.05, // tight
|
|
156
|
+
'coverage': 0.10, // moderate
|
|
157
|
+
'test-generation': 0.15, // relaxed
|
|
158
|
+
'learning': 0.20, // most relaxed
|
|
159
|
+
'default': 0.12,
|
|
160
|
+
};
|
|
161
|
+
const DEFAULT_CONFIG = {
|
|
162
|
+
thresholds: DEFAULT_THRESHOLDS,
|
|
163
|
+
agentId: 'unknown',
|
|
164
|
+
maxHistorySize: 200,
|
|
165
|
+
fallbackDimension: 64,
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Deterministic pseudo-embedding via FNV-1a-inspired hash spread.
|
|
169
|
+
* Not semantically meaningful but sufficient for detecting payload mutations.
|
|
170
|
+
* @param text - Input text to embed.
|
|
171
|
+
* @param dim - Desired vector dimensionality.
|
|
172
|
+
* @returns A normalised float vector of length `dim`.
|
|
173
|
+
*/
|
|
174
|
+
function hashBasedEmbedding(text, dim) {
|
|
175
|
+
const vec = new Float64Array(dim);
|
|
176
|
+
let h1 = 0x811c9dc5;
|
|
177
|
+
let h2 = 0x01000193;
|
|
178
|
+
for (let i = 0; i < text.length; i++) {
|
|
179
|
+
const c = text.charCodeAt(i);
|
|
180
|
+
h1 ^= c;
|
|
181
|
+
h1 = Math.imul(h1, 0x01000193);
|
|
182
|
+
h2 ^= c;
|
|
183
|
+
h2 = Math.imul(h2, 0x811c9dc5);
|
|
184
|
+
const idx = (h1 >>> 0) % dim;
|
|
185
|
+
vec[idx] += ((h2 >>> 0) / 0xffffffff) * 2 - 1;
|
|
186
|
+
}
|
|
187
|
+
let norm = 0;
|
|
188
|
+
for (let i = 0; i < dim; i++)
|
|
189
|
+
norm += vec[i] * vec[i];
|
|
190
|
+
norm = Math.sqrt(norm);
|
|
191
|
+
const result = new Array(dim);
|
|
192
|
+
for (let i = 0; i < dim; i++)
|
|
193
|
+
result[i] = norm === 0 ? 0 : vec[i] / norm;
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
// Transformer availability probe (lazy, cached)
|
|
197
|
+
let _transformerProbed = false;
|
|
198
|
+
let _transformerAvailable = false;
|
|
199
|
+
let _computeRealEmbedding = null;
|
|
200
|
+
/** Lazily probe whether the transformer pipeline is usable. */
|
|
201
|
+
async function probeTransformer() {
|
|
202
|
+
if (_transformerProbed)
|
|
203
|
+
return _transformerAvailable;
|
|
204
|
+
_transformerProbed = true;
|
|
205
|
+
try {
|
|
206
|
+
const mod = await import('../learning/real-embeddings.js');
|
|
207
|
+
if (typeof mod.isTransformerAvailable === 'function' && mod.isTransformerAvailable()) {
|
|
208
|
+
_computeRealEmbedding = mod.computeRealEmbedding;
|
|
209
|
+
_transformerAvailable = true;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
try {
|
|
213
|
+
await mod.computeRealEmbedding('probe');
|
|
214
|
+
_computeRealEmbedding = mod.computeRealEmbedding;
|
|
215
|
+
_transformerAvailable = true;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
_transformerAvailable = false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
_transformerAvailable = false;
|
|
224
|
+
}
|
|
225
|
+
return _transformerAvailable;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Middleware enforcing semantic stability of domain events across agent-hop
|
|
229
|
+
* boundaries. `onEmit` computes an embedding and attaches a SemanticFingerprint;
|
|
230
|
+
* `onReceive` re-embeds and checks cosine distance, dropping drifted events.
|
|
231
|
+
*/
|
|
232
|
+
export class SemanticAntiDriftMiddleware {
|
|
233
|
+
name = 'semantic-anti-drift';
|
|
234
|
+
priority = 10;
|
|
235
|
+
config;
|
|
236
|
+
history = [];
|
|
237
|
+
totalChecked = 0;
|
|
238
|
+
driftCount = 0;
|
|
239
|
+
similaritySum = 0;
|
|
240
|
+
constructor(config) {
|
|
241
|
+
this.config = {
|
|
242
|
+
...DEFAULT_CONFIG,
|
|
243
|
+
...config,
|
|
244
|
+
thresholds: { ...DEFAULT_THRESHOLDS, ...config?.thresholds },
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Compute the semantic embedding of the event payload and attach a
|
|
249
|
+
* {@link SemanticFingerprint} before publication.
|
|
250
|
+
* @param event - The domain event about to be published.
|
|
251
|
+
* @returns The event augmented with a `semanticFingerprint` field.
|
|
252
|
+
*/
|
|
253
|
+
async onEmit(event) {
|
|
254
|
+
const payloadText = JSON.stringify(event.payload);
|
|
255
|
+
const embedding = await this.embed(payloadText);
|
|
256
|
+
const category = this.resolveCategory(event.type);
|
|
257
|
+
const threshold = this.config.thresholds[category] ?? this.config.thresholds['default'];
|
|
258
|
+
const fingerprint = {
|
|
259
|
+
embedding,
|
|
260
|
+
driftThreshold: threshold,
|
|
261
|
+
sourceAgentId: this.config.agentId,
|
|
262
|
+
hopCount: 0,
|
|
263
|
+
emittedAt: Date.now(),
|
|
264
|
+
};
|
|
265
|
+
return { ...event, semanticFingerprint: fingerprint };
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Re-embed the payload and compare with the original fingerprint.
|
|
269
|
+
* If drift exceeds threshold the event is dropped (returns null) and a
|
|
270
|
+
* SemanticDriftDetectedEvent is emitted. Events without a fingerprint
|
|
271
|
+
* pass through unchanged.
|
|
272
|
+
* @param event - The incoming domain event.
|
|
273
|
+
* @returns The event with incremented hopCount, or null if drifted.
|
|
274
|
+
*/
|
|
275
|
+
async onReceive(event) {
|
|
276
|
+
const fp = event.semanticFingerprint;
|
|
277
|
+
if (!fp)
|
|
278
|
+
return event;
|
|
279
|
+
const payloadText = JSON.stringify(event.payload);
|
|
280
|
+
const currentEmbedding = await this.embed(payloadText);
|
|
281
|
+
const similarity = cosineSimilarity(currentEmbedding, fp.embedding);
|
|
282
|
+
const distance = 1 - similarity;
|
|
283
|
+
const drifted = distance > fp.driftThreshold;
|
|
284
|
+
this.totalChecked++;
|
|
285
|
+
this.similaritySum += similarity;
|
|
286
|
+
const checkResult = {
|
|
287
|
+
drifted,
|
|
288
|
+
cosineSimilarity: similarity,
|
|
289
|
+
threshold: fp.driftThreshold,
|
|
290
|
+
eventType: event.type,
|
|
291
|
+
hopCount: fp.hopCount + 1,
|
|
292
|
+
checkedAt: Date.now(),
|
|
293
|
+
};
|
|
294
|
+
this.history.push(checkResult);
|
|
295
|
+
if (this.history.length > this.config.maxHistorySize)
|
|
296
|
+
this.history.shift();
|
|
297
|
+
if (drifted) {
|
|
298
|
+
this.driftCount++;
|
|
299
|
+
await this.emitDriftEvent(event, checkResult);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const updatedFingerprint = { ...fp, hopCount: fp.hopCount + 1 };
|
|
303
|
+
return { ...event, semanticFingerprint: updatedFingerprint };
|
|
304
|
+
}
|
|
305
|
+
/** Returns recent drift check results (bounded by maxHistorySize). */
|
|
306
|
+
getDriftHistory() {
|
|
307
|
+
return this.history;
|
|
308
|
+
}
|
|
309
|
+
/** Aggregated statistics about drift checks performed so far. */
|
|
310
|
+
getStats() {
|
|
311
|
+
return {
|
|
312
|
+
totalChecked: this.totalChecked,
|
|
313
|
+
driftCount: this.driftCount,
|
|
314
|
+
averageSimilarity: this.totalChecked > 0 ? this.similaritySum / this.totalChecked : 0,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Validate the middleware configuration.
|
|
319
|
+
* @returns ok(void) if valid, err(Error) otherwise.
|
|
320
|
+
*/
|
|
321
|
+
validateConfig() {
|
|
322
|
+
for (const [key, value] of Object.entries(this.config.thresholds)) {
|
|
323
|
+
if (typeof value !== 'number' || value < 0 || value > 1) {
|
|
324
|
+
return err(new Error(`Invalid threshold for "${key}": must be between 0 and 1, got ${value}`));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (this.config.maxHistorySize <= 0)
|
|
328
|
+
return err(new Error('maxHistorySize must be positive'));
|
|
329
|
+
if (this.config.fallbackDimension <= 0)
|
|
330
|
+
return err(new Error('fallbackDimension must be positive'));
|
|
331
|
+
return ok(undefined);
|
|
332
|
+
}
|
|
333
|
+
/** Compute embedding, preferring transformer pipeline with hash fallback. */
|
|
334
|
+
async embed(text) {
|
|
335
|
+
const hasTransformer = await probeTransformer();
|
|
336
|
+
if (hasTransformer && _computeRealEmbedding)
|
|
337
|
+
return _computeRealEmbedding(text);
|
|
338
|
+
return hashBasedEmbedding(text, this.config.fallbackDimension);
|
|
339
|
+
}
|
|
340
|
+
/** Map event type to threshold category via substring matching. */
|
|
341
|
+
resolveCategory(eventType) {
|
|
342
|
+
const lower = eventType.toLowerCase();
|
|
343
|
+
for (const category of Object.keys(this.config.thresholds)) {
|
|
344
|
+
if (category !== 'default' && lower.includes(category))
|
|
345
|
+
return category;
|
|
346
|
+
}
|
|
347
|
+
return 'default';
|
|
348
|
+
}
|
|
349
|
+
/** Fire a SemanticDriftDetectedEvent via the configured callback. */
|
|
350
|
+
async emitDriftEvent(originalEvent, check) {
|
|
351
|
+
if (!this.config.onDriftDetected)
|
|
352
|
+
return;
|
|
353
|
+
const driftEvent = {
|
|
354
|
+
id: `drift-${originalEvent.id}-${Date.now()}`,
|
|
355
|
+
type: 'SemanticDriftDetected',
|
|
356
|
+
timestamp: new Date(),
|
|
357
|
+
source: originalEvent.source,
|
|
358
|
+
correlationId: originalEvent.correlationId,
|
|
359
|
+
payload: {
|
|
360
|
+
originalEventId: originalEvent.id,
|
|
361
|
+
originalEventType: originalEvent.type,
|
|
362
|
+
cosineSimilarity: check.cosineSimilarity,
|
|
363
|
+
threshold: check.threshold,
|
|
364
|
+
hopCount: check.hopCount,
|
|
365
|
+
agentId: this.config.agentId,
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
try {
|
|
369
|
+
await this.config.onDriftDetected(driftEvent);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// Swallow callback errors to avoid disrupting the pipeline.
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=anti-drift-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anti-drift-middleware.js","sourceRoot":"","sources":["../../src/kernel/anti-drift-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAqClE,4CAA4C;AAC5C,MAAM,6BAA6B,GAAwB;IACzD,iBAAiB,EAAE,CAAC;IACpB,QAAQ,EAAE,KAAK;IACf,eAAe,EAAE,+HAA+H;IAChJ,mBAAmB,EAAE,KAAK;CAC3B,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,IAAI,GAAG,UAAU,CAAC,CAAC,mBAAmB;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY;IAClD,CAAC;IACD,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,wBAAwB;IAClB,MAAM,CAAsB;IAC5B,WAAW,GAAqC,IAAI,GAAG,EAAE,CAAC;IACnE,iBAAiB,GAAG,CAAC,CAAC;IACtB,aAAa,GAAG,CAAC,CAAC;IAE1B,YAAY,MAAqC;QAC/C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,6BAA6B,EAAE,GAAG,MAAM,EAAE,CAAC;IAChE,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,OAAe,EAAE,QAAgB,EAAE,IAAa;QACxD,qBAAqB;QACrB,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,OAAO,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACvD,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,CAAC;gBACZ,SAAS;gBACT,MAAM,EAAE,OAAO;aAChB,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;QAE/C,8BAA8B;QAC9B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAExB,yCAAyC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACjD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;QACjE,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7B,0BAA0B;YAC1B,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,0CAA0C;QAC1C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAE7E,yCAAyC;QACzC,IAAI,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACpD,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,cAAc;gBACzB,SAAS;gBACT,MAAM,EAAE,OAAO;gBACf,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;aAC7C,CAAC;QACJ,CAAC;QAED,IAAI,cAAc,KAAK,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;YACzD,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,cAAc;gBACzB,SAAS;gBACT,MAAM,EAAE,MAAM;aACf,CAAC;QACJ,CAAC;QAED,OAAO;YACL,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,cAAc;YACzB,SAAS;YACT,MAAM,EAAE,OAAO;SAChB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO;YACL,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,QAAgB,EAAE,IAAa;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,GAAG,QAAQ,IAAI,cAAc,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;QAEtC,OAAO;YACL,IAAI;YACJ,QAAQ;YACR,eAAe;YACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;CACF;AA2CD,6DAA6D;AAC7D,MAAM,kBAAkB,GAA2B;IACjD,cAAc,EAAE,IAAI,EAAK,QAAQ;IACjC,UAAU,EAAE,IAAI,EAAS,WAAW;IACpC,iBAAiB,EAAE,IAAI,EAAE,UAAU;IACnC,UAAU,EAAE,IAAI,EAAS,eAAe;IACxC,SAAS,EAAE,IAAI;CAChB,CAAC;AAEF,MAAM,cAAc,GAAoB;IACtC,UAAU,EAAE,kBAAkB;IAC9B,OAAO,EAAE,SAAS;IAClB,cAAc,EAAE,GAAG;IACnB,iBAAiB,EAAE,EAAE;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,IAAY,EAAE,GAAW;IACnD,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC7B,EAAE,IAAI,CAAC,CAAC;QACR,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC/B,EAAE,IAAI,CAAC,CAAC;QACR,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC;QAC7B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;QAAE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,MAAM,GAAa,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACzE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gDAAgD;AAChD,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAC/B,IAAI,qBAAqB,GAAG,KAAK,CAAC;AAClC,IAAI,qBAAqB,GAAiD,IAAI,CAAC;AAE/E,+DAA+D;AAC/D,KAAK,UAAU,gBAAgB;IAC7B,IAAI,kBAAkB;QAAE,OAAO,qBAAqB,CAAC;IACrD,kBAAkB,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;QAC3D,IAAI,OAAO,GAAG,CAAC,sBAAsB,KAAK,UAAU,IAAI,GAAG,CAAC,sBAAsB,EAAE,EAAE,CAAC;YACrF,qBAAqB,GAAG,GAAG,CAAC,oBAAoB,CAAC;YACjD,qBAAqB,GAAG,IAAI,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;gBACxC,qBAAqB,GAAG,GAAG,CAAC,oBAAoB,CAAC;gBACjD,qBAAqB,GAAG,IAAI,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB,GAAG,KAAK,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB,GAAG,KAAK,CAAC;IAChC,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,2BAA2B;IAC7B,IAAI,GAAG,qBAAqB,CAAC;IAC7B,QAAQ,GAAG,EAAE,CAAC;IACN,MAAM,CAAkB;IACxB,OAAO,GAAuB,EAAE,CAAC;IAC1C,YAAY,GAAG,CAAC,CAAC;IACjB,UAAU,GAAG,CAAC,CAAC;IACf,aAAa,GAAG,CAAC,CAAC;IAE1B,YAAY,MAAiC;QAC3C,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,cAAc;YACjB,GAAG,MAAM;YACT,UAAU,EAAE,EAAE,GAAG,kBAAkB,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE;SAC7D,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,KAAkB;QAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACxF,MAAM,WAAW,GAAwB;YACvC,SAAS;YACT,cAAc,EAAE,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAClC,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,OAAO,EAAE,GAAG,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAiB,CAAC;IACvE,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,SAAS,CAAC,KAAkB;QAChC,MAAM,EAAE,GAAG,KAAK,CAAC,mBAAmB,CAAC;QACrC,IAAI,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAEtB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAgB,EAAE,EAAE,CAAC,SAAqB,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,CAAC,GAAG,UAAU,CAAC;QAChC,MAAM,OAAO,GAAG,QAAQ,GAAG,EAAE,CAAC,cAAc,CAAC;QAE7C,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,aAAa,IAAI,UAAU,CAAC;QAEjC,MAAM,WAAW,GAAqB;YACpC,OAAO;YACP,gBAAgB,EAAE,UAAU;YAC5B,SAAS,EAAE,EAAE,CAAC,cAAc;YAC5B,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,CAAC;YACzB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAE3E,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,kBAAkB,GAAwB,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACrF,OAAO,EAAE,GAAG,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAiB,CAAC;IAC9E,CAAC;IAED,sEAAsE;IACtE,eAAe;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,iEAAiE;IACjE,QAAQ;QACN,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,iBAAiB,EAAE,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACtF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACxD,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,0BAA0B,GAAG,mCAAmC,KAAK,EAAE,CAAC,CAAC,CAAC;YACjG,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC9F,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;QACpG,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED,6EAA6E;IACrE,KAAK,CAAC,KAAK,CAAC,IAAY;QAC9B,MAAM,cAAc,GAAG,MAAM,gBAAgB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,qBAAqB;YAAE,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAChF,OAAO,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACjE,CAAC;IAED,mEAAmE;IAC3D,eAAe,CAAC,SAAiB;QACvC,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACtC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3D,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAC;QAC1E,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,qEAAqE;IAC7D,KAAK,CAAC,cAAc,CAAC,aAA0B,EAAE,KAAuB;QAC9E,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe;YAAE,OAAO;QACzC,MAAM,UAAU,GAAgB;YAC9B,EAAE,EAAE,SAAS,aAAa,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YAC7C,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,aAAa,EAAE,aAAa,CAAC,aAAa;YAC1C,OAAO,EAAE;gBACP,eAAe,EAAE,aAAa,CAAC,EAAE;gBACjC,iBAAiB,EAAE,aAAa,CAAC,IAAI;gBACrC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;gBACxC,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;aAC7B;SACF,CAAC;QACF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;QAC9D,CAAC;IACH,CAAC;CACF"}
|
|
@@ -7,7 +7,21 @@
|
|
|
7
7
|
* - Subscription indexes for O(1) lookup (replaces O(n) filter)
|
|
8
8
|
*/
|
|
9
9
|
import { DomainEvent, DomainName, EventHandler } from '../shared/types';
|
|
10
|
-
import { EventBus, Subscription, EventFilter } from './interfaces';
|
|
10
|
+
import { EventBus, Subscription, EventFilter, EventMiddleware } from './interfaces';
|
|
11
|
+
/**
|
|
12
|
+
* Event type constants for loop detection (ADR-062).
|
|
13
|
+
*
|
|
14
|
+
* - `loop.warning` - Emitted on strike 2 (second identical tool call in window)
|
|
15
|
+
* - `loop.detected` - Emitted on strike 3+ (loop confirmed, steering injected)
|
|
16
|
+
*
|
|
17
|
+
* Payload shape: LoopDetectionResult from anti-drift-middleware.ts
|
|
18
|
+
*/
|
|
19
|
+
export declare const LOOP_EVENT_TYPES: {
|
|
20
|
+
/** Emitted on strike 2: second identical tool call within the sliding window. */
|
|
21
|
+
LOOP_WARNING: "loop.warning";
|
|
22
|
+
/** Emitted on strike 3+: loop confirmed, steering message injected. */
|
|
23
|
+
LOOP_DETECTED: "loop.detected";
|
|
24
|
+
};
|
|
11
25
|
export declare class InMemoryEventBus implements EventBus {
|
|
12
26
|
private subscriptions;
|
|
13
27
|
private subscriptionsByEventType;
|
|
@@ -16,7 +30,21 @@ export declare class InMemoryEventBus implements EventBus {
|
|
|
16
30
|
private eventHistory;
|
|
17
31
|
private maxHistorySize;
|
|
18
32
|
private subscriptionCounter;
|
|
33
|
+
private middlewares;
|
|
19
34
|
constructor(maxHistorySize?: 10000);
|
|
35
|
+
/**
|
|
36
|
+
* ADR-060: Register an event middleware
|
|
37
|
+
* Middlewares are sorted by priority (lower runs first)
|
|
38
|
+
*/
|
|
39
|
+
registerMiddleware(middleware: EventMiddleware): void;
|
|
40
|
+
/**
|
|
41
|
+
* ADR-060: Remove an event middleware by name
|
|
42
|
+
*/
|
|
43
|
+
removeMiddleware(name: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* ADR-060: Get registered middlewares
|
|
46
|
+
*/
|
|
47
|
+
getMiddlewares(): readonly EventMiddleware[];
|
|
20
48
|
publish<T>(event: DomainEvent<T>): Promise<void>;
|
|
21
49
|
subscribe<T>(eventType: string, handler: EventHandler<T>): Subscription;
|
|
22
50
|
subscribeToChannel(domain: DomainName, handler: EventHandler): Subscription;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/kernel/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/kernel/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQpF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;IAC3B,iFAAiF;;IAEjF,uEAAuE;;CAExE,CAAC;AAUF,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,OAAO,CAAC,aAAa,CAA6C;IAGlE,OAAO,CAAC,wBAAwB,CAAuC;IACvE,OAAO,CAAC,sBAAsB,CAA2C;IACzE,OAAO,CAAC,qBAAqB,CAA0B;IAGvD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,mBAAmB,CAAK;IAGhC,OAAO,CAAC,WAAW,CAAyB;gBAEhC,cAAc,QAAuC;IAKjE;;;OAGG;IACH,kBAAkB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAKrD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IASvC;;OAEG;IACH,cAAc,IAAI,SAAS,eAAe,EAAE;IAItC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmEtD,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY;IAqCvE,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;IA8BrE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA4BxD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ/B"}
|