@principal-ai/principal-view-core 0.6.3 → 0.7.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/dist/ConfigurationLoader.js +2 -1
- package/dist/ConfigurationLoader.js.map +1 -1
- package/dist/ConfigurationValidator.js.map +1 -1
- package/dist/EventProcessor.js.map +1 -1
- package/dist/EventRecorderService.js.map +1 -1
- package/dist/LibraryLoader.js.map +1 -1
- package/dist/PathBasedEventProcessor.js.map +1 -1
- package/dist/SessionManager.js +1 -1
- package/dist/SessionManager.js.map +1 -1
- package/dist/ValidationEngine.js.map +1 -1
- package/dist/cli/codegen.js.map +1 -1
- package/dist/codegen/type-generator.js.map +1 -1
- package/dist/codegen/usage-example.js.map +1 -1
- package/dist/helpers/GraphInstrumentationHelper.js +2 -2
- package/dist/helpers/GraphInstrumentationHelper.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/narrative/example.d.ts +11 -0
- package/dist/narrative/example.d.ts.map +1 -0
- package/dist/narrative/example.js +331 -0
- package/dist/narrative/example.js.map +1 -0
- package/dist/narrative/index.d.ts +12 -0
- package/dist/narrative/index.d.ts.map +1 -0
- package/dist/narrative/index.js +14 -0
- package/dist/narrative/index.js.map +1 -0
- package/dist/narrative/scenario-matcher.d.ts +87 -0
- package/dist/narrative/scenario-matcher.d.ts.map +1 -0
- package/dist/narrative/scenario-matcher.js +269 -0
- package/dist/narrative/scenario-matcher.js.map +1 -0
- package/dist/narrative/template-parser.d.ts +33 -0
- package/dist/narrative/template-parser.d.ts.map +1 -0
- package/dist/narrative/template-parser.js +288 -0
- package/dist/narrative/template-parser.js.map +1 -0
- package/dist/narrative/template-renderer.d.ts +18 -0
- package/dist/narrative/template-renderer.d.ts.map +1 -0
- package/dist/narrative/template-renderer.js +367 -0
- package/dist/narrative/template-renderer.js.map +1 -0
- package/dist/narrative/types.d.ts +268 -0
- package/dist/narrative/types.d.ts.map +1 -0
- package/dist/narrative/types.js +10 -0
- package/dist/narrative/types.js.map +1 -0
- package/dist/rules/config.js.map +1 -1
- package/dist/rules/engine.js.map +1 -1
- package/dist/rules/implementations/connection-type-references.js.map +1 -1
- package/dist/rules/implementations/dead-end-states.js.map +1 -1
- package/dist/rules/implementations/library-node-type-match.js.map +1 -1
- package/dist/rules/implementations/minimum-node-sources.js.map +1 -1
- package/dist/rules/implementations/no-unknown-fields.js.map +1 -1
- package/dist/rules/implementations/orphaned-edge-types.js.map +1 -1
- package/dist/rules/implementations/orphaned-node-types.js.map +1 -1
- package/dist/rules/implementations/required-metadata.js.map +1 -1
- package/dist/rules/implementations/state-transition-references.js.map +1 -1
- package/dist/rules/implementations/unreachable-states.js.map +1 -1
- package/dist/rules/implementations/valid-action-patterns.js.map +1 -1
- package/dist/rules/implementations/valid-color-format.js.map +1 -1
- package/dist/rules/implementations/valid-edge-types.js.map +1 -1
- package/dist/rules/implementations/valid-node-types.js.map +1 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/telemetry/coverage.js.map +1 -1
- package/dist/telemetry/event-validator.js.map +1 -1
- package/dist/types/audit.js.map +1 -1
- package/dist/types/canvas.js +5 -5
- package/dist/types/canvas.js.map +1 -1
- package/dist/types/otel.js.map +1 -1
- package/dist/types/resource-match.js.map +1 -1
- package/dist/utils/CanvasConverter.js.map +1 -1
- package/dist/utils/GraphConverter.js.map +1 -1
- package/dist/utils/LibraryConverter.js.map +1 -1
- package/dist/utils/PathMatcher.js.map +1 -1
- package/dist/utils/TraceToCanvas.js +7 -7
- package/dist/utils/TraceToCanvas.js.map +1 -1
- package/dist/utils/YamlParser.js.map +1 -1
- package/package.json +15 -15
- package/src/index.ts +31 -13
- package/src/narrative/README.md +381 -0
- package/src/narrative/__tests__/scenario-matcher.test.ts +368 -0
- package/src/narrative/__tests__/template-parser.test.ts +235 -0
- package/src/narrative/__tests__/template-renderer.test.ts +377 -0
- package/src/narrative/example.ts +349 -0
- package/src/narrative/index.ts +35 -0
- package/src/narrative/scenario-matcher.ts +331 -0
- package/src/narrative/template-parser.ts +298 -0
- package/src/narrative/template-renderer.ts +423 -0
- package/src/narrative/types.ts +368 -0
- package/src/utils/GraphConverter.test.ts +0 -79
- package/dist/utils/ExecutionFileDiscovery.d.ts +0 -206
- package/dist/utils/ExecutionFileDiscovery.d.ts.map +0 -1
- package/dist/utils/ExecutionFileDiscovery.js +0 -340
- package/dist/utils/ExecutionFileDiscovery.js.map +0 -1
- package/src/utils/ExecutionFileDiscovery.ts +0 -522
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrative Template System Types
|
|
3
|
+
*
|
|
4
|
+
* Types for transforming OpenTelemetry event streams into human-readable
|
|
5
|
+
* execution narratives based on OTEL canvas definitions.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/NARRATIVE_TEMPLATES_DESIGN.md
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { OtelLog, OtelSpan } from '../types/otel';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Combined OTEL signal type for narrative processing
|
|
14
|
+
*/
|
|
15
|
+
export type OtelSignal = OtelSpan | OtelLog | OtelEvent;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generic OTEL event (spans can also be treated as events)
|
|
19
|
+
*/
|
|
20
|
+
export interface OtelEvent {
|
|
21
|
+
/** Event name (e.g., "conversion.started", "log.error") */
|
|
22
|
+
name: string;
|
|
23
|
+
|
|
24
|
+
/** Event timestamp */
|
|
25
|
+
timestamp: string | number;
|
|
26
|
+
|
|
27
|
+
/** Event type (span, log, metric) */
|
|
28
|
+
type?: 'span' | 'log' | 'metric';
|
|
29
|
+
|
|
30
|
+
/** Event attributes */
|
|
31
|
+
attributes?: Record<string, string | number | boolean>;
|
|
32
|
+
|
|
33
|
+
/** Trace correlation */
|
|
34
|
+
traceId?: string;
|
|
35
|
+
spanId?: string;
|
|
36
|
+
parentSpanId?: string;
|
|
37
|
+
|
|
38
|
+
/** For logs: severity information */
|
|
39
|
+
severityText?: string;
|
|
40
|
+
severityNumber?: number;
|
|
41
|
+
|
|
42
|
+
/** For logs: message body */
|
|
43
|
+
body?: string | Record<string, unknown>;
|
|
44
|
+
|
|
45
|
+
/** For spans: duration */
|
|
46
|
+
duration?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Narrative template definition
|
|
51
|
+
*
|
|
52
|
+
* References an .otel.canvas file and defines how to render
|
|
53
|
+
* execution events into human-readable narratives.
|
|
54
|
+
*/
|
|
55
|
+
export interface NarrativeTemplate {
|
|
56
|
+
// Metadata
|
|
57
|
+
/** Schema version (e.g., "1.0.0") */
|
|
58
|
+
version: string;
|
|
59
|
+
|
|
60
|
+
/** Reference to .otel.canvas file */
|
|
61
|
+
canvas: string;
|
|
62
|
+
|
|
63
|
+
/** Human-readable template name */
|
|
64
|
+
name: string;
|
|
65
|
+
|
|
66
|
+
/** Purpose of this narrative view */
|
|
67
|
+
description: string;
|
|
68
|
+
|
|
69
|
+
// Rendering configuration
|
|
70
|
+
/** How to structure the narrative */
|
|
71
|
+
mode: NarrativeMode;
|
|
72
|
+
|
|
73
|
+
/** Scenario selection strategy */
|
|
74
|
+
scenarioSelection: 'first-match' | 'manual';
|
|
75
|
+
|
|
76
|
+
// OTEL signal integration
|
|
77
|
+
/** Show logs associated with each span (span-tree mode) */
|
|
78
|
+
showLogsPerSpan?: boolean;
|
|
79
|
+
|
|
80
|
+
/** Mix spans/logs by timestamp (timeline mode) */
|
|
81
|
+
interleaveSignals?: boolean;
|
|
82
|
+
|
|
83
|
+
// Scenario definitions
|
|
84
|
+
/** Mutually exclusive narrative scenarios */
|
|
85
|
+
scenarios: NarrativeScenario[];
|
|
86
|
+
|
|
87
|
+
// Formatting options
|
|
88
|
+
/** Display formatting preferences */
|
|
89
|
+
formatting?: FormattingOptions;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Narrative rendering mode
|
|
94
|
+
*/
|
|
95
|
+
export type NarrativeMode =
|
|
96
|
+
| 'span-tree' // Follow OTEL span hierarchy (uses parent-child relationships)
|
|
97
|
+
| 'timeline' // Chronological order (sorts all signals by timestamp)
|
|
98
|
+
| 'summary-only'; // Just show summary, skip event details
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Narrative scenario definition
|
|
102
|
+
*
|
|
103
|
+
* Scenarios are mutually exclusive narrative templates selected
|
|
104
|
+
* based on which events occurred during execution.
|
|
105
|
+
*/
|
|
106
|
+
export interface NarrativeScenario {
|
|
107
|
+
// Identification
|
|
108
|
+
/** Unique scenario identifier (kebab-case) */
|
|
109
|
+
id: string;
|
|
110
|
+
|
|
111
|
+
/** Selection priority (lower = higher priority, 1 = highest) */
|
|
112
|
+
priority: number;
|
|
113
|
+
|
|
114
|
+
/** What this scenario represents */
|
|
115
|
+
description: string;
|
|
116
|
+
|
|
117
|
+
// Matching logic
|
|
118
|
+
/** Conditions that must be met for this scenario to match */
|
|
119
|
+
condition: ScenarioCondition;
|
|
120
|
+
|
|
121
|
+
// Template content
|
|
122
|
+
/** Narrative template content */
|
|
123
|
+
template: ScenarioTemplate;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Scenario matching conditions
|
|
128
|
+
*/
|
|
129
|
+
export interface ScenarioCondition {
|
|
130
|
+
// Event requirements
|
|
131
|
+
/** Must have these events (supports glob patterns like "*.error") */
|
|
132
|
+
requires?: string[];
|
|
133
|
+
|
|
134
|
+
/** Must NOT have these events (supports glob patterns) */
|
|
135
|
+
excludes?: string[];
|
|
136
|
+
|
|
137
|
+
// Attribute assertions
|
|
138
|
+
/** Assertions on event attributes */
|
|
139
|
+
assertions?: Record<string, Assertion>;
|
|
140
|
+
|
|
141
|
+
// Special conditions
|
|
142
|
+
/** Always matches (use as fallback) */
|
|
143
|
+
default?: boolean;
|
|
144
|
+
|
|
145
|
+
/** Match if ANY requires condition met (instead of ALL) */
|
|
146
|
+
any?: boolean;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Attribute assertion operators
|
|
151
|
+
*/
|
|
152
|
+
export interface Assertion {
|
|
153
|
+
/** Greater than */
|
|
154
|
+
$gt?: number;
|
|
155
|
+
|
|
156
|
+
/** Greater than or equal */
|
|
157
|
+
$gte?: number;
|
|
158
|
+
|
|
159
|
+
/** Less than */
|
|
160
|
+
$lt?: number;
|
|
161
|
+
|
|
162
|
+
/** Less than or equal */
|
|
163
|
+
$lte?: number;
|
|
164
|
+
|
|
165
|
+
/** Equal to */
|
|
166
|
+
$eq?: string | number | boolean;
|
|
167
|
+
|
|
168
|
+
/** Not equal to */
|
|
169
|
+
$ne?: string | number | boolean;
|
|
170
|
+
|
|
171
|
+
/** Attribute exists/doesn't exist */
|
|
172
|
+
$exists?: boolean;
|
|
173
|
+
|
|
174
|
+
/** Value in array */
|
|
175
|
+
$in?: (string | number | boolean)[];
|
|
176
|
+
|
|
177
|
+
/** Value not in array */
|
|
178
|
+
$nin?: (string | number | boolean)[];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Scenario template content
|
|
183
|
+
*/
|
|
184
|
+
export interface ScenarioTemplate {
|
|
185
|
+
/** Opening text */
|
|
186
|
+
introduction?: string;
|
|
187
|
+
|
|
188
|
+
/** Event/log name -> template mapping */
|
|
189
|
+
events?: Record<string, string>;
|
|
190
|
+
|
|
191
|
+
/** Optional: separate log templates by severity */
|
|
192
|
+
logs?: LogTemplates;
|
|
193
|
+
|
|
194
|
+
/** Narrative flow steps */
|
|
195
|
+
flow?: Array<string | FlowDirective>;
|
|
196
|
+
|
|
197
|
+
/** Closing text */
|
|
198
|
+
summary?: string;
|
|
199
|
+
|
|
200
|
+
/** For span-tree mode: span rendering template */
|
|
201
|
+
span?: string;
|
|
202
|
+
|
|
203
|
+
/** For span-tree mode: how to recurse into children */
|
|
204
|
+
children?: 'recurse' | 'ignore';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Log templates by severity level
|
|
209
|
+
*/
|
|
210
|
+
export interface LogTemplates {
|
|
211
|
+
/** Template for TRACE logs (severity 1-4) */
|
|
212
|
+
trace?: string;
|
|
213
|
+
|
|
214
|
+
/** Template for DEBUG logs (severity 5-8) */
|
|
215
|
+
debug?: string;
|
|
216
|
+
|
|
217
|
+
/** Template for INFO logs (severity 9-12) */
|
|
218
|
+
info?: string;
|
|
219
|
+
|
|
220
|
+
/** Template for WARN logs (severity 13-16) */
|
|
221
|
+
warn?: string;
|
|
222
|
+
|
|
223
|
+
/** Template for ERROR logs (severity 17-20) */
|
|
224
|
+
error?: string;
|
|
225
|
+
|
|
226
|
+
/** Template for FATAL logs (severity 21-24) */
|
|
227
|
+
fatal?: string;
|
|
228
|
+
|
|
229
|
+
/** Fallback for any log */
|
|
230
|
+
default?: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Flow directive for narrative generation
|
|
235
|
+
*/
|
|
236
|
+
export interface FlowDirective {
|
|
237
|
+
/** Iterate over collection (e.g., "violations", "logs.filter(l => l.severityNumber >= 17)") */
|
|
238
|
+
forEach?: string;
|
|
239
|
+
|
|
240
|
+
/** Template for each item in iteration */
|
|
241
|
+
template?: string;
|
|
242
|
+
|
|
243
|
+
/** Conditional expression */
|
|
244
|
+
if?: string;
|
|
245
|
+
|
|
246
|
+
/** Template if condition true */
|
|
247
|
+
then?: string;
|
|
248
|
+
|
|
249
|
+
/** Template if condition false */
|
|
250
|
+
else?: string;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Formatting options for narrative rendering
|
|
255
|
+
*/
|
|
256
|
+
export interface FormattingOptions {
|
|
257
|
+
/** Indentation per hierarchy level (default: " ") */
|
|
258
|
+
indentPerLevel?: string;
|
|
259
|
+
|
|
260
|
+
/** Timestamp format (default: "HH:mm:ss.SSS") */
|
|
261
|
+
timestampFormat?: string;
|
|
262
|
+
|
|
263
|
+
/** Show timestamps in output (default: false) */
|
|
264
|
+
showTimestamps?: boolean;
|
|
265
|
+
|
|
266
|
+
/** Show duration information (default: true) */
|
|
267
|
+
showDuration?: boolean;
|
|
268
|
+
|
|
269
|
+
/** Show span IDs (useful for debugging) (default: false) */
|
|
270
|
+
showSpanIds?: boolean;
|
|
271
|
+
|
|
272
|
+
/** Which attributes to show: none, matched (from template), or all (default: 'matched') */
|
|
273
|
+
showAttributes?: 'none' | 'matched' | 'all';
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Narrative rendering context
|
|
278
|
+
*
|
|
279
|
+
* Contains all data needed to render a narrative from events.
|
|
280
|
+
*/
|
|
281
|
+
export interface NarrativeContext {
|
|
282
|
+
/** The narrative template being used */
|
|
283
|
+
template: NarrativeTemplate;
|
|
284
|
+
|
|
285
|
+
/** Selected scenario */
|
|
286
|
+
scenario: NarrativeScenario;
|
|
287
|
+
|
|
288
|
+
/** All collected events */
|
|
289
|
+
events: OtelEvent[];
|
|
290
|
+
|
|
291
|
+
/** Span tree (for span-tree mode) */
|
|
292
|
+
spanTree?: SpanTreeNode[];
|
|
293
|
+
|
|
294
|
+
/** Computed aggregate values */
|
|
295
|
+
aggregates?: Record<string, unknown>;
|
|
296
|
+
|
|
297
|
+
/** Formatting options */
|
|
298
|
+
formatting: FormattingOptions;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Span tree node for hierarchical rendering
|
|
303
|
+
*/
|
|
304
|
+
export interface SpanTreeNode {
|
|
305
|
+
/** The span event */
|
|
306
|
+
span: OtelEvent;
|
|
307
|
+
|
|
308
|
+
/** Child spans */
|
|
309
|
+
children: SpanTreeNode[];
|
|
310
|
+
|
|
311
|
+
/** Associated logs (if showLogsPerSpan is true) */
|
|
312
|
+
logs?: OtelEvent[];
|
|
313
|
+
|
|
314
|
+
/** Depth in tree (for indentation) */
|
|
315
|
+
depth: number;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Narrative rendering result
|
|
320
|
+
*/
|
|
321
|
+
export interface NarrativeResult {
|
|
322
|
+
/** Rendered narrative text */
|
|
323
|
+
text: string;
|
|
324
|
+
|
|
325
|
+
/** Scenario that was selected */
|
|
326
|
+
scenarioId: string;
|
|
327
|
+
|
|
328
|
+
/** Metadata about the rendering */
|
|
329
|
+
metadata: {
|
|
330
|
+
/** Number of events processed */
|
|
331
|
+
eventCount: number;
|
|
332
|
+
|
|
333
|
+
/** Number of spans */
|
|
334
|
+
spanCount: number;
|
|
335
|
+
|
|
336
|
+
/** Number of logs */
|
|
337
|
+
logCount: number;
|
|
338
|
+
|
|
339
|
+
/** Time range of events */
|
|
340
|
+
timeRange?: {
|
|
341
|
+
start: string | number;
|
|
342
|
+
end: string | number;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/** Any errors encountered during rendering */
|
|
346
|
+
errors?: string[];
|
|
347
|
+
|
|
348
|
+
/** Any warnings encountered during rendering */
|
|
349
|
+
warnings?: string[];
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Scenario matching result
|
|
355
|
+
*/
|
|
356
|
+
export interface ScenarioMatchResult {
|
|
357
|
+
/** The matched scenario */
|
|
358
|
+
scenario: NarrativeScenario;
|
|
359
|
+
|
|
360
|
+
/** Whether this was the default/fallback scenario */
|
|
361
|
+
isDefault: boolean;
|
|
362
|
+
|
|
363
|
+
/** All applicable scenarios (for manual selection UI) */
|
|
364
|
+
applicableScenarios: NarrativeScenario[];
|
|
365
|
+
|
|
366
|
+
/** Reasons why other scenarios didn't match */
|
|
367
|
+
matchReasons?: Record<string, string>;
|
|
368
|
+
}
|
|
@@ -9,8 +9,6 @@ import {
|
|
|
9
9
|
markTestFailed,
|
|
10
10
|
setSpanAttribute,
|
|
11
11
|
exportSpans,
|
|
12
|
-
log,
|
|
13
|
-
recordLog,
|
|
14
12
|
} from '../../test/otel-setup';
|
|
15
13
|
|
|
16
14
|
describe('GraphConverter', () => {
|
|
@@ -26,25 +24,11 @@ describe('GraphConverter', () => {
|
|
|
26
24
|
});
|
|
27
25
|
|
|
28
26
|
try {
|
|
29
|
-
// TRACE log at test start (automatically correlated with testSpan)
|
|
30
|
-
log('TRACE', 'Entering test case for simple config conversion', {
|
|
31
|
-
'service.name': 'graph-converter-service',
|
|
32
|
-
'service.version': '1.0.0',
|
|
33
|
-
});
|
|
34
|
-
|
|
35
27
|
// Setup - record as event
|
|
36
28
|
addEvent(testSpan, 'setup.started', {
|
|
37
29
|
description: 'Creating test configuration with 2 nodes and 1 edge',
|
|
38
30
|
});
|
|
39
31
|
|
|
40
|
-
// INFO log during setup
|
|
41
|
-
log('INFO', 'Initializing test configuration', {
|
|
42
|
-
'service.name': 'graph-converter-service',
|
|
43
|
-
}, {
|
|
44
|
-
'config.nodeCount': 2,
|
|
45
|
-
'config.edgeCount': 1,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
32
|
const config: PathBasedGraphConfiguration = {
|
|
49
33
|
metadata: {
|
|
50
34
|
name: 'Test Config',
|
|
@@ -86,15 +70,6 @@ describe('GraphConverter', () => {
|
|
|
86
70
|
'config.edges': 1,
|
|
87
71
|
});
|
|
88
72
|
|
|
89
|
-
// DEBUG log with structured data after setup
|
|
90
|
-
log('DEBUG', {
|
|
91
|
-
phase: 'setup-complete',
|
|
92
|
-
nodeTypes: Object.keys(config.nodeTypes),
|
|
93
|
-
edgeTypes: Object.keys(config.edgeTypes),
|
|
94
|
-
}, {
|
|
95
|
-
'service.name': 'graph-converter-service',
|
|
96
|
-
});
|
|
97
|
-
|
|
98
73
|
// Execution - record as event
|
|
99
74
|
// Note: execution happens in GraphConverter.ts, not the test file
|
|
100
75
|
addEvent(testSpan, 'execution.started', {
|
|
@@ -103,25 +78,8 @@ describe('GraphConverter', () => {
|
|
|
103
78
|
'code.lineno': 15,
|
|
104
79
|
});
|
|
105
80
|
|
|
106
|
-
// INFO log before conversion
|
|
107
|
-
log('INFO', 'Starting graph conversion process', {
|
|
108
|
-
'service.name': 'graph-converter-service',
|
|
109
|
-
}, {
|
|
110
|
-
'operation': 'configToGraph',
|
|
111
|
-
'inputSize.bytes': JSON.stringify(config).length,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
81
|
const result = GraphConverter.configToGraph(config);
|
|
115
82
|
|
|
116
|
-
// DEBUG log after conversion with result details
|
|
117
|
-
log('DEBUG', 'Conversion completed successfully', {
|
|
118
|
-
'service.name': 'graph-converter-service',
|
|
119
|
-
}, {
|
|
120
|
-
'output.nodeCount': result.nodes.length,
|
|
121
|
-
'output.edgeCount': result.edges.length,
|
|
122
|
-
'processingTime.ms': 5,
|
|
123
|
-
});
|
|
124
|
-
|
|
125
83
|
addEvent(testSpan, 'execution.complete', {
|
|
126
84
|
'result.nodes.count': result.nodes.length,
|
|
127
85
|
'result.edges.count': result.edges.length,
|
|
@@ -134,13 +92,6 @@ describe('GraphConverter', () => {
|
|
|
134
92
|
assertions: 'Verifying nodes and edges structure',
|
|
135
93
|
});
|
|
136
94
|
|
|
137
|
-
// INFO log at assertion phase
|
|
138
|
-
log('INFO', 'Running assertions on converted graph', {
|
|
139
|
-
'service.name': 'graph-converter-service',
|
|
140
|
-
}, {
|
|
141
|
-
'totalAssertions': 11,
|
|
142
|
-
});
|
|
143
|
-
|
|
144
95
|
expect(result.nodes).toHaveLength(2);
|
|
145
96
|
expect(result.edges).toHaveLength(1);
|
|
146
97
|
|
|
@@ -165,24 +116,8 @@ describe('GraphConverter', () => {
|
|
|
165
116
|
'assertions.failed': 0,
|
|
166
117
|
});
|
|
167
118
|
|
|
168
|
-
// INFO log on successful test completion
|
|
169
|
-
log('INFO', 'All assertions passed - test successful', {
|
|
170
|
-
'service.name': 'graph-converter-service',
|
|
171
|
-
}, {
|
|
172
|
-
'test.status': 'passed',
|
|
173
|
-
'test.duration.ms': Date.now() - testSpan.startTime,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
119
|
markTestPassed(testSpan);
|
|
177
120
|
} catch (error) {
|
|
178
|
-
// ERROR log on failure
|
|
179
|
-
log('ERROR', `Test failed: ${(error as Error).message}`, {
|
|
180
|
-
'service.name': 'graph-converter-service',
|
|
181
|
-
}, {
|
|
182
|
-
'test.status': 'failed',
|
|
183
|
-
'error.type': (error as Error).name,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
121
|
addEvent(testSpan, 'test.failed', {
|
|
187
122
|
error: (error as Error).message,
|
|
188
123
|
});
|
|
@@ -190,20 +125,6 @@ describe('GraphConverter', () => {
|
|
|
190
125
|
throw error;
|
|
191
126
|
} finally {
|
|
192
127
|
endSpan(testSpan);
|
|
193
|
-
|
|
194
|
-
// Uncorrelated log after span ends (simulating cleanup/background task)
|
|
195
|
-
recordLog({
|
|
196
|
-
severity: 'DEBUG',
|
|
197
|
-
body: 'Test cleanup completed',
|
|
198
|
-
resource: {
|
|
199
|
-
'service.name': 'test-cleanup-service',
|
|
200
|
-
'cleanup.type': 'post-test',
|
|
201
|
-
},
|
|
202
|
-
attributes: {
|
|
203
|
-
'test.name': 'should convert simple config to nodes and edges',
|
|
204
|
-
},
|
|
205
|
-
// No traceId/spanId - this is an uncorrelated log
|
|
206
|
-
});
|
|
207
128
|
}
|
|
208
129
|
});
|
|
209
130
|
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Execution File Discovery
|
|
3
|
-
*
|
|
4
|
-
* Discovers execution artifacts and canvas files in a repository with monorepo awareness.
|
|
5
|
-
* Uses codebase-composition (browser-safe export) to intelligently detect package boundaries
|
|
6
|
-
* and workspace patterns.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Represents a discovered execution artifact file
|
|
10
|
-
*/
|
|
11
|
-
export interface ExecutionFile {
|
|
12
|
-
/** Unique identifier for this execution */
|
|
13
|
-
id: string;
|
|
14
|
-
/** Display name for this execution */
|
|
15
|
-
name: string;
|
|
16
|
-
/** Full file path (relative to repository root) */
|
|
17
|
-
path: string;
|
|
18
|
-
/** Canvas basename (without extension) that this execution is linked to */
|
|
19
|
-
canvasBasename: string;
|
|
20
|
-
/** Package context if this execution belongs to a specific package */
|
|
21
|
-
packageContext?: PackageContext;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Represents a discovered canvas file
|
|
25
|
-
*/
|
|
26
|
-
export interface CanvasFile {
|
|
27
|
-
/** Unique identifier for this canvas */
|
|
28
|
-
id: string;
|
|
29
|
-
/** Display name for this canvas */
|
|
30
|
-
name: string;
|
|
31
|
-
/** Full file path (relative to repository root) */
|
|
32
|
-
path: string;
|
|
33
|
-
/** Canvas basename (without .otel.canvas or .canvas extension) */
|
|
34
|
-
basename: string;
|
|
35
|
-
/** Package context if this canvas belongs to a specific package */
|
|
36
|
-
packageContext?: PackageContext;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Package context for execution/canvas files
|
|
40
|
-
*/
|
|
41
|
-
export interface PackageContext {
|
|
42
|
-
/** Package name (from package.json, Cargo.toml, etc.) */
|
|
43
|
-
name: string;
|
|
44
|
-
/** Package directory path (relative to repository root) */
|
|
45
|
-
packagePath: string;
|
|
46
|
-
/** Package type (npm, cargo, go, etc.) */
|
|
47
|
-
packageType?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Execution artifact metadata
|
|
51
|
-
*/
|
|
52
|
-
export interface ExecutionMetadata {
|
|
53
|
-
name: string;
|
|
54
|
-
canvasName?: string;
|
|
55
|
-
exportedAt?: string;
|
|
56
|
-
source?: string;
|
|
57
|
-
framework?: string;
|
|
58
|
-
status?: 'success' | 'error' | 'OK';
|
|
59
|
-
spanCount: number;
|
|
60
|
-
eventCount: number;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Execution span structure
|
|
64
|
-
*/
|
|
65
|
-
export interface ExecutionSpan {
|
|
66
|
-
id: string;
|
|
67
|
-
name: string;
|
|
68
|
-
startTime: number;
|
|
69
|
-
endTime?: number;
|
|
70
|
-
duration?: number;
|
|
71
|
-
status?: string;
|
|
72
|
-
attributes?: Record<string, any>;
|
|
73
|
-
events: Array<{
|
|
74
|
-
time: number;
|
|
75
|
-
name: string;
|
|
76
|
-
attributes?: Record<string, any>;
|
|
77
|
-
}>;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Execution artifact file structure
|
|
81
|
-
*/
|
|
82
|
-
export interface ExecutionArtifact {
|
|
83
|
-
metadata?: {
|
|
84
|
-
canvasName?: string;
|
|
85
|
-
exportedAt?: string;
|
|
86
|
-
source?: string;
|
|
87
|
-
framework?: string;
|
|
88
|
-
status?: 'success' | 'error';
|
|
89
|
-
};
|
|
90
|
-
spans: ExecutionSpan[];
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* File tree entry for discovery
|
|
94
|
-
*/
|
|
95
|
-
export interface FileTreeEntry {
|
|
96
|
-
path?: string;
|
|
97
|
-
relativePath?: string;
|
|
98
|
-
name?: string;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Options for execution file discovery
|
|
102
|
-
*/
|
|
103
|
-
export interface DiscoveryOptions {
|
|
104
|
-
/** Whether to include package-level .principal-views folders */
|
|
105
|
-
includePackagePrincipalViews?: boolean;
|
|
106
|
-
/** Custom execution folder names (defaults to ['__executions__']) */
|
|
107
|
-
executionFolders?: string[];
|
|
108
|
-
/** Custom canvas extensions (defaults to ['.otel.canvas']) */
|
|
109
|
-
canvasExtensions?: string[];
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Execution File Discovery Engine
|
|
113
|
-
*
|
|
114
|
-
* Discovers execution artifacts and canvas files using monorepo-aware logic.
|
|
115
|
-
*/
|
|
116
|
-
export declare class ExecutionFileDiscovery {
|
|
117
|
-
private packageLayerModule;
|
|
118
|
-
private options;
|
|
119
|
-
constructor(options?: DiscoveryOptions);
|
|
120
|
-
/**
|
|
121
|
-
* Find all execution artifact files in the repository
|
|
122
|
-
*/
|
|
123
|
-
findExecutionFiles(files: FileTreeEntry[]): Promise<ExecutionFile[]>;
|
|
124
|
-
/**
|
|
125
|
-
* Find all canvas files in the repository
|
|
126
|
-
*/
|
|
127
|
-
findCanvasFiles(files: FileTreeEntry[]): Promise<CanvasFile[]>;
|
|
128
|
-
/**
|
|
129
|
-
* Find execution artifact for a given canvas
|
|
130
|
-
* Now package-aware - can disambiguate between packages
|
|
131
|
-
*/
|
|
132
|
-
findExecutionForCanvas(canvas: CanvasFile, executionFiles: ExecutionFile[]): ExecutionFile | null;
|
|
133
|
-
/**
|
|
134
|
-
* Find canvas file for a given execution
|
|
135
|
-
*/
|
|
136
|
-
findCanvasForExecution(execution: ExecutionFile, canvasFiles: CanvasFile[]): CanvasFile | null;
|
|
137
|
-
/**
|
|
138
|
-
* Parse execution artifact JSON
|
|
139
|
-
*/
|
|
140
|
-
static parseExecutionArtifact(content: string): ExecutionArtifact;
|
|
141
|
-
/**
|
|
142
|
-
* Get spans from an artifact
|
|
143
|
-
*/
|
|
144
|
-
static getSpans(artifact: ExecutionArtifact): ExecutionSpan[];
|
|
145
|
-
/**
|
|
146
|
-
* Extract metadata from an execution artifact
|
|
147
|
-
*/
|
|
148
|
-
static getExecutionMetadata(artifact: ExecutionArtifact): ExecutionMetadata;
|
|
149
|
-
/**
|
|
150
|
-
* Detect packages using codebase-composition
|
|
151
|
-
*/
|
|
152
|
-
private detectPackages;
|
|
153
|
-
/**
|
|
154
|
-
* Convert file entries to file tree format for codebase-composition
|
|
155
|
-
*/
|
|
156
|
-
private convertToFileTree;
|
|
157
|
-
/**
|
|
158
|
-
* Find executions in a specific package
|
|
159
|
-
*/
|
|
160
|
-
private findExecutionsInPackage;
|
|
161
|
-
/**
|
|
162
|
-
* Find executions in root-level locations
|
|
163
|
-
*/
|
|
164
|
-
private findExecutionsInRoot;
|
|
165
|
-
/**
|
|
166
|
-
* Find canvas files in a specific directory
|
|
167
|
-
*/
|
|
168
|
-
private findCanvasesInDirectory;
|
|
169
|
-
/**
|
|
170
|
-
* Create package context from PackageLayer
|
|
171
|
-
*/
|
|
172
|
-
private createPackageContext;
|
|
173
|
-
/**
|
|
174
|
-
* Check if filename is an execution file
|
|
175
|
-
*/
|
|
176
|
-
private isExecutionFile;
|
|
177
|
-
/**
|
|
178
|
-
* Check if filename is a canvas file
|
|
179
|
-
*/
|
|
180
|
-
private isCanvasFile;
|
|
181
|
-
/**
|
|
182
|
-
* Extract basename from execution filename
|
|
183
|
-
*/
|
|
184
|
-
private extractExecutionBasename;
|
|
185
|
-
/**
|
|
186
|
-
* Extract basename from canvas filename
|
|
187
|
-
*/
|
|
188
|
-
private extractCanvasBasename;
|
|
189
|
-
/**
|
|
190
|
-
* Format display name from basename (kebab-case to Title Case)
|
|
191
|
-
*/
|
|
192
|
-
private formatDisplayName;
|
|
193
|
-
/**
|
|
194
|
-
* Generate unique ID for execution file
|
|
195
|
-
*/
|
|
196
|
-
private generateExecutionId;
|
|
197
|
-
/**
|
|
198
|
-
* Generate unique ID for canvas file
|
|
199
|
-
*/
|
|
200
|
-
private generateCanvasId;
|
|
201
|
-
/**
|
|
202
|
-
* Sort execution files by package name, then by basename
|
|
203
|
-
*/
|
|
204
|
-
private sortExecutionFiles;
|
|
205
|
-
}
|
|
206
|
-
//# sourceMappingURL=ExecutionFileDiscovery.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ExecutionFileDiscovery.d.ts","sourceRoot":"","sources":["../../src/utils/ExecutionFileDiscovery.ts"],"names":[],"mappings":"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"}
|