monora-ai 1.0.1 → 1.3.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/README.md +13 -0
- package/dist/ai_act_report.d.ts +66 -0
- package/dist/ai_act_report.d.ts.map +1 -0
- package/dist/ai_act_report.js +294 -0
- package/dist/api.d.ts +102 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +125 -0
- package/dist/attestation.d.ts +26 -1
- package/dist/attestation.d.ts.map +1 -1
- package/dist/attestation.js +97 -12
- package/dist/cli.js +74 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -3
- package/dist/context.d.ts +50 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +122 -2
- package/dist/events.d.ts +5 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +17 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -2
- package/dist/instrumentation.d.ts +7 -2
- package/dist/instrumentation.d.ts.map +1 -1
- package/dist/instrumentation.js +200 -14
- package/dist/lineage.d.ts +178 -0
- package/dist/lineage.d.ts.map +1 -0
- package/dist/lineage.js +313 -0
- package/dist/middleware/express.d.ts +61 -0
- package/dist/middleware/express.d.ts.map +1 -0
- package/dist/middleware/express.js +112 -0
- package/dist/propagation.d.ts +103 -0
- package/dist/propagation.d.ts.map +1 -0
- package/dist/propagation.js +214 -0
- package/dist/registry.d.ts +9 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +33 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +88 -25
- package/dist/reporting.d.ts +30 -0
- package/dist/reporting.d.ts.map +1 -0
- package/dist/reporting.js +519 -0
- package/dist/runtime.d.ts +78 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +315 -6
- package/dist/signing.d.ts +106 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +424 -0
- package/dist/timers.d.ts +86 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +100 -0
- package/dist/traced_emitter.d.ts +97 -0
- package/dist/traced_emitter.d.ts.map +1 -0
- package/dist/traced_emitter.js +184 -0
- package/dist/trust_package.d.ts +22 -0
- package/dist/trust_package.d.ts.map +1 -0
- package/dist/trust_package.js +147 -0
- package/dist/verify.d.ts +47 -0
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +90 -0
- package/dist/wal.d.ts +91 -0
- package/dist/wal.d.ts.map +1 -0
- package/dist/wal.js +344 -0
- package/package.json +1 -1
package/dist/attestation.js
CHANGED
|
@@ -41,6 +41,7 @@ exports.serializeReport = serializeReport;
|
|
|
41
41
|
exports.computeSha256 = computeSha256;
|
|
42
42
|
exports.signReportGpg = signReportGpg;
|
|
43
43
|
exports.buildAttestationBundle = buildAttestationBundle;
|
|
44
|
+
exports.extractComplianceSummary = extractComplianceSummary;
|
|
44
45
|
const crypto = __importStar(require("crypto"));
|
|
45
46
|
const fs = __importStar(require("fs"));
|
|
46
47
|
const os = __importStar(require("os"));
|
|
@@ -114,19 +115,103 @@ function signReportGpg(reportBytes, options) {
|
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Build attestation bundle with optional chain proof (v2.0.0 format).
|
|
120
|
+
*
|
|
121
|
+
* @param report - Compliance report
|
|
122
|
+
* @param reportBytes - Serialized report
|
|
123
|
+
* @param signature - Optional GPG signature
|
|
124
|
+
* @param options - Optional v2.0.0 fields (chainProof, eventsDigest, traceInfo, events)
|
|
125
|
+
* @returns Trust proof bundle (v2.0.0 format if chainProof provided, v1.0.0 otherwise)
|
|
126
|
+
*/
|
|
127
|
+
function buildAttestationBundle(report, reportBytes, signature, options) {
|
|
128
|
+
const isTrustProof = options?.chainProof != null;
|
|
129
|
+
const bundleVersion = isTrustProof ? '2.0.0' : '1.0.0';
|
|
130
|
+
const bundleType = isTrustProof ? 'trust_proof' : 'compliance_report';
|
|
131
|
+
const bundle = {
|
|
132
|
+
bundle_version: bundleVersion,
|
|
133
|
+
bundle_type: bundleType,
|
|
120
134
|
generated_at: new Date().toISOString(),
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
135
|
+
};
|
|
136
|
+
// Add trace info (v2.0.0 only)
|
|
137
|
+
if (options?.traceInfo) {
|
|
138
|
+
bundle.trace_info = options.traceInfo;
|
|
139
|
+
}
|
|
140
|
+
// Add chain proof (v2.0.0 only)
|
|
141
|
+
if (options?.chainProof) {
|
|
142
|
+
bundle.chain_proof = options.chainProof;
|
|
143
|
+
}
|
|
144
|
+
// Add events digest (v2.0.0 only)
|
|
145
|
+
if (options?.eventsDigest) {
|
|
146
|
+
bundle.events_digest = options.eventsDigest;
|
|
147
|
+
}
|
|
148
|
+
// Embed raw events if provided (v2.0.0 only)
|
|
149
|
+
if (options?.events) {
|
|
150
|
+
bundle.events = options.events;
|
|
151
|
+
}
|
|
152
|
+
// Add compliance summary (v2.0.0 only)
|
|
153
|
+
if (isTrustProof) {
|
|
154
|
+
bundle.compliance_summary = extractComplianceSummary(report);
|
|
155
|
+
}
|
|
156
|
+
// Add report artifacts (v2.0.0 only)
|
|
157
|
+
if (isTrustProof) {
|
|
158
|
+
bundle.report_artifacts = report.artifacts || [];
|
|
159
|
+
}
|
|
160
|
+
// v1.0.0 format (backward compatibility)
|
|
161
|
+
if (!isTrustProof) {
|
|
162
|
+
bundle.report_sha256 = computeSha256(reportBytes);
|
|
163
|
+
bundle.report_json = reportBytes.toString('utf-8');
|
|
164
|
+
}
|
|
165
|
+
// Add signature if provided
|
|
166
|
+
if (signature) {
|
|
167
|
+
if (isTrustProof) {
|
|
168
|
+
// For v2.0.0, compute signature over entire bundle (excluding signature itself)
|
|
169
|
+
const payload = {};
|
|
170
|
+
for (const [key, value] of Object.entries(bundle)) {
|
|
171
|
+
if (key !== 'signature') {
|
|
172
|
+
payload[key] = value;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const payloadBytes = serializeReport(payload);
|
|
176
|
+
const payloadSha = computeSha256(payloadBytes);
|
|
177
|
+
bundle.signature = {
|
|
178
|
+
type: signature.signature_type,
|
|
179
|
+
value: signature.signature,
|
|
180
|
+
key_id: signature.key_id,
|
|
181
|
+
fingerprint: signature.fingerprint,
|
|
182
|
+
signed_at: new Date().toISOString(),
|
|
183
|
+
signed_payload_sha256: payloadSha,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// v1.0.0 format
|
|
188
|
+
bundle.signature = {
|
|
189
|
+
type: signature.signature_type,
|
|
190
|
+
value: signature.signature,
|
|
191
|
+
key_id: signature.key_id,
|
|
192
|
+
fingerprint: signature.fingerprint,
|
|
193
|
+
signed_at: new Date().toISOString(),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return bundle;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Extract key compliance metrics for bundle.
|
|
201
|
+
*
|
|
202
|
+
* @param report - Full compliance report
|
|
203
|
+
* @returns Compact compliance summary
|
|
204
|
+
*/
|
|
205
|
+
function extractComplianceSummary(report) {
|
|
206
|
+
const modelCompliance = report.model_compliance || {};
|
|
207
|
+
const violations = report.violations || [];
|
|
208
|
+
const tokenUsage = report.token_usage || {};
|
|
209
|
+
return {
|
|
210
|
+
policy_violations: Array.isArray(violations) ? violations.length : 0,
|
|
211
|
+
data_handling_issues: 0, // TODO: Extract from data handling events
|
|
212
|
+
unknown_models: modelCompliance.unknown_models_used || [],
|
|
213
|
+
forbidden_models_blocked: (modelCompliance.forbidden_models_blocked || []).length,
|
|
214
|
+
total_tokens: tokenUsage.total_tokens || 0,
|
|
130
215
|
};
|
|
131
216
|
}
|
|
132
217
|
function findGpg() {
|
package/dist/cli.js
CHANGED
|
@@ -43,8 +43,10 @@ const readline = __importStar(require("readline"));
|
|
|
43
43
|
const yaml = __importStar(require("js-yaml"));
|
|
44
44
|
const config_1 = require("./config");
|
|
45
45
|
const report_1 = require("./report");
|
|
46
|
+
const ai_act_report_1 = require("./ai_act_report");
|
|
46
47
|
const security_report_1 = require("./security_report");
|
|
47
48
|
const attestation_1 = require("./attestation");
|
|
49
|
+
const trust_package_1 = require("./trust_package");
|
|
48
50
|
const diagnostics_1 = require("./cli/diagnostics");
|
|
49
51
|
function usage() {
|
|
50
52
|
console.log('Usage:');
|
|
@@ -53,6 +55,8 @@ function usage() {
|
|
|
53
55
|
console.log(' monora doctor [--config monora.yml] [--json] [--no-network]');
|
|
54
56
|
console.log(' monora report --input <events.jsonl> --output <report.json> [--format json|markdown] [--config monora.yml]');
|
|
55
57
|
console.log(' monora security-review --input <events.jsonl> --output <security.json> [--config monora.yml] [--sign gpg --gpg-key <id> --bundle <bundle.json>]');
|
|
58
|
+
console.log(' monora trust-package --input <events.jsonl> --trace-id <trace_id> --output <trust.json> [--config monora.yml] [--sign gpg --gpg-key <id>]');
|
|
59
|
+
console.log(' monora ai-act-report --input <events.jsonl> --output <report.json> [--format json|markdown] [--config monora.yml]');
|
|
56
60
|
}
|
|
57
61
|
function parseArgs(argv) {
|
|
58
62
|
const args = argv.slice(2);
|
|
@@ -319,6 +323,29 @@ function parseSecurityReviewOptions(args) {
|
|
|
319
323
|
bundle: getFlagValue(args, '--bundle'),
|
|
320
324
|
};
|
|
321
325
|
}
|
|
326
|
+
function parseTrustPackageOptions(args) {
|
|
327
|
+
return {
|
|
328
|
+
input: getFlagValue(args, '--input'),
|
|
329
|
+
traceId: getFlagValue(args, '--trace-id'),
|
|
330
|
+
output: getFlagValue(args, '--output'),
|
|
331
|
+
config: getFlagValue(args, '--config'),
|
|
332
|
+
sign: getFlagValue(args, '--sign') || undefined,
|
|
333
|
+
gpgKey: getFlagValue(args, '--gpg-key'),
|
|
334
|
+
gpgHome: getFlagValue(args, '--gpg-home'),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function parseAIActReportOptions(args) {
|
|
338
|
+
const input = getFlagValue(args, '--input');
|
|
339
|
+
const output = getFlagValue(args, '--output');
|
|
340
|
+
const format = getFlagValue(args, '--format') || 'json';
|
|
341
|
+
const config = getFlagValue(args, '--config');
|
|
342
|
+
return {
|
|
343
|
+
input,
|
|
344
|
+
output,
|
|
345
|
+
format: format === 'markdown' ? 'markdown' : 'json',
|
|
346
|
+
config,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
322
349
|
async function runReport(options) {
|
|
323
350
|
if (!options.input || !options.output) {
|
|
324
351
|
usage();
|
|
@@ -335,6 +362,17 @@ async function runReport(options) {
|
|
|
335
362
|
}
|
|
336
363
|
console.log(`Report generated: ${options.output}`);
|
|
337
364
|
}
|
|
365
|
+
async function runAIActReport(options) {
|
|
366
|
+
if (!options.input || !options.output) {
|
|
367
|
+
usage();
|
|
368
|
+
process.exit(1);
|
|
369
|
+
}
|
|
370
|
+
const events = (0, report_1.loadJsonl)(options.input);
|
|
371
|
+
const config = options.config ? (0, config_1.loadConfig)({ configPath: options.config }) : (0, config_1.loadConfig)();
|
|
372
|
+
const report = (0, ai_act_report_1.buildAIActReport)(events, config);
|
|
373
|
+
(0, ai_act_report_1.writeAIActReport)(report, options.output, options.format);
|
|
374
|
+
console.log(`AI Act transparency report generated: ${options.output}`);
|
|
375
|
+
}
|
|
338
376
|
async function runSecurityReview(options) {
|
|
339
377
|
if (!options.input || !options.output) {
|
|
340
378
|
usage();
|
|
@@ -369,6 +407,34 @@ async function runSecurityReview(options) {
|
|
|
369
407
|
}
|
|
370
408
|
console.log(`Security review report generated: ${options.output}`);
|
|
371
409
|
}
|
|
410
|
+
async function runTrustPackage(options) {
|
|
411
|
+
if (!options.input || !options.output || !options.traceId) {
|
|
412
|
+
usage();
|
|
413
|
+
process.exit(1);
|
|
414
|
+
}
|
|
415
|
+
const events = (0, report_1.loadJsonl)(options.input);
|
|
416
|
+
const config = options.config ? (0, config_1.loadConfig)({ configPath: options.config }) : (0, config_1.loadConfig)();
|
|
417
|
+
let trustPackage = (0, trust_package_1.buildTrustPackage)(options.traceId, events, config);
|
|
418
|
+
if (options.sign) {
|
|
419
|
+
if (options.sign !== 'gpg') {
|
|
420
|
+
console.error(`Unsupported signing type: ${options.sign}`);
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
trustPackage = (0, trust_package_1.applyGpgSignature)(trustPackage, {
|
|
425
|
+
gpgKey: options.gpgKey,
|
|
426
|
+
gpgHome: options.gpgHome,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
const message = error instanceof attestation_1.AttestationError ? error.message : String(error);
|
|
431
|
+
console.error(`Signing failed: ${message}`);
|
|
432
|
+
process.exit(1);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
(0, trust_package_1.writeTrustPackage)(options.output, trustPackage);
|
|
436
|
+
console.log(`Trust package generated: ${options.output}`);
|
|
437
|
+
}
|
|
372
438
|
async function runValidate(args) {
|
|
373
439
|
const configPath = getFlagValue(args, '--config') || 'monora.yml';
|
|
374
440
|
const asJson = hasFlag(args, '--json');
|
|
@@ -434,6 +500,14 @@ async function main() {
|
|
|
434
500
|
await runSecurityReview(parseSecurityReviewOptions(parsed.args));
|
|
435
501
|
return;
|
|
436
502
|
}
|
|
503
|
+
if (parsed.command === 'trust-package') {
|
|
504
|
+
await runTrustPackage(parseTrustPackageOptions(parsed.args));
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (parsed.command === 'ai-act-report') {
|
|
508
|
+
await runAIActReport(parseAIActReportOptions(parsed.args));
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
437
511
|
usage();
|
|
438
512
|
}
|
|
439
513
|
main().catch((err) => {
|
package/dist/config.d.ts
CHANGED
|
@@ -17,6 +17,17 @@ export interface MonoraConfig {
|
|
|
17
17
|
enabled?: boolean;
|
|
18
18
|
scope?: 'per_trace' | 'global';
|
|
19
19
|
hash_algorithm?: string;
|
|
20
|
+
verify_on_emit?: boolean;
|
|
21
|
+
verify_on_shutdown?: boolean;
|
|
22
|
+
persist_chain?: boolean;
|
|
23
|
+
};
|
|
24
|
+
attestation?: {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
gpg?: {
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
key_id?: string;
|
|
29
|
+
gpg_home?: string;
|
|
30
|
+
};
|
|
20
31
|
};
|
|
21
32
|
registry?: any;
|
|
22
33
|
instrumentation?: {
|
|
@@ -26,6 +37,16 @@ export interface MonoraConfig {
|
|
|
26
37
|
data_classification?: string;
|
|
27
38
|
reason?: string;
|
|
28
39
|
fail_fast?: boolean;
|
|
40
|
+
log_report?: boolean;
|
|
41
|
+
};
|
|
42
|
+
reporting?: {
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
emit_trust_summary?: boolean;
|
|
45
|
+
output_dir?: string;
|
|
46
|
+
formats?: string[];
|
|
47
|
+
include_security_report?: boolean;
|
|
48
|
+
max_events_per_trace?: number;
|
|
49
|
+
redact_host?: boolean;
|
|
29
50
|
};
|
|
30
51
|
data_handling?: {
|
|
31
52
|
enabled?: boolean;
|
|
@@ -59,6 +80,29 @@ export interface MonoraConfig {
|
|
|
59
80
|
flush_interval_sec?: number;
|
|
60
81
|
queue_full_timeout_sec?: number | null;
|
|
61
82
|
};
|
|
83
|
+
wal?: {
|
|
84
|
+
enabled?: boolean;
|
|
85
|
+
path?: string;
|
|
86
|
+
sync_mode?: 'fsync' | 'async' | 'none';
|
|
87
|
+
max_file_size_mb?: number;
|
|
88
|
+
retention_hours?: number;
|
|
89
|
+
recovery_on_startup?: boolean;
|
|
90
|
+
};
|
|
91
|
+
signing?: {
|
|
92
|
+
enabled?: boolean;
|
|
93
|
+
algorithm?: 'ed25519' | 'hmac-sha256';
|
|
94
|
+
key_id?: string | null;
|
|
95
|
+
key_file?: string | null;
|
|
96
|
+
key_env?: string;
|
|
97
|
+
};
|
|
98
|
+
ai_act?: {
|
|
99
|
+
enabled?: boolean;
|
|
100
|
+
organization_name?: string | null;
|
|
101
|
+
contact_email?: string | null;
|
|
102
|
+
default_risk_category?: 'minimal' | 'limited' | 'high' | 'unacceptable';
|
|
103
|
+
generate_transparency_report?: boolean;
|
|
104
|
+
transparency_report_formats?: string[];
|
|
105
|
+
};
|
|
62
106
|
}
|
|
63
107
|
export declare function loadConfig(options?: {
|
|
64
108
|
configPath?: string;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE;QACT,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;QAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -71,6 +71,15 @@ const DEFAULT_CONFIG = {
|
|
|
71
71
|
reason: undefined,
|
|
72
72
|
fail_fast: false,
|
|
73
73
|
},
|
|
74
|
+
reporting: {
|
|
75
|
+
enabled: true,
|
|
76
|
+
emit_trust_summary: true,
|
|
77
|
+
output_dir: './monora_reports',
|
|
78
|
+
formats: ['json'],
|
|
79
|
+
include_security_report: false,
|
|
80
|
+
max_events_per_trace: 10000,
|
|
81
|
+
redact_host: true,
|
|
82
|
+
},
|
|
74
83
|
data_handling: {
|
|
75
84
|
enabled: false,
|
|
76
85
|
mode: 'redact',
|
|
@@ -111,6 +120,29 @@ const DEFAULT_CONFIG = {
|
|
|
111
120
|
flush_interval_sec: 1.0,
|
|
112
121
|
queue_full_timeout_sec: null,
|
|
113
122
|
},
|
|
123
|
+
wal: {
|
|
124
|
+
enabled: false,
|
|
125
|
+
path: './monora_wal',
|
|
126
|
+
sync_mode: 'fsync',
|
|
127
|
+
max_file_size_mb: 100,
|
|
128
|
+
retention_hours: 24,
|
|
129
|
+
recovery_on_startup: true,
|
|
130
|
+
},
|
|
131
|
+
signing: {
|
|
132
|
+
enabled: false,
|
|
133
|
+
algorithm: 'ed25519',
|
|
134
|
+
key_id: null,
|
|
135
|
+
key_file: null,
|
|
136
|
+
key_env: 'MONORA_SIGNING_KEY',
|
|
137
|
+
},
|
|
138
|
+
ai_act: {
|
|
139
|
+
enabled: false,
|
|
140
|
+
organization_name: null,
|
|
141
|
+
contact_email: null,
|
|
142
|
+
default_risk_category: 'limited',
|
|
143
|
+
generate_transparency_report: true,
|
|
144
|
+
transparency_report_formats: ['json'],
|
|
145
|
+
},
|
|
114
146
|
};
|
|
115
147
|
function loadConfig(options) {
|
|
116
148
|
const { configPath, configDict, envPrefix = 'MONORA_' } = options || {};
|
|
@@ -171,9 +203,17 @@ function envKeyToPath(key) {
|
|
|
171
203
|
if (parts.length >= 2 && parts[0] === 'ERROR' && parts[1] === 'HANDLING') {
|
|
172
204
|
return ['error_handling', ...parts.slice(2).map((p) => p.toLowerCase())];
|
|
173
205
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
const path = [
|
|
206
|
+
const upperKey = key.toUpperCase();
|
|
207
|
+
let rest = parts.slice(1);
|
|
208
|
+
const path = [];
|
|
209
|
+
if (upperKey.startsWith('AI_ACT') ||
|
|
210
|
+
(parts.length >= 2 && parts[0] === 'AI' && parts[1] === 'ACT')) {
|
|
211
|
+
path.push('ai_act');
|
|
212
|
+
rest = parts.slice(2);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
path.push(parts[0].toLowerCase());
|
|
216
|
+
}
|
|
177
217
|
const buffer = [];
|
|
178
218
|
for (const part of rest) {
|
|
179
219
|
if (/^\d+$/.test(part)) {
|
package/dist/context.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface TraceContext {
|
|
|
14
14
|
stepCounter: number;
|
|
15
15
|
eventCounter: number;
|
|
16
16
|
}
|
|
17
|
+
type TraceCompletionHandler = (span: Span) => void | Promise<void>;
|
|
18
|
+
export declare function registerTraceCompletionHandler(handler: TraceCompletionHandler): () => void;
|
|
17
19
|
export declare function getCurrentContext(): TraceContext | undefined;
|
|
18
20
|
export declare function getCurrentSpan(): Span | null;
|
|
19
21
|
export declare function pushSpan(span: Span): void;
|
|
@@ -29,4 +31,52 @@ export declare function traceAsync<T>(name: string, fn: (span: Span) => Promise<
|
|
|
29
31
|
export declare function startSpan(name: string, metadata?: Record<string, any>): Span;
|
|
30
32
|
export declare function nextStepNumber(): number;
|
|
31
33
|
export declare function nextEventSequence(): number | null;
|
|
34
|
+
/**
|
|
35
|
+
* Capture the current trace context for later use.
|
|
36
|
+
*
|
|
37
|
+
* This is useful for preserving context across async boundaries like
|
|
38
|
+
* setTimeout, setInterval, EventEmitter callbacks, or worker threads.
|
|
39
|
+
*
|
|
40
|
+
* @returns The current trace context, or undefined if no trace is active.
|
|
41
|
+
*/
|
|
42
|
+
export declare function captureContext(): TraceContext | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Run a function within a specific trace context.
|
|
45
|
+
*
|
|
46
|
+
* This allows executing code as if it were inside a particular trace,
|
|
47
|
+
* even when called from outside that trace's async chain.
|
|
48
|
+
*
|
|
49
|
+
* @param ctx The trace context to run within (or undefined for no context).
|
|
50
|
+
* @param fn The function to execute.
|
|
51
|
+
* @returns The result of the function.
|
|
52
|
+
*/
|
|
53
|
+
export declare function runInContext<T>(ctx: TraceContext | undefined, fn: () => T): T;
|
|
54
|
+
/**
|
|
55
|
+
* Bind a function to the current trace context.
|
|
56
|
+
*
|
|
57
|
+
* The returned function, when called, will execute within the captured
|
|
58
|
+
* trace context regardless of where it's called from. This is essential
|
|
59
|
+
* for preserving trace context through:
|
|
60
|
+
* - setTimeout/setInterval callbacks
|
|
61
|
+
* - EventEmitter handlers
|
|
62
|
+
* - process.nextTick/setImmediate callbacks
|
|
63
|
+
* - Any other async scheduling mechanism
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* trace('my-workflow', async (span) => {
|
|
68
|
+
* const boundCallback = bindContext(() => {
|
|
69
|
+
* // getCurrentSpan() will return the correct span here
|
|
70
|
+
* logEvent('delayed_action', { data: 'test' });
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* setTimeout(boundCallback, 1000);
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @param fn The function to bind to the current context.
|
|
78
|
+
* @returns A wrapped function that will execute in the captured context.
|
|
79
|
+
*/
|
|
80
|
+
export declare function bindContext<T extends (...args: any[]) => any>(fn: T): T;
|
|
81
|
+
export {};
|
|
32
82
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,SAAS,CAE5D;AAED,wBAAgB,cAAc,IAAI,IAAI,GAAG,IAAI,CAG5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,IAAI,CAiBrC;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,EACrB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,KAAK,sBAAsB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAGnE,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,sBAAsB,GAC9B,MAAM,IAAI,CAGZ;AAED,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,SAAS,CAE5D;AAED,wBAAgB,cAAc,IAAI,IAAI,GAAG,IAAI,CAG5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,IAAI,CAiBrC;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,EACrB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,CAAC,CA+BH;AAED,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAe5E;AAED,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAOjD;AA+BD;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,YAAY,GAAG,SAAS,CAEzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAK7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAQvE"}
|
package/dist/context.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Trace context propagation using AsyncLocalStorage.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerTraceCompletionHandler = registerTraceCompletionHandler;
|
|
6
7
|
exports.getCurrentContext = getCurrentContext;
|
|
7
8
|
exports.getCurrentSpan = getCurrentSpan;
|
|
8
9
|
exports.pushSpan = pushSpan;
|
|
@@ -12,10 +13,18 @@ exports.traceAsync = traceAsync;
|
|
|
12
13
|
exports.startSpan = startSpan;
|
|
13
14
|
exports.nextStepNumber = nextStepNumber;
|
|
14
15
|
exports.nextEventSequence = nextEventSequence;
|
|
16
|
+
exports.captureContext = captureContext;
|
|
17
|
+
exports.runInContext = runInContext;
|
|
18
|
+
exports.bindContext = bindContext;
|
|
15
19
|
const async_hooks_1 = require("async_hooks");
|
|
16
20
|
const ids_1 = require("./ids");
|
|
17
21
|
// AsyncLocalStorage for Node.js context propagation
|
|
18
22
|
const asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
|
|
23
|
+
const traceCompletionHandlers = new Set();
|
|
24
|
+
function registerTraceCompletionHandler(handler) {
|
|
25
|
+
traceCompletionHandlers.add(handler);
|
|
26
|
+
return () => traceCompletionHandlers.delete(handler);
|
|
27
|
+
}
|
|
19
28
|
function getCurrentContext() {
|
|
20
29
|
return asyncLocalStorage.getStore();
|
|
21
30
|
}
|
|
@@ -62,7 +71,21 @@ function trace(name, fn, options) {
|
|
|
62
71
|
stepCounter: 0,
|
|
63
72
|
eventCounter: 0,
|
|
64
73
|
};
|
|
65
|
-
return asyncLocalStorage.run(ctx, () =>
|
|
74
|
+
return asyncLocalStorage.run(ctx, () => {
|
|
75
|
+
let result;
|
|
76
|
+
try {
|
|
77
|
+
result = fn(span);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
runTraceCompletionHandlersSync(span);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
if (isPromise(result)) {
|
|
84
|
+
return result.finally(() => runTraceCompletionHandlers(span));
|
|
85
|
+
}
|
|
86
|
+
runTraceCompletionHandlersSync(span);
|
|
87
|
+
return result;
|
|
88
|
+
});
|
|
66
89
|
}
|
|
67
90
|
async function traceAsync(name, fn, options) {
|
|
68
91
|
const rootTraceId = options?.traceId || (0, ids_1.generateUlid)('trc');
|
|
@@ -79,7 +102,14 @@ async function traceAsync(name, fn, options) {
|
|
|
79
102
|
stepCounter: 0,
|
|
80
103
|
eventCounter: 0,
|
|
81
104
|
};
|
|
82
|
-
return asyncLocalStorage.run(ctx, () =>
|
|
105
|
+
return asyncLocalStorage.run(ctx, async () => {
|
|
106
|
+
try {
|
|
107
|
+
return await fn(span);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await runTraceCompletionHandlers(span);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
83
113
|
}
|
|
84
114
|
function startSpan(name, metadata) {
|
|
85
115
|
const current = getCurrentSpan();
|
|
@@ -111,3 +141,93 @@ function nextEventSequence() {
|
|
|
111
141
|
ctx.eventCounter += 1;
|
|
112
142
|
return ctx.eventCounter;
|
|
113
143
|
}
|
|
144
|
+
function runTraceCompletionHandlersSync(span) {
|
|
145
|
+
for (const handler of traceCompletionHandlers) {
|
|
146
|
+
try {
|
|
147
|
+
const result = handler(span);
|
|
148
|
+
if (result && typeof result.then === 'function') {
|
|
149
|
+
result.catch((error) => {
|
|
150
|
+
console.error(`Monora: trace completion handler failed: ${error}`);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error(`Monora: trace completion handler failed: ${error}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function runTraceCompletionHandlers(span) {
|
|
160
|
+
for (const handler of traceCompletionHandlers) {
|
|
161
|
+
try {
|
|
162
|
+
await handler(span);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.error(`Monora: trace completion handler failed: ${error}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function isPromise(value) {
|
|
170
|
+
return value && typeof value.then === 'function';
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Capture the current trace context for later use.
|
|
174
|
+
*
|
|
175
|
+
* This is useful for preserving context across async boundaries like
|
|
176
|
+
* setTimeout, setInterval, EventEmitter callbacks, or worker threads.
|
|
177
|
+
*
|
|
178
|
+
* @returns The current trace context, or undefined if no trace is active.
|
|
179
|
+
*/
|
|
180
|
+
function captureContext() {
|
|
181
|
+
return asyncLocalStorage.getStore();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Run a function within a specific trace context.
|
|
185
|
+
*
|
|
186
|
+
* This allows executing code as if it were inside a particular trace,
|
|
187
|
+
* even when called from outside that trace's async chain.
|
|
188
|
+
*
|
|
189
|
+
* @param ctx The trace context to run within (or undefined for no context).
|
|
190
|
+
* @param fn The function to execute.
|
|
191
|
+
* @returns The result of the function.
|
|
192
|
+
*/
|
|
193
|
+
function runInContext(ctx, fn) {
|
|
194
|
+
if (!ctx) {
|
|
195
|
+
return fn();
|
|
196
|
+
}
|
|
197
|
+
return asyncLocalStorage.run(ctx, fn);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Bind a function to the current trace context.
|
|
201
|
+
*
|
|
202
|
+
* The returned function, when called, will execute within the captured
|
|
203
|
+
* trace context regardless of where it's called from. This is essential
|
|
204
|
+
* for preserving trace context through:
|
|
205
|
+
* - setTimeout/setInterval callbacks
|
|
206
|
+
* - EventEmitter handlers
|
|
207
|
+
* - process.nextTick/setImmediate callbacks
|
|
208
|
+
* - Any other async scheduling mechanism
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* trace('my-workflow', async (span) => {
|
|
213
|
+
* const boundCallback = bindContext(() => {
|
|
214
|
+
* // getCurrentSpan() will return the correct span here
|
|
215
|
+
* logEvent('delayed_action', { data: 'test' });
|
|
216
|
+
* });
|
|
217
|
+
*
|
|
218
|
+
* setTimeout(boundCallback, 1000);
|
|
219
|
+
* });
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* @param fn The function to bind to the current context.
|
|
223
|
+
* @returns A wrapped function that will execute in the captured context.
|
|
224
|
+
*/
|
|
225
|
+
function bindContext(fn) {
|
|
226
|
+
const captured = captureContext();
|
|
227
|
+
if (!captured) {
|
|
228
|
+
return fn;
|
|
229
|
+
}
|
|
230
|
+
return ((...args) => {
|
|
231
|
+
return runInContext(captured, () => fn(...args));
|
|
232
|
+
});
|
|
233
|
+
}
|
package/dist/events.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ export declare class EventBuilder {
|
|
|
10
10
|
dataClassification?: string;
|
|
11
11
|
purpose?: string;
|
|
12
12
|
reason?: string;
|
|
13
|
+
parentEventId?: string;
|
|
14
|
+
inputEventIds?: string[];
|
|
15
|
+
promptId?: string;
|
|
16
|
+
templateId?: string;
|
|
17
|
+
dataSourceIds?: string[];
|
|
13
18
|
}): Record<string, any>;
|
|
14
19
|
}
|
|
15
20
|
//# sourceMappingURL=events.d.ts.map
|
package/dist/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAqFxC,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,SAAS,CAAa;gBAElB,MAAM,EAAE,YAAY;IAWhC,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,OAAO,CAAC,EAAE;QACR,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,GACA,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CA4CvB"}
|
package/dist/events.js
CHANGED
|
@@ -40,6 +40,7 @@ exports.EventBuilder = void 0;
|
|
|
40
40
|
const os = __importStar(require("os"));
|
|
41
41
|
const context_1 = require("./context");
|
|
42
42
|
const ids_1 = require("./ids");
|
|
43
|
+
const lineage_1 = require("./lineage");
|
|
43
44
|
class TimestampEnricher {
|
|
44
45
|
enrich(event) {
|
|
45
46
|
event.timestamp = new Date().toISOString();
|
|
@@ -107,13 +108,25 @@ class EventBuilder {
|
|
|
107
108
|
}
|
|
108
109
|
build(eventType, body, options) {
|
|
109
110
|
const span = (0, context_1.getCurrentSpan)();
|
|
111
|
+
// Auto-capture lineage from context if not explicitly provided
|
|
112
|
+
const effectiveParentEventId = options?.parentEventId ?? (0, lineage_1.getParentEventId)();
|
|
113
|
+
const effectiveInputEventIds = options?.inputEventIds ?? (0, lineage_1.getInputEvents)();
|
|
114
|
+
const effectivePromptId = options?.promptId ?? (0, lineage_1.getPromptId)();
|
|
115
|
+
const effectiveTemplateId = options?.templateId ?? (0, lineage_1.getTemplateId)();
|
|
116
|
+
const effectiveDataSourceIds = options?.dataSourceIds ?? (0, lineage_1.getDataSources)();
|
|
117
|
+
const eventId = (0, ids_1.generateUlid)('evt');
|
|
110
118
|
const event = {
|
|
111
|
-
schema_version: '1.
|
|
112
|
-
event_id:
|
|
119
|
+
schema_version: '1.1.0',
|
|
120
|
+
event_id: eventId,
|
|
113
121
|
event_type: eventType,
|
|
114
122
|
trace_id: span ? span.traceId : (0, ids_1.generateUlid)('trc'),
|
|
115
123
|
span_id: span ? span.spanId : (0, ids_1.generateUlid)('spn'),
|
|
116
124
|
parent_span_id: span ? span.parentSpanId : null,
|
|
125
|
+
parent_event_id: effectiveParentEventId,
|
|
126
|
+
input_event_ids: effectiveInputEventIds.length > 0 ? effectiveInputEventIds : [],
|
|
127
|
+
prompt_id: effectivePromptId,
|
|
128
|
+
template_id: effectiveTemplateId,
|
|
129
|
+
data_source_ids: effectiveDataSourceIds.length > 0 ? effectiveDataSourceIds : [],
|
|
117
130
|
data_classification: options?.dataClassification || this.defaults?.data_classification || 'internal',
|
|
118
131
|
purpose: options?.purpose || this.defaults?.purpose || 'general',
|
|
119
132
|
reason: options?.reason || null,
|
|
@@ -126,6 +139,8 @@ class EventBuilder {
|
|
|
126
139
|
for (const enricher of this.enrichers) {
|
|
127
140
|
enricher.enrich(event);
|
|
128
141
|
}
|
|
142
|
+
// Update current event for next event's parent_event_id
|
|
143
|
+
(0, lineage_1.setCurrentEvent)(eventId);
|
|
129
144
|
return event;
|
|
130
145
|
}
|
|
131
146
|
}
|