mcp-event-intelligence 0.5.0 → 0.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/CHANGELOG.md +41 -0
- package/README.md +31 -38
- package/SECURITY.md +4 -4
- package/bin/mcp-event-intelligence.mjs +2 -2
- package/dist/src/composite/engine.d.ts +11 -7
- package/dist/src/composite/engine.js +150 -414
- package/dist/src/composite/matching.d.ts +1 -5
- package/dist/src/composite/matching.js +0 -54
- package/dist/src/composite/runtimeSupport.js +10 -6
- package/dist/src/composite/store.d.ts +38 -4
- package/dist/src/composite/temporal.d.ts +0 -17
- package/dist/src/composite/temporal.js +0 -266
- package/dist/src/intelligenceProtocol/activationSchemas.d.ts +36 -3
- package/dist/src/intelligenceProtocol/activationSchemas.js +4 -3
- package/dist/src/intelligenceProtocol/index.d.ts +8 -12
- package/dist/src/intelligenceProtocol/index.js +4 -7
- package/dist/src/intelligenceProtocol/lifecycle.js +2 -10
- package/dist/src/intelligenceProtocol/operatorRegistry.d.ts +3 -270
- package/dist/src/intelligenceProtocol/operatorRegistry.js +5 -144
- package/dist/src/intelligenceProtocol/schemas.d.ts +0 -189
- package/dist/src/intelligenceProtocol/schemas.js +1 -97
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.d.ts +5 -102
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.js +2 -26
- package/dist/src/intelligenceProtocol/triggerSchemas.d.ts +14 -215
- package/dist/src/intelligenceProtocol/triggerSchemas.js +18 -191
- package/dist/src/intelligenceProtocol/version.d.ts +2 -2
- package/dist/src/intelligenceProtocol/version.js +2 -2
- package/dist/src/patternV2/evaluator.d.ts +9 -1
- package/dist/src/patternV2/evaluator.js +63 -4
- package/dist/src/semantic/types.d.ts +6 -0
- package/dist/src/semantic/typesafeJevEvaluator.d.ts +1 -0
- package/dist/src/semantic/typesafeJevEvaluator.js +6 -0
- package/package.json +5 -2
- package/scripts/host-integration.d.mts +48 -5
- package/scripts/host-integration.mjs +16 -4
- package/scripts/lib/activation-hydrator.mjs +12 -12
- package/scripts/lib/composite-event-consumer.mjs +8 -28
- package/scripts/lib/composite-wake-coordinator.mjs +19 -19
- package/scripts/lib/derived-contract-registry.mjs +4 -4
- package/scripts/lib/derived-event-coordinator.mjs +11 -22
- package/scripts/lib/local-event-intelligence-runtime.mjs +35 -3
- package/scripts/lib/mcp-events-client.mjs +36 -32
- package/scripts/lib/persistent-event-store.mjs +228 -61
- package/scripts/lib/store-capabilities.mjs +88 -0
- package/scripts/lib/store-conformance.mjs +127 -0
- package/scripts/lib/temporal-deadline-scheduler.mjs +3 -3
- package/scripts/lib/trigger-control-plane.mjs +52 -57
- package/scripts/lib/trigger-inspector.mjs +48 -160
- package/scripts/lib/trigger-planner.mjs +37 -126
- package/scripts/lib/wake-retry-scheduler.mjs +2 -19
- package/scripts/mcp-stdio-server.mjs +8 -8
- package/scripts/service.mjs +19 -138
- package/server.json +3 -3
- package/dist/src/intelligenceProtocol/invariants.d.ts +0 -3
- package/dist/src/intelligenceProtocol/invariants.js +0 -36
- package/dist/src/intelligenceProtocol/mapper.d.ts +0 -14
- package/dist/src/intelligenceProtocol/mapper.js +0 -28
- package/dist/src/patternV2/legacyCompiler.d.ts +0 -3
- package/dist/src/patternV2/legacyCompiler.js +0 -184
- package/scripts/lib/event-processor.mjs +0 -624
- package/scripts/lib/http-wake-deliverer.mjs +0 -31
|
@@ -2,9 +2,6 @@ import {
|
|
|
2
2
|
parseDerivedEventRecord,
|
|
3
3
|
sha256Hex,
|
|
4
4
|
} from '../../dist/src/intelligenceProtocol/index.js';
|
|
5
|
-
import {
|
|
6
|
-
evaluateTemporalConditions,
|
|
7
|
-
} from '../../dist/src/composite/temporal.js';
|
|
8
5
|
import {
|
|
9
6
|
evaluatePatternMeasure,
|
|
10
7
|
} from '../../dist/src/patternV2/evaluator.js';
|
|
@@ -92,22 +89,14 @@ function patternCandidateForMatch(match) {
|
|
|
92
89
|
};
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
function derivedOccurredAt(match
|
|
92
|
+
function derivedOccurredAt(match) {
|
|
93
|
+
if (match.patternState?.completedAt) {
|
|
94
|
+
return match.patternState.completedAt;
|
|
95
|
+
}
|
|
96
|
+
|
|
96
97
|
const candidates = match.sourceEvents
|
|
97
98
|
.map((event) => Date.parse(event.occurredAt))
|
|
98
99
|
.filter(Number.isFinite);
|
|
99
|
-
|
|
100
|
-
const temporal = evaluateTemporalConditions(
|
|
101
|
-
definition,
|
|
102
|
-
match,
|
|
103
|
-
new Date(match.updatedAt),
|
|
104
|
-
);
|
|
105
|
-
for (const state of temporal.conditionStates) {
|
|
106
|
-
if (state.status !== 'satisfied' || !state.dueAt) continue;
|
|
107
|
-
const dueAt = Date.parse(state.dueAt);
|
|
108
|
-
if (Number.isFinite(dueAt)) candidates.push(dueAt);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
100
|
if (!candidates.length) return match.updatedAt;
|
|
112
101
|
return new Date(Math.max(...candidates)).toISOString();
|
|
113
102
|
}
|
|
@@ -141,7 +130,7 @@ export class DerivedEventCoordinator {
|
|
|
141
130
|
})
|
|
142
131
|
).slice(0, 24)}`;
|
|
143
132
|
|
|
144
|
-
const existing = this.store.getDerivedEvent(
|
|
133
|
+
const existing = await this.store.getDerivedEvent(
|
|
145
134
|
eventId,
|
|
146
135
|
DERIVED_EVENT_SERVER_ID,
|
|
147
136
|
);
|
|
@@ -162,7 +151,7 @@ export class DerivedEventCoordinator {
|
|
|
162
151
|
const rootEvidence = [];
|
|
163
152
|
for (const source of match.sourceEvents) {
|
|
164
153
|
if (source.serverId === DERIVED_EVENT_SERVER_ID) {
|
|
165
|
-
const parent = this.store.getDerivedEvent(
|
|
154
|
+
const parent = await this.store.getDerivedEvent(
|
|
166
155
|
source.sourceEventId,
|
|
167
156
|
DERIVED_EVENT_SERVER_ID,
|
|
168
157
|
);
|
|
@@ -219,7 +208,7 @@ export class DerivedEventCoordinator {
|
|
|
219
208
|
}
|
|
220
209
|
}
|
|
221
210
|
|
|
222
|
-
const contract = this.store.getDerivedContract(
|
|
211
|
+
const contract = await this.store.getDerivedContract(
|
|
223
212
|
spec.name,
|
|
224
213
|
spec.contractVersion,
|
|
225
214
|
);
|
|
@@ -239,7 +228,7 @@ export class DerivedEventCoordinator {
|
|
|
239
228
|
triggerId: definition.triggerId,
|
|
240
229
|
triggerVersion: definition.version,
|
|
241
230
|
matchId: match.matchId,
|
|
242
|
-
|
|
231
|
+
partitionKey: match.partitionKey,
|
|
243
232
|
contractVersion: spec.contractVersion,
|
|
244
233
|
schemaFingerprint: contract.schemaFingerprint,
|
|
245
234
|
},
|
|
@@ -249,7 +238,7 @@ export class DerivedEventCoordinator {
|
|
|
249
238
|
traceId: `derived:${eventId}`,
|
|
250
239
|
sourceEventId: eventId,
|
|
251
240
|
name: spec.name,
|
|
252
|
-
occurredAt: derivedOccurredAt(match
|
|
241
|
+
occurredAt: derivedOccurredAt(match),
|
|
253
242
|
receivedAt: this.now().toISOString(),
|
|
254
243
|
provider: 'event-intelligence',
|
|
255
244
|
serverId: DERIVED_EVENT_SERVER_ID,
|
|
@@ -296,7 +285,7 @@ export class DerivedEventCoordinator {
|
|
|
296
285
|
await sha256Hex({
|
|
297
286
|
kind,
|
|
298
287
|
sourceEventId: record.event.sourceEventId,
|
|
299
|
-
sequence: this.store.auditLength(),
|
|
288
|
+
sequence: await this.store.auditLength(),
|
|
300
289
|
})
|
|
301
290
|
).slice(0, 24)}`,
|
|
302
291
|
traceId: record.event.traceId,
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
PersistentEventStore,
|
|
27
27
|
normalizeEventScopeId,
|
|
28
28
|
} from './persistent-event-store.mjs';
|
|
29
|
+
import {
|
|
30
|
+
assertSharedStoreCapabilities,
|
|
31
|
+
describeStoreCapabilities,
|
|
32
|
+
} from './store-capabilities.mjs';
|
|
29
33
|
import {
|
|
30
34
|
TriggerInspector,
|
|
31
35
|
} from './trigger-inspector.mjs';
|
|
@@ -114,6 +118,23 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
114
118
|
const dataDir = env.DATA_DIR ?? './data';
|
|
115
119
|
const rootStore = providedStore ?? new PersistentEventStore(dataDir);
|
|
116
120
|
const restored = await initializeStore(rootStore);
|
|
121
|
+
const storeCapabilities = describeStoreCapabilities(rootStore);
|
|
122
|
+
const requireSharedStore =
|
|
123
|
+
env.EVENT_INTELLIGENCE_REQUIRE_SHARED_STORE === 'true';
|
|
124
|
+
if (requireSharedStore) {
|
|
125
|
+
assertSharedStoreCapabilities(rootStore);
|
|
126
|
+
if (!String(env.EVENT_INTELLIGENCE_WORKER_ID || '').trim()) {
|
|
127
|
+
const error = new Error(
|
|
128
|
+
'EVENT_INTELLIGENCE_WORKER_ID is required in shared-store mode',
|
|
129
|
+
);
|
|
130
|
+
error.code = 'EVENT_INTELLIGENCE_WORKER_ID_REQUIRED';
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const rootWorkerId = String(
|
|
135
|
+
env.EVENT_INTELLIGENCE_WORKER_ID ||
|
|
136
|
+
`ei-${process.pid}`,
|
|
137
|
+
).trim();
|
|
117
138
|
|
|
118
139
|
const evaluator =
|
|
119
140
|
semanticEvaluator !== undefined
|
|
@@ -161,7 +182,17 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
161
182
|
assertStoreContract(store);
|
|
162
183
|
}
|
|
163
184
|
|
|
164
|
-
const triggerEngine = new CompositeTriggerEngine(
|
|
185
|
+
const triggerEngine = new CompositeTriggerEngine(
|
|
186
|
+
store,
|
|
187
|
+
evaluator,
|
|
188
|
+
undefined,
|
|
189
|
+
{
|
|
190
|
+
workerId: `${rootWorkerId}:${scopeId}`,
|
|
191
|
+
partitionLeaseMs: Number(
|
|
192
|
+
env.EVENT_INTELLIGENCE_PARTITION_LEASE_MS ?? 300000,
|
|
193
|
+
),
|
|
194
|
+
},
|
|
195
|
+
);
|
|
165
196
|
const triggerPlanner = new TriggerPlanner({ store });
|
|
166
197
|
const activationHydrator = new ActivationHydrator({ store });
|
|
167
198
|
const wakeCoordinators = new Map();
|
|
@@ -195,7 +226,7 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
195
226
|
packetBuilder,
|
|
196
227
|
...deliveryOptions,
|
|
197
228
|
deliverer: async (packet) => {
|
|
198
|
-
const activation = activationHydrator.hydrateWake(packet.wake_id);
|
|
229
|
+
const activation = await activationHydrator.hydrateWake(packet.wake_id);
|
|
199
230
|
const result = await handler(packet, activation);
|
|
200
231
|
if (typeof result === 'string' && result) {
|
|
201
232
|
return { runtimeReceiptId: result };
|
|
@@ -224,7 +255,7 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
224
255
|
packetBuilder,
|
|
225
256
|
...deliveryOptions,
|
|
226
257
|
deliverer: async (packet) => {
|
|
227
|
-
const activation = activationHydrator.hydrateWake(packet.wake_id);
|
|
258
|
+
const activation = await activationHydrator.hydrateWake(packet.wake_id);
|
|
228
259
|
const result = await wake(packet, activation);
|
|
229
260
|
if (typeof result === 'string' && result) {
|
|
230
261
|
return { runtimeReceiptId: result };
|
|
@@ -330,6 +361,7 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
330
361
|
|
|
331
362
|
return {
|
|
332
363
|
restored,
|
|
364
|
+
storeCapabilities,
|
|
333
365
|
store: defaultContext.store,
|
|
334
366
|
evaluator,
|
|
335
367
|
triggerEngine: defaultContext.triggerEngine,
|
|
@@ -394,7 +394,7 @@ export class McpEventsClientManager {
|
|
|
394
394
|
}
|
|
395
395
|
const removed = this.connections.delete(connectionId);
|
|
396
396
|
if (removed && context) {
|
|
397
|
-
const sources = context.store.listEventSources({
|
|
397
|
+
const sources = await context.store.listEventSources({
|
|
398
398
|
connectionIds: [connectionId],
|
|
399
399
|
});
|
|
400
400
|
for (const source of sources) {
|
|
@@ -486,9 +486,9 @@ export class McpEventsClientManager {
|
|
|
486
486
|
for (const normalized of descriptors) {
|
|
487
487
|
const sourceId =
|
|
488
488
|
`mcp:${connection.connectionId}:${normalized.name}`;
|
|
489
|
-
const existing =
|
|
490
|
-
.listEventSources()
|
|
491
|
-
|
|
489
|
+
const existing = (
|
|
490
|
+
await context.store.listEventSources()
|
|
491
|
+
).find((source) => source.sourceId === sourceId);
|
|
492
492
|
const same =
|
|
493
493
|
existing &&
|
|
494
494
|
existing.enabled !== false &&
|
|
@@ -571,25 +571,26 @@ export class McpEventsClientManager {
|
|
|
571
571
|
return results;
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
-
desiredSubscriptions(connection, context) {
|
|
574
|
+
async desiredSubscriptions(connection, context) {
|
|
575
575
|
const descriptors = this.descriptors.get(connection.connectionId) || [];
|
|
576
576
|
const byName = new Map(descriptors.map((item) => [item.name, item]));
|
|
577
577
|
const desired = new Map();
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
578
|
+
let triggers = [];
|
|
579
|
+
if (typeof context.triggerControl?.listTriggers === 'function') {
|
|
580
|
+
triggers = await context.triggerControl.listTriggers();
|
|
581
|
+
} else if (typeof context.store?.listTriggers === 'function') {
|
|
582
|
+
const definitions = await context.store.listTriggers();
|
|
583
|
+
triggers = await Promise.all(definitions.map(async (definition) => ({
|
|
584
|
+
definition,
|
|
585
|
+
state:
|
|
586
|
+
typeof context.store.getTriggerState === 'function'
|
|
587
|
+
? await context.store.getTriggerState(
|
|
588
|
+
definition.triggerId,
|
|
589
|
+
definition.version,
|
|
590
|
+
)
|
|
591
|
+
: null,
|
|
592
|
+
})));
|
|
593
|
+
}
|
|
593
594
|
|
|
594
595
|
for (const { definition, state } of triggers) {
|
|
595
596
|
if (state?.status !== 'active') continue;
|
|
@@ -664,7 +665,7 @@ export class McpEventsClientManager {
|
|
|
664
665
|
subscription,
|
|
665
666
|
patch = {},
|
|
666
667
|
) {
|
|
667
|
-
const previous = context.store.getMcpClientState(
|
|
668
|
+
const previous = await context.store.getMcpClientState(
|
|
668
669
|
connection.connectionId,
|
|
669
670
|
subscription.eventName,
|
|
670
671
|
subscription.arguments,
|
|
@@ -687,7 +688,7 @@ export class McpEventsClientManager {
|
|
|
687
688
|
{ respectSchedule = false } = {},
|
|
688
689
|
) {
|
|
689
690
|
const store = context.store;
|
|
690
|
-
const current = store.getMcpClientState(
|
|
691
|
+
const current = await store.getMcpClientState(
|
|
691
692
|
connection.connectionId,
|
|
692
693
|
subscription.eventName,
|
|
693
694
|
subscription.arguments,
|
|
@@ -810,7 +811,7 @@ export class McpEventsClientManager {
|
|
|
810
811
|
}
|
|
811
812
|
if (existing) await this.closeSession(subscription.subscriptionId);
|
|
812
813
|
|
|
813
|
-
const current = context.store.getMcpClientState(
|
|
814
|
+
const current = await context.store.getMcpClientState(
|
|
814
815
|
connection.connectionId,
|
|
815
816
|
subscription.eventName,
|
|
816
817
|
subscription.arguments,
|
|
@@ -995,7 +996,7 @@ export class McpEventsClientManager {
|
|
|
995
996
|
descriptors = await this.discoverConnection(connectionId);
|
|
996
997
|
}
|
|
997
998
|
|
|
998
|
-
const desired = this.desiredSubscriptions(connection, context);
|
|
999
|
+
const desired = await this.desiredSubscriptions(connection, context);
|
|
999
1000
|
const desiredIds = new Set(desired.keys());
|
|
1000
1001
|
const results = [];
|
|
1001
1002
|
|
|
@@ -1062,12 +1063,12 @@ export class McpEventsClientManager {
|
|
|
1062
1063
|
return results;
|
|
1063
1064
|
}
|
|
1064
1065
|
|
|
1065
|
-
nextDelay(connection) {
|
|
1066
|
+
async nextDelay(connection) {
|
|
1066
1067
|
const context = this.scopeContexts.get(
|
|
1067
1068
|
`${connection.connectionId}::${connection.scopeId}`,
|
|
1068
1069
|
);
|
|
1069
1070
|
if (!context) return connection.pollIntervalMs;
|
|
1070
|
-
const states = context.store.listMcpClientStates(
|
|
1071
|
+
const states = await context.store.listMcpClientStates(
|
|
1071
1072
|
connection.connectionId,
|
|
1072
1073
|
);
|
|
1073
1074
|
const now = this.now().getTime();
|
|
@@ -1101,7 +1102,10 @@ export class McpEventsClientManager {
|
|
|
1101
1102
|
this.started &&
|
|
1102
1103
|
this.connections.get(connection.connectionId) === connection
|
|
1103
1104
|
) {
|
|
1104
|
-
this.scheduleConnection(
|
|
1105
|
+
this.scheduleConnection(
|
|
1106
|
+
connection,
|
|
1107
|
+
await this.nextDelay(connection),
|
|
1108
|
+
);
|
|
1105
1109
|
}
|
|
1106
1110
|
}
|
|
1107
1111
|
}, Math.max(0, delay));
|
|
@@ -1136,15 +1140,15 @@ export class McpEventsClientManager {
|
|
|
1136
1140
|
await this.drain();
|
|
1137
1141
|
}
|
|
1138
1142
|
|
|
1139
|
-
status() {
|
|
1140
|
-
return [...this.connections.values()].map((connection) => {
|
|
1143
|
+
async status() {
|
|
1144
|
+
return Promise.all([...this.connections.values()].map(async (connection) => {
|
|
1141
1145
|
const context = this.scopeContexts.get(
|
|
1142
1146
|
`${connection.connectionId}::${connection.scopeId}`,
|
|
1143
1147
|
);
|
|
1144
1148
|
const store = context?.store ?? this.store;
|
|
1145
|
-
const states = store.listMcpClientStates(connection.connectionId);
|
|
1149
|
+
const states = await store.listMcpClientStates(connection.connectionId);
|
|
1146
1150
|
const desired = context
|
|
1147
|
-
? this.desiredSubscriptions(connection, context)
|
|
1151
|
+
? await this.desiredSubscriptions(connection, context)
|
|
1148
1152
|
: new Map();
|
|
1149
1153
|
return {
|
|
1150
1154
|
connectionId: connection.connectionId,
|
|
@@ -1177,6 +1181,6 @@ export class McpEventsClientManager {
|
|
|
1177
1181
|
),
|
|
1178
1182
|
error: this.lastErrors.get(connection.connectionId) ?? null,
|
|
1179
1183
|
};
|
|
1180
|
-
});
|
|
1184
|
+
}));
|
|
1181
1185
|
}
|
|
1182
1186
|
}
|