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/README.md
CHANGED
|
@@ -52,12 +52,25 @@ This generates a `monora.yml` you can load with `loadConfig({ configPath: './mon
|
|
|
52
52
|
|
|
53
53
|
### Reports & Security Review
|
|
54
54
|
|
|
55
|
+
The runtime automatically generates compliance reports at trace completion (default: `./monora_reports/<trace_id>/compliance.json`) and emits a `trust_summary` event. Configure behavior with the `reporting` section in `monora.yml`.
|
|
56
|
+
|
|
55
57
|
```bash
|
|
56
58
|
npx monora-ai report --input events.jsonl --output report.json
|
|
57
59
|
npx monora-ai report --input events.jsonl --output report.md --format markdown
|
|
58
60
|
|
|
59
61
|
npx monora-ai security-review --input events.jsonl --output security.json
|
|
60
62
|
npx monora-ai security-review --input events.jsonl --output security.json --sign gpg --gpg-key "you@example.com"
|
|
63
|
+
|
|
64
|
+
npx monora-ai trust-package --input events.jsonl --trace-id trc_123 --output trust.json --config monora.yml
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { exportTrustPackage } from 'monora-ai';
|
|
69
|
+
|
|
70
|
+
const trustPackage = exportTrustPackage('trc_123', {
|
|
71
|
+
inputPath: 'events.jsonl',
|
|
72
|
+
configPath: 'monora.yml',
|
|
73
|
+
});
|
|
61
74
|
```
|
|
62
75
|
|
|
63
76
|
### Data Handling + Alerts
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EU AI Act transparency report generation.
|
|
3
|
+
*
|
|
4
|
+
* This module provides tools for generating transparency reports compliant with
|
|
5
|
+
* the EU AI Act (Regulation 2024/1689), specifically addressing requirements from
|
|
6
|
+
* Articles 13, 52, and Annex IV.
|
|
7
|
+
*/
|
|
8
|
+
import { MonoraConfig } from './config';
|
|
9
|
+
export interface RiskCategorySummary {
|
|
10
|
+
minimal: number;
|
|
11
|
+
limited: number;
|
|
12
|
+
high: number;
|
|
13
|
+
unacceptable: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ModelUsageSummary {
|
|
16
|
+
model: string;
|
|
17
|
+
provider: string;
|
|
18
|
+
riskCategory: string;
|
|
19
|
+
callCount: number;
|
|
20
|
+
firstUsed?: string;
|
|
21
|
+
lastUsed?: string;
|
|
22
|
+
capabilities: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface AIActTransparencyReport {
|
|
25
|
+
reportVersion: string;
|
|
26
|
+
generatedAt: string;
|
|
27
|
+
organizationName?: string;
|
|
28
|
+
contactEmail?: string;
|
|
29
|
+
reportingPeriodStart?: string;
|
|
30
|
+
reportingPeriodEnd?: string;
|
|
31
|
+
totalAiInteractions: number;
|
|
32
|
+
uniqueModelsUsed: number;
|
|
33
|
+
uniqueTraces: number;
|
|
34
|
+
riskCategorySummary: RiskCategorySummary;
|
|
35
|
+
highRiskModels: string[];
|
|
36
|
+
unacceptableRiskModels: string[];
|
|
37
|
+
modelsUsed: ModelUsageSummary[];
|
|
38
|
+
policyViolationsCount: number;
|
|
39
|
+
policyViolationsByModel: Record<string, number>;
|
|
40
|
+
dataClassificationsUsed: Record<string, number>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build AI Act transparency report from event log.
|
|
44
|
+
*
|
|
45
|
+
* @param events - Array of Monora event objects.
|
|
46
|
+
* @param config - Optional Monora configuration containing ai_act and registry settings.
|
|
47
|
+
* @returns AIActTransparencyReport with populated fields.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const events = loadJsonl("events.jsonl");
|
|
52
|
+
* const config = loadConfig({ configPath: "monora.yml" });
|
|
53
|
+
* const report = buildAIActReport(events, config);
|
|
54
|
+
* writeAIActReport(report, "transparency_report.json");
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildAIActReport(events: Array<Record<string, any>>, config?: MonoraConfig): AIActTransparencyReport;
|
|
58
|
+
/**
|
|
59
|
+
* Write AI Act report to file.
|
|
60
|
+
*
|
|
61
|
+
* @param report - The transparency report to write.
|
|
62
|
+
* @param filePath - Output file path.
|
|
63
|
+
* @param format - Output format - 'json' or 'markdown'.
|
|
64
|
+
*/
|
|
65
|
+
export declare function writeAIActReport(report: AIActTransparencyReport, filePath: string, format?: 'json' | 'markdown'): void;
|
|
66
|
+
//# sourceMappingURL=ai_act_report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai_act_report.d.ts","sourceRoot":"","sources":["../src/ai_act_report.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAClC,MAAM,CAAC,EAAE,YAAY,GACpB,uBAAuB,CA0JzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,uBAAuB,EAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,UAAmB,GACnC,IAAI,CAcN"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EU AI Act transparency report generation.
|
|
4
|
+
*
|
|
5
|
+
* This module provides tools for generating transparency reports compliant with
|
|
6
|
+
* the EU AI Act (Regulation 2024/1689), specifically addressing requirements from
|
|
7
|
+
* Articles 13, 52, and Annex IV.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.buildAIActReport = buildAIActReport;
|
|
44
|
+
exports.writeAIActReport = writeAIActReport;
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
/**
|
|
48
|
+
* Build AI Act transparency report from event log.
|
|
49
|
+
*
|
|
50
|
+
* @param events - Array of Monora event objects.
|
|
51
|
+
* @param config - Optional Monora configuration containing ai_act and registry settings.
|
|
52
|
+
* @returns AIActTransparencyReport with populated fields.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const events = loadJsonl("events.jsonl");
|
|
57
|
+
* const config = loadConfig({ configPath: "monora.yml" });
|
|
58
|
+
* const report = buildAIActReport(events, config);
|
|
59
|
+
* writeAIActReport(report, "transparency_report.json");
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
function buildAIActReport(events, config) {
|
|
63
|
+
const aiActConfig = config?.ai_act || {};
|
|
64
|
+
const registryConfig = config?.registry || {};
|
|
65
|
+
const report = {
|
|
66
|
+
reportVersion: '1.0',
|
|
67
|
+
generatedAt: new Date().toISOString(),
|
|
68
|
+
organizationName: aiActConfig.organization_name || undefined,
|
|
69
|
+
contactEmail: aiActConfig.contact_email || undefined,
|
|
70
|
+
reportingPeriodStart: undefined,
|
|
71
|
+
reportingPeriodEnd: undefined,
|
|
72
|
+
totalAiInteractions: 0,
|
|
73
|
+
uniqueModelsUsed: 0,
|
|
74
|
+
uniqueTraces: 0,
|
|
75
|
+
riskCategorySummary: { minimal: 0, limited: 0, high: 0, unacceptable: 0 },
|
|
76
|
+
highRiskModels: [],
|
|
77
|
+
unacceptableRiskModels: [],
|
|
78
|
+
modelsUsed: [],
|
|
79
|
+
policyViolationsCount: 0,
|
|
80
|
+
policyViolationsByModel: {},
|
|
81
|
+
dataClassificationsUsed: {},
|
|
82
|
+
};
|
|
83
|
+
// Build provider risk category and capabilities maps
|
|
84
|
+
const providerRisk = {};
|
|
85
|
+
const providerCapabilities = {};
|
|
86
|
+
const defaultRisk = aiActConfig.default_risk_category || 'limited';
|
|
87
|
+
for (const provider of registryConfig.providers || []) {
|
|
88
|
+
const name = provider.name || '';
|
|
89
|
+
providerRisk[name] = provider.risk_category || defaultRisk;
|
|
90
|
+
providerCapabilities[name] = provider.capabilities || [];
|
|
91
|
+
}
|
|
92
|
+
// Process events
|
|
93
|
+
const traceIds = new Set();
|
|
94
|
+
const modelStats = {};
|
|
95
|
+
const timestamps = [];
|
|
96
|
+
for (const event of events) {
|
|
97
|
+
// Skip trust summary events
|
|
98
|
+
if (event.event_type === 'trust_summary') {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Track trace IDs
|
|
102
|
+
if (event.trace_id) {
|
|
103
|
+
traceIds.add(event.trace_id);
|
|
104
|
+
}
|
|
105
|
+
// Track timestamps
|
|
106
|
+
if (event.timestamp) {
|
|
107
|
+
timestamps.push(event.timestamp);
|
|
108
|
+
}
|
|
109
|
+
const body = event.body || {};
|
|
110
|
+
// Track LLM calls
|
|
111
|
+
if (event.event_type === 'llm_call') {
|
|
112
|
+
const model = body.model || 'unknown';
|
|
113
|
+
const provider = body.provider || 'unknown';
|
|
114
|
+
const ts = event.timestamp;
|
|
115
|
+
if (!modelStats[model]) {
|
|
116
|
+
modelStats[model] = {
|
|
117
|
+
provider,
|
|
118
|
+
count: 0,
|
|
119
|
+
firstUsed: ts,
|
|
120
|
+
lastUsed: ts,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// increment count always
|
|
124
|
+
modelStats[model].count++;
|
|
125
|
+
// update firstUsed/lastUsed defensively using min/max comparison
|
|
126
|
+
if (ts) {
|
|
127
|
+
if (!modelStats[model].firstUsed || ts < modelStats[model].firstUsed) {
|
|
128
|
+
modelStats[model].firstUsed = ts;
|
|
129
|
+
}
|
|
130
|
+
if (!modelStats[model].lastUsed || ts > modelStats[model].lastUsed) {
|
|
131
|
+
modelStats[model].lastUsed = ts;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Track policy violations
|
|
136
|
+
if (body.status === 'policy_violation') {
|
|
137
|
+
report.policyViolationsCount++;
|
|
138
|
+
const model = body.model || 'unknown';
|
|
139
|
+
report.policyViolationsByModel[model] =
|
|
140
|
+
(report.policyViolationsByModel[model] || 0) + 1;
|
|
141
|
+
}
|
|
142
|
+
// Track data classifications
|
|
143
|
+
const dataClass = event.data_classification;
|
|
144
|
+
if (dataClass) {
|
|
145
|
+
report.dataClassificationsUsed[dataClass] =
|
|
146
|
+
(report.dataClassificationsUsed[dataClass] || 0) + 1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Set reporting period
|
|
150
|
+
if (timestamps.length > 0) {
|
|
151
|
+
timestamps.sort();
|
|
152
|
+
report.reportingPeriodStart = timestamps[0];
|
|
153
|
+
report.reportingPeriodEnd = timestamps[timestamps.length - 1];
|
|
154
|
+
}
|
|
155
|
+
// Build model summaries with risk categorization
|
|
156
|
+
for (const [model, stats] of Object.entries(modelStats)) {
|
|
157
|
+
const provider = stats.provider;
|
|
158
|
+
const risk = providerRisk[provider] || defaultRisk;
|
|
159
|
+
const caps = providerCapabilities[provider] || [];
|
|
160
|
+
const summary = {
|
|
161
|
+
model,
|
|
162
|
+
provider,
|
|
163
|
+
riskCategory: risk,
|
|
164
|
+
callCount: stats.count,
|
|
165
|
+
firstUsed: stats.firstUsed,
|
|
166
|
+
lastUsed: stats.lastUsed,
|
|
167
|
+
capabilities: [...caps],
|
|
168
|
+
};
|
|
169
|
+
report.modelsUsed.push(summary);
|
|
170
|
+
// Update risk category counts
|
|
171
|
+
if (risk === 'minimal') {
|
|
172
|
+
report.riskCategorySummary.minimal += stats.count;
|
|
173
|
+
}
|
|
174
|
+
else if (risk === 'limited') {
|
|
175
|
+
report.riskCategorySummary.limited += stats.count;
|
|
176
|
+
}
|
|
177
|
+
else if (risk === 'high') {
|
|
178
|
+
report.riskCategorySummary.high += stats.count;
|
|
179
|
+
if (!report.highRiskModels.includes(model)) {
|
|
180
|
+
report.highRiskModels.push(model);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (risk === 'unacceptable') {
|
|
184
|
+
report.riskCategorySummary.unacceptable += stats.count;
|
|
185
|
+
if (!report.unacceptableRiskModels.includes(model)) {
|
|
186
|
+
report.unacceptableRiskModels.push(model);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Set summary counts
|
|
191
|
+
report.totalAiInteractions = Object.values(modelStats).reduce((sum, s) => sum + s.count, 0);
|
|
192
|
+
report.uniqueModelsUsed = Object.keys(modelStats).length;
|
|
193
|
+
report.uniqueTraces = traceIds.size;
|
|
194
|
+
return report;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Write AI Act report to file.
|
|
198
|
+
*
|
|
199
|
+
* @param report - The transparency report to write.
|
|
200
|
+
* @param filePath - Output file path.
|
|
201
|
+
* @param format - Output format - 'json' or 'markdown'.
|
|
202
|
+
*/
|
|
203
|
+
function writeAIActReport(report, filePath, format = 'json') {
|
|
204
|
+
// Ensure output directory exists
|
|
205
|
+
const outputDir = path.dirname(filePath);
|
|
206
|
+
if (outputDir) {
|
|
207
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
208
|
+
}
|
|
209
|
+
if (format === 'json') {
|
|
210
|
+
writeJson(report, filePath);
|
|
211
|
+
}
|
|
212
|
+
else if (format === 'markdown') {
|
|
213
|
+
writeMarkdown(report, filePath);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function writeJson(report, filePath) {
|
|
220
|
+
fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
|
|
221
|
+
}
|
|
222
|
+
function writeMarkdown(report, filePath) {
|
|
223
|
+
const lines = [
|
|
224
|
+
'# EU AI Act Transparency Report',
|
|
225
|
+
'',
|
|
226
|
+
`**Generated:** ${report.generatedAt}`,
|
|
227
|
+
`**Organization:** ${report.organizationName || 'N/A'}`,
|
|
228
|
+
`**Contact:** ${report.contactEmail || 'N/A'}`,
|
|
229
|
+
'',
|
|
230
|
+
`**Reporting Period:** ${report.reportingPeriodStart || 'N/A'} to ${report.reportingPeriodEnd || 'N/A'}`,
|
|
231
|
+
'',
|
|
232
|
+
'---',
|
|
233
|
+
'',
|
|
234
|
+
'## Summary',
|
|
235
|
+
'',
|
|
236
|
+
`- **Total AI Interactions:** ${report.totalAiInteractions}`,
|
|
237
|
+
`- **Unique Models Used:** ${report.uniqueModelsUsed}`,
|
|
238
|
+
`- **Unique Traces:** ${report.uniqueTraces}`,
|
|
239
|
+
`- **Policy Violations:** ${report.policyViolationsCount}`,
|
|
240
|
+
'',
|
|
241
|
+
'---',
|
|
242
|
+
'',
|
|
243
|
+
'## Risk Category Breakdown',
|
|
244
|
+
'',
|
|
245
|
+
'| Category | Interactions |',
|
|
246
|
+
'|----------|--------------|',
|
|
247
|
+
`| Minimal Risk | ${report.riskCategorySummary.minimal} |`,
|
|
248
|
+
`| Limited Risk | ${report.riskCategorySummary.limited} |`,
|
|
249
|
+
`| High Risk | ${report.riskCategorySummary.high} |`,
|
|
250
|
+
`| Unacceptable Risk | ${report.riskCategorySummary.unacceptable} |`,
|
|
251
|
+
'',
|
|
252
|
+
];
|
|
253
|
+
// High risk models warning
|
|
254
|
+
if (report.highRiskModels.length > 0) {
|
|
255
|
+
lines.push('### High Risk Models Used', '');
|
|
256
|
+
for (const model of report.highRiskModels) {
|
|
257
|
+
lines.push(`- ${model}`);
|
|
258
|
+
}
|
|
259
|
+
lines.push('');
|
|
260
|
+
}
|
|
261
|
+
// Unacceptable risk models warning
|
|
262
|
+
if (report.unacceptableRiskModels.length > 0) {
|
|
263
|
+
lines.push('### Unacceptable Risk Models Used', '');
|
|
264
|
+
for (const model of report.unacceptableRiskModels) {
|
|
265
|
+
lines.push(`- ${model}`);
|
|
266
|
+
}
|
|
267
|
+
lines.push('');
|
|
268
|
+
}
|
|
269
|
+
// Model inventory
|
|
270
|
+
lines.push('---', '', '## Model Inventory', '', '| Model | Provider | Risk Category | Calls | Capabilities |', '|-------|----------|---------------|-------|--------------|');
|
|
271
|
+
for (const m of report.modelsUsed) {
|
|
272
|
+
const esc = (v) => (v ? String(v).replace(/\|/g, '\\|') : 'N/A');
|
|
273
|
+
const caps = m.capabilities.length > 0 ? m.capabilities.map(c => String(c).replace(/\|/g, '\\|')).join(', ') : 'N/A';
|
|
274
|
+
lines.push(`| ${esc(m.model)} | ${esc(m.provider)} | ${esc(m.riskCategory)} | ${m.callCount} | ${caps} |`);
|
|
275
|
+
}
|
|
276
|
+
// Data classifications
|
|
277
|
+
if (Object.keys(report.dataClassificationsUsed).length > 0) {
|
|
278
|
+
lines.push('', '---', '', '## Data Classifications', '', '| Classification | Events |', '|----------------|--------|');
|
|
279
|
+
for (const [classification, count] of Object.entries(report.dataClassificationsUsed).sort((a, b) => String(a[0]).localeCompare(String(b[0])))) {
|
|
280
|
+
const escClass = String(classification || 'N/A').replace(/\|/g, '\\|');
|
|
281
|
+
lines.push(`| ${escClass} | ${count} |`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Policy violations by model
|
|
285
|
+
if (Object.keys(report.policyViolationsByModel).length > 0) {
|
|
286
|
+
lines.push('', '---', '', '## Policy Violations by Model', '', '| Model | Violations |', '|-------|------------|');
|
|
287
|
+
for (const [model, count] of Object.entries(report.policyViolationsByModel).sort((a, b) => String(a[0]).localeCompare(String(b[0])))) {
|
|
288
|
+
const escModel = String(model || 'N/A').replace(/\|/g, '\\|');
|
|
289
|
+
lines.push(`| ${escModel} | ${count} |`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
lines.push('', '---', '', '*Report generated by Monora SDK*');
|
|
293
|
+
fs.writeFileSync(filePath, lines.join('\n'));
|
|
294
|
+
}
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct callable API for Node.js SDK
|
|
3
|
+
* Provides non-decorator functions for immediate execution with Monora governance
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Execute an LLM API call with Monora governance (direct callable).
|
|
7
|
+
*
|
|
8
|
+
* This function provides a direct, non-decorator way to instrument LLM calls.
|
|
9
|
+
* It wraps the execution with policy enforcement, data handling, and event logging.
|
|
10
|
+
*
|
|
11
|
+
* @param callFn - The function to execute (e.g., client.chat.completions.create)
|
|
12
|
+
* @param callArgs - Arguments to pass to callFn
|
|
13
|
+
* @param options - Monora governance options
|
|
14
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import * as monora from 'monora-ai';
|
|
19
|
+
* import OpenAI from 'openai';
|
|
20
|
+
*
|
|
21
|
+
* const client = new OpenAI();
|
|
22
|
+
*
|
|
23
|
+
* const response = await monora.callLlm(
|
|
24
|
+
* client.chat.completions.create.bind(client.chat.completions),
|
|
25
|
+
* {
|
|
26
|
+
* model: "gpt-4o-mini",
|
|
27
|
+
* messages: [{ role: "user", content: "Hello" }]
|
|
28
|
+
* },
|
|
29
|
+
* {
|
|
30
|
+
* purpose: "CUSTOMER_SUPPORT",
|
|
31
|
+
* dataClassification: "PUBLIC"
|
|
32
|
+
* }
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function callLlm<T>(callFn: (...args: any[]) => T | Promise<T>, callArgs: Record<string, any> | any[] | undefined, options: {
|
|
37
|
+
model?: string;
|
|
38
|
+
dataClassification?: string;
|
|
39
|
+
purpose: string;
|
|
40
|
+
reason?: string;
|
|
41
|
+
explainFn?: (response: Record<string, any>) => string;
|
|
42
|
+
}): T | Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Execute a tool call with Monora governance (direct callable).
|
|
45
|
+
*
|
|
46
|
+
* This function provides a direct, non-decorator way to instrument tool calls.
|
|
47
|
+
* It wraps the execution with data handling and event logging.
|
|
48
|
+
*
|
|
49
|
+
* @param callFn - The function to execute
|
|
50
|
+
* @param callArgs - Arguments to pass to callFn
|
|
51
|
+
* @param options - Monora governance options
|
|
52
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const result = await monora.callTool(
|
|
57
|
+
* fetchFromDatabase,
|
|
58
|
+
* { customerId: "123" },
|
|
59
|
+
* {
|
|
60
|
+
* toolName: "customer_lookup",
|
|
61
|
+
* purpose: "CUSTOMER_SUPPORT"
|
|
62
|
+
* }
|
|
63
|
+
* );
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function callTool<T>(callFn: (...args: any[]) => T | Promise<T>, callArgs: Record<string, any> | any[] | undefined, options: {
|
|
67
|
+
toolName: string;
|
|
68
|
+
dataClassification?: string;
|
|
69
|
+
purpose: string;
|
|
70
|
+
reason?: string;
|
|
71
|
+
}): T | Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Execute an agent step with Monora governance (direct callable).
|
|
74
|
+
*
|
|
75
|
+
* This function provides a direct, non-decorator way to instrument agent steps.
|
|
76
|
+
* It wraps the execution with data handling, step counting, and event logging.
|
|
77
|
+
*
|
|
78
|
+
* @param callFn - The function to execute
|
|
79
|
+
* @param callArgs - Arguments to pass to callFn
|
|
80
|
+
* @param options - Monora governance options
|
|
81
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const thought = await monora.callAgent(
|
|
86
|
+
* reasoningFunction,
|
|
87
|
+
* { context: { customer: "Acme Corp" } },
|
|
88
|
+
* {
|
|
89
|
+
* agentName: "sales_agent",
|
|
90
|
+
* stepType: "planning",
|
|
91
|
+
* purpose: "SALES_AUTOMATION"
|
|
92
|
+
* }
|
|
93
|
+
* );
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function callAgent<T>(callFn: (...args: any[]) => T | Promise<T>, callArgs: Record<string, any> | any[] | undefined, options: {
|
|
97
|
+
agentName: string;
|
|
98
|
+
stepType: string;
|
|
99
|
+
dataClassification?: string;
|
|
100
|
+
purpose: string;
|
|
101
|
+
}): T | Promise<T>;
|
|
102
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,SAAS,EACjD,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;CACvD,GACA,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAUhB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,SAAS,EACjD,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAShB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,SAAS,EACjD,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,GACA,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAShB"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Direct callable API for Node.js SDK
|
|
4
|
+
* Provides non-decorator functions for immediate execution with Monora governance
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.callLlm = callLlm;
|
|
8
|
+
exports.callTool = callTool;
|
|
9
|
+
exports.callAgent = callAgent;
|
|
10
|
+
const runtime_1 = require("./runtime");
|
|
11
|
+
/**
|
|
12
|
+
* Execute an LLM API call with Monora governance (direct callable).
|
|
13
|
+
*
|
|
14
|
+
* This function provides a direct, non-decorator way to instrument LLM calls.
|
|
15
|
+
* It wraps the execution with policy enforcement, data handling, and event logging.
|
|
16
|
+
*
|
|
17
|
+
* @param callFn - The function to execute (e.g., client.chat.completions.create)
|
|
18
|
+
* @param callArgs - Arguments to pass to callFn
|
|
19
|
+
* @param options - Monora governance options
|
|
20
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import * as monora from 'monora-ai';
|
|
25
|
+
* import OpenAI from 'openai';
|
|
26
|
+
*
|
|
27
|
+
* const client = new OpenAI();
|
|
28
|
+
*
|
|
29
|
+
* const response = await monora.callLlm(
|
|
30
|
+
* client.chat.completions.create.bind(client.chat.completions),
|
|
31
|
+
* {
|
|
32
|
+
* model: "gpt-4o-mini",
|
|
33
|
+
* messages: [{ role: "user", content: "Hello" }]
|
|
34
|
+
* },
|
|
35
|
+
* {
|
|
36
|
+
* purpose: "CUSTOMER_SUPPORT",
|
|
37
|
+
* dataClassification: "PUBLIC"
|
|
38
|
+
* }
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function callLlm(callFn, callArgs, options) {
|
|
43
|
+
const args = normalizeArgs(callArgs);
|
|
44
|
+
const wrapped = (0, runtime_1.llmCall)({
|
|
45
|
+
model: options.model,
|
|
46
|
+
dataClassification: options.dataClassification,
|
|
47
|
+
purpose: options.purpose,
|
|
48
|
+
reason: options.reason,
|
|
49
|
+
explainFn: options.explainFn,
|
|
50
|
+
})((...fnArgs) => callFn(...fnArgs));
|
|
51
|
+
return wrapped(...args);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute a tool call with Monora governance (direct callable).
|
|
55
|
+
*
|
|
56
|
+
* This function provides a direct, non-decorator way to instrument tool calls.
|
|
57
|
+
* It wraps the execution with data handling and event logging.
|
|
58
|
+
*
|
|
59
|
+
* @param callFn - The function to execute
|
|
60
|
+
* @param callArgs - Arguments to pass to callFn
|
|
61
|
+
* @param options - Monora governance options
|
|
62
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const result = await monora.callTool(
|
|
67
|
+
* fetchFromDatabase,
|
|
68
|
+
* { customerId: "123" },
|
|
69
|
+
* {
|
|
70
|
+
* toolName: "customer_lookup",
|
|
71
|
+
* purpose: "CUSTOMER_SUPPORT"
|
|
72
|
+
* }
|
|
73
|
+
* );
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function callTool(callFn, callArgs, options) {
|
|
77
|
+
const args = normalizeArgs(callArgs);
|
|
78
|
+
const wrapped = (0, runtime_1.toolCall)({
|
|
79
|
+
toolName: options.toolName,
|
|
80
|
+
dataClassification: options.dataClassification,
|
|
81
|
+
purpose: options.purpose,
|
|
82
|
+
reason: options.reason,
|
|
83
|
+
})((...fnArgs) => callFn(...fnArgs));
|
|
84
|
+
return wrapped(...args);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Execute an agent step with Monora governance (direct callable).
|
|
88
|
+
*
|
|
89
|
+
* This function provides a direct, non-decorator way to instrument agent steps.
|
|
90
|
+
* It wraps the execution with data handling, step counting, and event logging.
|
|
91
|
+
*
|
|
92
|
+
* @param callFn - The function to execute
|
|
93
|
+
* @param callArgs - Arguments to pass to callFn
|
|
94
|
+
* @param options - Monora governance options
|
|
95
|
+
* @returns The result from callFn (preserves sync/async nature)
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const thought = await monora.callAgent(
|
|
100
|
+
* reasoningFunction,
|
|
101
|
+
* { context: { customer: "Acme Corp" } },
|
|
102
|
+
* {
|
|
103
|
+
* agentName: "sales_agent",
|
|
104
|
+
* stepType: "planning",
|
|
105
|
+
* purpose: "SALES_AUTOMATION"
|
|
106
|
+
* }
|
|
107
|
+
* );
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
function callAgent(callFn, callArgs, options) {
|
|
111
|
+
const args = normalizeArgs(callArgs);
|
|
112
|
+
const wrapped = (0, runtime_1.agentStep)({
|
|
113
|
+
agentName: options.agentName,
|
|
114
|
+
stepType: options.stepType,
|
|
115
|
+
dataClassification: options.dataClassification,
|
|
116
|
+
purpose: options.purpose,
|
|
117
|
+
})((...fnArgs) => callFn(...fnArgs));
|
|
118
|
+
return wrapped(...args);
|
|
119
|
+
}
|
|
120
|
+
function normalizeArgs(value) {
|
|
121
|
+
if (value === undefined) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
return Array.isArray(value) ? value : [value];
|
|
125
|
+
}
|
package/dist/attestation.d.ts
CHANGED
|
@@ -16,5 +16,30 @@ export declare function signReportGpg(reportBytes: Buffer, options?: {
|
|
|
16
16
|
keyId?: string;
|
|
17
17
|
gpgHome?: string;
|
|
18
18
|
}): SignatureResult;
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Options for building attestation bundles.
|
|
21
|
+
*/
|
|
22
|
+
export interface AttestationBundleOptions {
|
|
23
|
+
chainProof?: Record<string, any>;
|
|
24
|
+
eventsDigest?: Record<string, any>;
|
|
25
|
+
traceInfo?: Record<string, any>;
|
|
26
|
+
events?: Array<Record<string, any>>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build attestation bundle with optional chain proof (v2.0.0 format).
|
|
30
|
+
*
|
|
31
|
+
* @param report - Compliance report
|
|
32
|
+
* @param reportBytes - Serialized report
|
|
33
|
+
* @param signature - Optional GPG signature
|
|
34
|
+
* @param options - Optional v2.0.0 fields (chainProof, eventsDigest, traceInfo, events)
|
|
35
|
+
* @returns Trust proof bundle (v2.0.0 format if chainProof provided, v1.0.0 otherwise)
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildAttestationBundle(report: Record<string, any>, reportBytes: Buffer, signature?: SignatureResult, options?: AttestationBundleOptions): Record<string, any>;
|
|
38
|
+
/**
|
|
39
|
+
* Extract key compliance metrics for bundle.
|
|
40
|
+
*
|
|
41
|
+
* @param report - Full compliance report
|
|
42
|
+
* @returns Compact compliance summary
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractComplianceSummary(report: Record<string, any>): Record<string, any>;
|
|
20
45
|
//# sourceMappingURL=attestation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAEnE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,eAAe,CAsDjB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAEnE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,eAAe,CAsDjB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CACrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,eAAe,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GACjC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiFrB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAYzF"}
|