@loongsuite/otel-util-genai 0.1.0-beta.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.
Files changed (103) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +262 -0
  3. package/dist/environment-variables.d.ts +8 -0
  4. package/dist/environment-variables.d.ts.map +1 -0
  5. package/dist/environment-variables.js +21 -0
  6. package/dist/environment-variables.js.map +1 -0
  7. package/dist/event-log/converter.d.ts +19 -0
  8. package/dist/event-log/converter.d.ts.map +1 -0
  9. package/dist/event-log/converter.js +216 -0
  10. package/dist/event-log/converter.js.map +1 -0
  11. package/dist/event-log/field-mapping.d.ts +53 -0
  12. package/dist/event-log/field-mapping.d.ts.map +1 -0
  13. package/dist/event-log/field-mapping.js +400 -0
  14. package/dist/event-log/field-mapping.js.map +1 -0
  15. package/dist/event-log/grouping.d.ts +67 -0
  16. package/dist/event-log/grouping.d.ts.map +1 -0
  17. package/dist/event-log/grouping.js +241 -0
  18. package/dist/event-log/grouping.js.map +1 -0
  19. package/dist/event-log/index.d.ts +5 -0
  20. package/dist/event-log/index.d.ts.map +1 -0
  21. package/dist/event-log/index.js +18 -0
  22. package/dist/event-log/index.js.map +1 -0
  23. package/dist/event-log/parent-context.d.ts +14 -0
  24. package/dist/event-log/parent-context.d.ts.map +1 -0
  25. package/dist/event-log/parent-context.js +45 -0
  26. package/dist/event-log/parent-context.js.map +1 -0
  27. package/dist/event-log/readable-spans.d.ts +36 -0
  28. package/dist/event-log/readable-spans.d.ts.map +1 -0
  29. package/dist/event-log/readable-spans.js +73 -0
  30. package/dist/event-log/readable-spans.js.map +1 -0
  31. package/dist/event-log/types.d.ts +78 -0
  32. package/dist/event-log/types.d.ts.map +1 -0
  33. package/dist/event-log/types.js +35 -0
  34. package/dist/event-log/types.js.map +1 -0
  35. package/dist/extended-environment-variables.d.ts +12 -0
  36. package/dist/extended-environment-variables.d.ts.map +1 -0
  37. package/dist/extended-environment-variables.js +25 -0
  38. package/dist/extended-environment-variables.js.map +1 -0
  39. package/dist/extended-handler.d.ts +50 -0
  40. package/dist/extended-handler.d.ts.map +1 -0
  41. package/dist/extended-handler.js +334 -0
  42. package/dist/extended-handler.js.map +1 -0
  43. package/dist/extended-metrics.d.ts +13 -0
  44. package/dist/extended-metrics.d.ts.map +1 -0
  45. package/dist/extended-metrics.js +27 -0
  46. package/dist/extended-metrics.js.map +1 -0
  47. package/dist/extended-span-utils.d.ts +14 -0
  48. package/dist/extended-span-utils.d.ts.map +1 -0
  49. package/dist/extended-span-utils.js +427 -0
  50. package/dist/extended-span-utils.js.map +1 -0
  51. package/dist/extended-types.d.ts +150 -0
  52. package/dist/extended-types.d.ts.map +1 -0
  53. package/dist/extended-types.js +46 -0
  54. package/dist/extended-types.js.map +1 -0
  55. package/dist/handler.d.ts +23 -0
  56. package/dist/handler.d.ts.map +1 -0
  57. package/dist/handler.js +127 -0
  58. package/dist/handler.js.map +1 -0
  59. package/dist/index.d.ts +22 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +43 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/instruments.d.ts +4 -0
  64. package/dist/instruments.d.ts.map +1 -0
  65. package/dist/instruments.js +37 -0
  66. package/dist/instruments.js.map +1 -0
  67. package/dist/memory/memory-types.d.ts +26 -0
  68. package/dist/memory/memory-types.d.ts.map +1 -0
  69. package/dist/memory/memory-types.js +17 -0
  70. package/dist/memory/memory-types.js.map +1 -0
  71. package/dist/memory/memory-utils.d.ts +7 -0
  72. package/dist/memory/memory-utils.d.ts.map +1 -0
  73. package/dist/memory/memory-utils.js +121 -0
  74. package/dist/memory/memory-utils.js.map +1 -0
  75. package/dist/metrics.d.ts +11 -0
  76. package/dist/metrics.d.ts.map +1 -0
  77. package/dist/metrics.js +77 -0
  78. package/dist/metrics.js.map +1 -0
  79. package/dist/semconv/gen-ai-extended-attributes.d.ts +101 -0
  80. package/dist/semconv/gen-ai-extended-attributes.d.ts.map +1 -0
  81. package/dist/semconv/gen-ai-extended-attributes.js +120 -0
  82. package/dist/semconv/gen-ai-extended-attributes.js.map +1 -0
  83. package/dist/semconv/gen-ai-memory-attributes.d.ts +28 -0
  84. package/dist/semconv/gen-ai-memory-attributes.d.ts.map +1 -0
  85. package/dist/semconv/gen-ai-memory-attributes.js +42 -0
  86. package/dist/semconv/gen-ai-memory-attributes.js.map +1 -0
  87. package/dist/span-utils.d.ts +18 -0
  88. package/dist/span-utils.d.ts.map +1 -0
  89. package/dist/span-utils.js +236 -0
  90. package/dist/span-utils.js.map +1 -0
  91. package/dist/types.d.ts +117 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +33 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/utils.d.ts +8 -0
  96. package/dist/utils.d.ts.map +1 -0
  97. package/dist/utils.js +88 -0
  98. package/dist/utils.js.map +1 -0
  99. package/dist/version.d.ts +2 -0
  100. package/dist/version.d.ts.map +1 -0
  101. package/dist/version.js +2 -0
  102. package/dist/version.js.map +1 -0
  103. package/package.json +72 -0
@@ -0,0 +1,241 @@
1
+ // Copyright The OpenTelemetry Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { EventName, } from "./types.js";
15
+ import { isValidTraceId } from "./parent-context.js";
16
+ import { readNanoMs } from "./field-mapping.js";
17
+ /**
18
+ * Candidate predicate for "user-input hook" llm.request events.
19
+ *
20
+ * Rule: an llm.request that has neither gen_ai.step.id nor
21
+ * gen_ai.request.model is a structural sign that the plugin is using
22
+ * llm.request to mark user-prompt submission (not a real LLM API call).
23
+ *
24
+ * This is only the structural check; the converter must also verify the
25
+ * event has no matching llm.response in the turn before routing it to ENTRY.
26
+ */
27
+ export function isUserHookCandidate(record) {
28
+ return (record["event.name"] === EventName.LLM_REQUEST &&
29
+ !record["gen_ai.step.id"] &&
30
+ !record["gen_ai.request.model"]);
31
+ }
32
+ /**
33
+ * Within a turn's records, identify which llm.request events should be
34
+ * treated as user-hook prompts (merged into ENTRY) versus kept for normal
35
+ * LLM-span generation.
36
+ *
37
+ * Rule: structural candidate (no step.id, no model) AND no peer llm.response
38
+ * that could conceivably pair with it. A real LLM call always has step.id,
39
+ * so its response also has step.id. A user-hook candidate (no step.id) can
40
+ * only legitimately pair with a no-step llm.response — which never exists
41
+ * in well-formed data. So we declare the candidate user-hook iff there is
42
+ * no llm.response in the same turn that also lacks step.id.
43
+ *
44
+ * This avoids cross-step mispairing (where the time-ordered pairLlm could
45
+ * otherwise greedy-match a candidate with a later step's response).
46
+ */
47
+ export function partitionUserHookRequests(turnRecords) {
48
+ const candidates = turnRecords.filter(isUserHookCandidate);
49
+ if (candidates.length === 0) {
50
+ return { userHooks: [], remaining: turnRecords };
51
+ }
52
+ // Are there any llm.response events that could pair with no-step candidates?
53
+ // A no-step response would be needed to legitimately pair with a no-step
54
+ // candidate. In practice none exists; this guard keeps the rule strict.
55
+ const noStepResponses = turnRecords.filter((r) => r["event.name"] === EventName.LLM_RESPONSE && !r["gen_ai.step.id"]);
56
+ // Assign candidates to user-hooks in time order until we run out of
57
+ // potential pair-mates. Remaining candidates are user-hooks.
58
+ const sortedCandidates = [...candidates].sort((a, b) => readNanoMs(a["time_unix_nano"]) - readNanoMs(b["time_unix_nano"]));
59
+ const userHookSet = new Set(sortedCandidates.slice(noStepResponses.length));
60
+ const userHooks = [];
61
+ const remaining = [];
62
+ for (const r of turnRecords) {
63
+ if (userHookSet.has(r))
64
+ userHooks.push(r);
65
+ else
66
+ remaining.push(r);
67
+ }
68
+ return { userHooks, remaining };
69
+ }
70
+ function getStr(record, key) {
71
+ const v = record[key];
72
+ return typeof v === "string" && v.length > 0 ? v : undefined;
73
+ }
74
+ function turnKey(record) {
75
+ const turnId = getStr(record, "gen_ai.turn.id");
76
+ if (turnId)
77
+ return `turn:${turnId}`;
78
+ const sessionId = getStr(record, "gen_ai.session.id");
79
+ if (sessionId)
80
+ return `session:${sessionId}`;
81
+ return "__no_turn__";
82
+ }
83
+ /**
84
+ * Group records by turn. Insertion order of turns is preserved (matches order
85
+ * the first record of each turn appears in the input).
86
+ *
87
+ * If multiple records within a turn carry different trace_id values the
88
+ * first valid one wins and a warning is pushed.
89
+ */
90
+ export function groupByTurn(records, warnings) {
91
+ const map = new Map();
92
+ // De-dup warning keys so a turn with N misaligned records emits 1 message
93
+ // instead of N — real-world traffic with a buggy upstream can otherwise
94
+ // flood diag logs.
95
+ const seenWarnings = new Set();
96
+ for (const record of records) {
97
+ const key = turnKey(record);
98
+ let group = map.get(key);
99
+ if (!group) {
100
+ group = {
101
+ turnId: getStr(record, "gen_ai.turn.id"),
102
+ sessionId: getStr(record, "gen_ai.session.id"),
103
+ traceId: undefined,
104
+ records: [],
105
+ };
106
+ map.set(key, group);
107
+ }
108
+ group.records.push(record);
109
+ const candidate = record["trace_id"];
110
+ if (isValidTraceId(candidate)) {
111
+ if (group.traceId === undefined) {
112
+ group.traceId = candidate;
113
+ }
114
+ else if (group.traceId !== candidate) {
115
+ const wKey = `inconsistent:${key}:${group.traceId}:${candidate}`;
116
+ if (!seenWarnings.has(wKey)) {
117
+ seenWarnings.add(wKey);
118
+ warnings.push(`Inconsistent trace_id within turn ${group.turnId ?? "(no turn.id)"}: kept ${group.traceId}, saw ${candidate}`);
119
+ }
120
+ }
121
+ }
122
+ else if (candidate !== undefined && candidate !== null && candidate !== "") {
123
+ const wKey = `invalid:${key}:${String(candidate)}`;
124
+ if (!seenWarnings.has(wKey)) {
125
+ seenWarnings.add(wKey);
126
+ warnings.push(`Invalid trace_id "${String(candidate)}" in turn ${group.turnId ?? "(no turn.id)"}; SDK will allocate one`);
127
+ }
128
+ }
129
+ }
130
+ return [...map.values()];
131
+ }
132
+ /**
133
+ * Group records within a turn by gen_ai.step.id. Records missing step.id are
134
+ * placed into a synthetic "__no_step__" group, which still produces one STEP
135
+ * span downstream.
136
+ *
137
+ * Insertion order is preserved.
138
+ */
139
+ export function groupByStep(records) {
140
+ const map = new Map();
141
+ for (const record of records) {
142
+ const key = getStr(record, "gen_ai.step.id") ?? "__no_step__";
143
+ let group = map.get(key);
144
+ if (!group) {
145
+ group = {
146
+ stepId: getStr(record, "gen_ai.step.id"),
147
+ records: [],
148
+ };
149
+ map.set(key, group);
150
+ }
151
+ group.records.push(record);
152
+ }
153
+ return [...map.values()];
154
+ }
155
+ /**
156
+ * Pair llm.request with the following llm.response within the same step.
157
+ *
158
+ * Matching rules (in order):
159
+ * 1. If both records share a non-empty gen_ai.response.id, prefer ID match.
160
+ * (response.id appears on the response and sometimes is mirrored back to
161
+ * the request by the producer.)
162
+ * 2. Otherwise pair each request with the next unpaired response in
163
+ * time_unix_nano order.
164
+ *
165
+ * Orphan request/response records are returned as pairs with the other side
166
+ * undefined.
167
+ */
168
+ export function pairLlm(records, warnings) {
169
+ const requests = records
170
+ .filter((r) => r["event.name"] === EventName.LLM_REQUEST)
171
+ .slice()
172
+ .sort((a, b) => readNanoMs(a["time_unix_nano"]) - readNanoMs(b["time_unix_nano"]));
173
+ const responses = records
174
+ .filter((r) => r["event.name"] === EventName.LLM_RESPONSE)
175
+ .slice()
176
+ .sort((a, b) => readNanoMs(a["time_unix_nano"]) - readNanoMs(b["time_unix_nano"]));
177
+ const pairs = [];
178
+ const consumedResponses = new Set();
179
+ for (const req of requests) {
180
+ const reqRespId = getStr(req, "gen_ai.response.id");
181
+ let resp;
182
+ if (reqRespId) {
183
+ resp = responses.find((r) => !consumedResponses.has(r) && getStr(r, "gen_ai.response.id") === reqRespId);
184
+ }
185
+ if (!resp) {
186
+ resp = responses.find((r) => !consumedResponses.has(r));
187
+ }
188
+ if (resp) {
189
+ consumedResponses.add(resp);
190
+ pairs.push({ request: req, response: resp });
191
+ }
192
+ else {
193
+ warnings.push(`Orphan llm.request (event.id=${getStr(req, "event.id") ?? "?"}): no matching llm.response in step`);
194
+ pairs.push({ request: req });
195
+ }
196
+ }
197
+ for (const resp of responses) {
198
+ if (!consumedResponses.has(resp)) {
199
+ warnings.push(`Orphan llm.response (event.id=${getStr(resp, "event.id") ?? "?"}): no preceding llm.request in step`);
200
+ pairs.push({ response: resp });
201
+ }
202
+ }
203
+ return pairs;
204
+ }
205
+ /**
206
+ * Pair tool.call with tool.result by gen_ai.tool.call.id. Orphans are
207
+ * returned with the missing side undefined.
208
+ */
209
+ export function pairTool(records, warnings) {
210
+ const calls = records.filter((r) => r["event.name"] === EventName.TOOL_CALL);
211
+ const results = records.filter((r) => r["event.name"] === EventName.TOOL_RESULT);
212
+ const consumedResults = new Set();
213
+ const pairs = [];
214
+ for (const call of calls) {
215
+ const callId = getStr(call, "gen_ai.tool.call.id");
216
+ let result;
217
+ if (callId) {
218
+ result = results.find((r) => !consumedResults.has(r) && getStr(r, "gen_ai.tool.call.id") === callId);
219
+ }
220
+ if (!result) {
221
+ // Fallback: first unconsumed result without id
222
+ result = results.find((r) => !consumedResults.has(r));
223
+ }
224
+ if (result) {
225
+ consumedResults.add(result);
226
+ pairs.push({ call, result });
227
+ }
228
+ else {
229
+ warnings.push(`Orphan tool.call (tool.call.id=${callId ?? "?"}): no matching tool.result in step`);
230
+ pairs.push({ call });
231
+ }
232
+ }
233
+ for (const result of results) {
234
+ if (!consumedResults.has(result)) {
235
+ warnings.push(`Orphan tool.result (tool.call.id=${getStr(result, "gen_ai.tool.call.id") ?? "?"}): no preceding tool.call in step`);
236
+ pairs.push({ result });
237
+ }
238
+ }
239
+ return pairs;
240
+ }
241
+ //# sourceMappingURL=grouping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grouping.js","sourceRoot":"","sources":["../../src/event-log/grouping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { convertEventLogToTrace } from "./converter.js";
2
+ export { convertEventLogToReadableSpans, type ReadableSpansResult, } from "./readable-spans.js";
3
+ export { EventName, EventLogConversionError, type EventLogRecord, type EventNameValue, type ConvertOptions, type ConvertResult, } from "./types.js";
4
+ export { isValidTraceId, createTraceParentContext } from "./parent-context.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/event-log/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,8BAA8B,EAC9B,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,18 @@
1
+ // Copyright The OpenTelemetry Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ export { convertEventLogToTrace } from "./converter.js";
15
+ export { convertEventLogToReadableSpans, } from "./readable-spans.js";
16
+ export { EventName, EventLogConversionError, } from "./types.js";
17
+ export { isValidTraceId, createTraceParentContext } from "./parent-context.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/event-log/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,8BAA8B,GAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,SAAS,EACT,uBAAuB,GAKxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type Context } from "@opentelemetry/api";
2
+ /** True if value is a valid lowercase 32-hex trace_id and not all zeros. */
3
+ export declare function isValidTraceId(value: unknown): value is string;
4
+ /**
5
+ * Build a non-recording parent Context that carries the given trace_id so any
6
+ * child span created with this context inherits the same trace_id.
7
+ *
8
+ * The synthetic parent spanId is arbitrary — ENTRY spans use this as their
9
+ * parentSpanId, but ARMS/OTel consumers do not look it up (it has no
10
+ * corresponding real span). isRemote=true marks the parent as external, which
11
+ * is the correct semantic when reconstructing spans from out-of-band events.
12
+ */
13
+ export declare function createTraceParentContext(traceId: string): Context;
14
+ //# sourceMappingURL=parent-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-context.d.ts","sourceRoot":"","sources":["../../src/event-log/parent-context.ts"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,OAAO,EAEb,MAAM,oBAAoB,CAAC;AAK5B,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAK9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQjE"}
@@ -0,0 +1,45 @@
1
+ // Copyright The OpenTelemetry Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { ROOT_CONTEXT, TraceFlags, trace, } from "@opentelemetry/api";
15
+ const TRACE_ID_REGEX = /^[0-9a-f]{32}$/;
16
+ const ALL_ZERO_TRACE_ID = "0".repeat(32);
17
+ /** True if value is a valid lowercase 32-hex trace_id and not all zeros. */
18
+ export function isValidTraceId(value) {
19
+ if (typeof value !== "string")
20
+ return false;
21
+ if (!TRACE_ID_REGEX.test(value))
22
+ return false;
23
+ if (value === ALL_ZERO_TRACE_ID)
24
+ return false;
25
+ return true;
26
+ }
27
+ /**
28
+ * Build a non-recording parent Context that carries the given trace_id so any
29
+ * child span created with this context inherits the same trace_id.
30
+ *
31
+ * The synthetic parent spanId is arbitrary — ENTRY spans use this as their
32
+ * parentSpanId, but ARMS/OTel consumers do not look it up (it has no
33
+ * corresponding real span). isRemote=true marks the parent as external, which
34
+ * is the correct semantic when reconstructing spans from out-of-band events.
35
+ */
36
+ export function createTraceParentContext(traceId) {
37
+ const spanContext = {
38
+ traceId,
39
+ spanId: "0".repeat(15) + "1", // any valid non-zero 16-hex
40
+ traceFlags: TraceFlags.SAMPLED,
41
+ isRemote: true,
42
+ };
43
+ return trace.setSpan(ROOT_CONTEXT, trace.wrapSpanContext(spanContext));
44
+ }
45
+ //# sourceMappingURL=parent-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-context.js","sourceRoot":"","sources":["../../src/event-log/parent-context.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EACL,YAAY,EACZ,UAAU,EACV,KAAK,GAGN,MAAM,oBAAoB,CAAC;AAE5B,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,KAAK,KAAK,iBAAiB;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,MAAM,WAAW,GAAgB;QAC/B,OAAO;QACP,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,4BAA4B;QAC1D,UAAU,EAAE,UAAU,CAAC,OAAO;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC;IACF,OAAO,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { ReadableSpan } from "@opentelemetry/sdk-trace-base";
2
+ import type { ConvertOptions, EventLogRecord } from "./types.js";
3
+ export interface ReadableSpansResult {
4
+ /** Finished spans ready to feed into OTLPTraceExporter.export(). */
5
+ spans: ReadableSpan[];
6
+ /** trace_id per turn (in input order). */
7
+ traceIds: string[];
8
+ /** Non-fatal issues collected during conversion (always returned, never thrown unless strict). */
9
+ warnings: string[];
10
+ }
11
+ /**
12
+ * High-level helper that converts an event log into a flat list of
13
+ * {@link ReadableSpan}s ready to be fed into an OTLPTraceExporter.
14
+ *
15
+ * Internally this wires a private BasicTracerProvider + InMemorySpanExporter,
16
+ * runs {@link convertEventLogToTrace}, flushes, and returns the captured
17
+ * spans. The provider is **never** registered globally — it lives only for
18
+ * the duration of this call.
19
+ *
20
+ * Use this when:
21
+ * - You want a pure function-style API that yields ReadableSpan[] data,
22
+ * e.g. inside a pilot/exporter that owns its own OTLPTraceExporter.
23
+ * - You don't have an existing handler / TracerProvider to share.
24
+ *
25
+ * Use {@link convertEventLogToTrace} directly instead when:
26
+ * - You already have a long-lived ExtendedTelemetryHandler bound to a
27
+ * real production TracerProvider (e.g. inside a plugin's hook process).
28
+ * - You want the spans to flow through BatchSpanProcessor → OTLP exporter
29
+ * in the standard plugin pattern.
30
+ *
31
+ * @requires `@opentelemetry/sdk-trace-base` must be available at runtime in
32
+ * the consumer's `node_modules` (it is loaded via dynamic import).
33
+ * This package declares it as an optional peer dep.
34
+ */
35
+ export declare function convertEventLogToReadableSpans(records: EventLogRecord[], options?: Omit<ConvertOptions, "handler">): Promise<ReadableSpansResult>;
36
+ //# sourceMappingURL=readable-spans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readable-spans.d.ts","sourceRoot":"","sources":["../../src/event-log/readable-spans.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kGAAkG;IAClG,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,GACxC,OAAO,CAAC,mBAAmB,CAAC,CAmC9B"}
@@ -0,0 +1,73 @@
1
+ // Copyright The OpenTelemetry Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { ExtendedTelemetryHandler } from "../extended-handler.js";
15
+ import { convertEventLogToTrace } from "./converter.js";
16
+ /**
17
+ * High-level helper that converts an event log into a flat list of
18
+ * {@link ReadableSpan}s ready to be fed into an OTLPTraceExporter.
19
+ *
20
+ * Internally this wires a private BasicTracerProvider + InMemorySpanExporter,
21
+ * runs {@link convertEventLogToTrace}, flushes, and returns the captured
22
+ * spans. The provider is **never** registered globally — it lives only for
23
+ * the duration of this call.
24
+ *
25
+ * Use this when:
26
+ * - You want a pure function-style API that yields ReadableSpan[] data,
27
+ * e.g. inside a pilot/exporter that owns its own OTLPTraceExporter.
28
+ * - You don't have an existing handler / TracerProvider to share.
29
+ *
30
+ * Use {@link convertEventLogToTrace} directly instead when:
31
+ * - You already have a long-lived ExtendedTelemetryHandler bound to a
32
+ * real production TracerProvider (e.g. inside a plugin's hook process).
33
+ * - You want the spans to flow through BatchSpanProcessor → OTLP exporter
34
+ * in the standard plugin pattern.
35
+ *
36
+ * @requires `@opentelemetry/sdk-trace-base` must be available at runtime in
37
+ * the consumer's `node_modules` (it is loaded via dynamic import).
38
+ * This package declares it as an optional peer dep.
39
+ */
40
+ export async function convertEventLogToReadableSpans(records, options) {
41
+ if (!records || records.length === 0) {
42
+ return { spans: [], traceIds: [], warnings: [] };
43
+ }
44
+ let mod;
45
+ try {
46
+ mod = await import("@opentelemetry/sdk-trace-base");
47
+ }
48
+ catch {
49
+ throw new Error("convertEventLogToReadableSpans requires @opentelemetry/sdk-trace-base. " +
50
+ "Install it in the consumer package (npm install @opentelemetry/sdk-trace-base).");
51
+ }
52
+ const { BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor } = mod;
53
+ const exporter = new InMemorySpanExporter();
54
+ const provider = new BasicTracerProvider({
55
+ spanProcessors: [new SimpleSpanProcessor(exporter)],
56
+ });
57
+ const handler = new ExtendedTelemetryHandler({ tracerProvider: provider });
58
+ try {
59
+ const result = convertEventLogToTrace(records, { ...options, handler });
60
+ await provider.forceFlush();
61
+ const spans = exporter.getFinishedSpans();
62
+ return {
63
+ spans,
64
+ traceIds: result.traceIds,
65
+ warnings: result.warnings,
66
+ };
67
+ }
68
+ finally {
69
+ // Best-effort cleanup; ignore shutdown errors to avoid masking real failures.
70
+ await provider.shutdown().catch(() => undefined);
71
+ }
72
+ }
73
+ //# sourceMappingURL=readable-spans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readable-spans.js","sourceRoot":"","sources":["../../src/event-log/readable-spans.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAYxD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,OAAyB,EACzB,OAAyC;IAEzC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,GAAmD,CAAC;IACxD,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yEAAyE;YACvE,iFAAiF,CACpF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,GAAG,GAAG,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC;QACvC,cAAc,EAAE,CAAC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;KACpD,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,wBAAwB,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE3E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACxE,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC1C,OAAO;YACL,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,8EAA8E;QAC9E,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;AACH,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { ExtendedTelemetryHandler } from "../extended-handler.js";
2
+ /**
3
+ * Event log record as defined by loongsuite-pilot/docs/ai_event_schema.md.
4
+ *
5
+ * Intentionally typed as a loose key/value map so that schema evolution (new
6
+ * fields, removed fields) does not break TypeScript compilation of the
7
+ * converter. Field access is centralized in field-mapping.ts.
8
+ */
9
+ export type EventLogRecord = Record<string, unknown>;
10
+ /** Enum of supported event.name values (subset of pilot schema we handle). */
11
+ export declare const EventName: {
12
+ readonly LLM_REQUEST: "llm.request";
13
+ readonly LLM_RESPONSE: "llm.response";
14
+ readonly TOOL_CALL: "tool.call";
15
+ readonly TOOL_RESULT: "tool.result";
16
+ readonly SKILL_USE: "skill.use";
17
+ readonly TOOL_APPROVE: "tool.approve";
18
+ readonly OTHER: "other";
19
+ };
20
+ export type EventNameValue = (typeof EventName)[keyof typeof EventName];
21
+ /** Options accepted by convertEventLogToTrace. */
22
+ export interface ConvertOptions {
23
+ /**
24
+ * Handler used to create spans. If omitted the default singleton from
25
+ * getExtendedTelemetryHandler() is used.
26
+ */
27
+ handler?: ExtendedTelemetryHandler;
28
+ /**
29
+ * When true any conversion problem (orphan events, malformed JSON, invalid
30
+ * timestamps) throws EventLogConversionError instead of being collected as
31
+ * a warning. Default false.
32
+ */
33
+ strict?: boolean;
34
+ }
35
+ /** Result of a conversion. */
36
+ export interface ConvertResult {
37
+ /** trace_id per turn (in input order). */
38
+ traceIds: string[];
39
+ /** Total number of spans created (ENTRY+AGENT+STEP+LLM+TOOL). */
40
+ spanCount: number;
41
+ /** Non-fatal issues encountered when strict=false. */
42
+ warnings: string[];
43
+ }
44
+ /** Thrown in strict mode when conversion cannot proceed. */
45
+ export declare class EventLogConversionError extends Error {
46
+ readonly eventId?: string | undefined;
47
+ readonly eventName?: string | undefined;
48
+ constructor(message: string, eventId?: string | undefined, eventName?: string | undefined);
49
+ }
50
+ /**
51
+ * Internal grouping result: records grouped by turn.
52
+ *
53
+ * traceId is the value read from records (validated 32-hex). May be undefined
54
+ * if no record in the turn carried a valid trace_id — in that case the SDK
55
+ * will allocate one.
56
+ */
57
+ export interface TurnGroup {
58
+ turnId: string | undefined;
59
+ sessionId: string | undefined;
60
+ traceId: string | undefined;
61
+ records: EventLogRecord[];
62
+ }
63
+ /** Internal grouping result: records within one step of a turn. */
64
+ export interface StepGroup {
65
+ stepId: string | undefined;
66
+ records: EventLogRecord[];
67
+ }
68
+ /** A matched llm.request + llm.response pair (either side may be missing). */
69
+ export interface LlmPair {
70
+ request?: EventLogRecord;
71
+ response?: EventLogRecord;
72
+ }
73
+ /** A matched tool.call + tool.result pair (either side may be missing). */
74
+ export interface ToolPair {
75
+ call?: EventLogRecord;
76
+ result?: EventLogRecord;
77
+ }
78
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/event-log/types.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD,8EAA8E;AAC9E,eAAO,MAAM,SAAS;;;;;;;;CAQZ,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAExE,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,8BAA8B;AAC9B,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,4DAA4D;AAC5D,qBAAa,uBAAwB,SAAQ,KAAK;aAG9B,OAAO,CAAC,EAAE,MAAM;aAChB,SAAS,CAAC,EAAE,MAAM;gBAFlC,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,MAAM,YAAA,EAChB,SAAS,CAAC,EAAE,MAAM,YAAA;CAKrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,8EAA8E;AAC9E,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,2EAA2E;AAC3E,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB"}
@@ -0,0 +1,35 @@
1
+ // Copyright The OpenTelemetry Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ /** Enum of supported event.name values (subset of pilot schema we handle). */
15
+ export const EventName = {
16
+ LLM_REQUEST: "llm.request",
17
+ LLM_RESPONSE: "llm.response",
18
+ TOOL_CALL: "tool.call",
19
+ TOOL_RESULT: "tool.result",
20
+ SKILL_USE: "skill.use",
21
+ TOOL_APPROVE: "tool.approve",
22
+ OTHER: "other",
23
+ };
24
+ /** Thrown in strict mode when conversion cannot proceed. */
25
+ export class EventLogConversionError extends Error {
26
+ eventId;
27
+ eventName;
28
+ constructor(message, eventId, eventName) {
29
+ super(message);
30
+ this.eventId = eventId;
31
+ this.eventName = eventName;
32
+ this.name = "EventLogConversionError";
33
+ }
34
+ }
35
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/event-log/types.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAajC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,cAAc;IAC5B,KAAK,EAAE,OAAO;CACN,CAAC;AA6BX,4DAA4D;AAC5D,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAG9B;IACA;IAHlB,YACE,OAAe,EACC,OAAgB,EAChB,SAAkB;QAElC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,YAAO,GAAP,OAAO,CAAS;QAChB,cAAS,GAAT,SAAS,CAAS;QAGlC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export declare const OTEL_INSTRUMENTATION_GENAI_MESSAGE_CONTENT_MAX_LENGTH = "OTEL_INSTRUMENTATION_GENAI_MESSAGE_CONTENT_MAX_LENGTH";
2
+ export declare const OTEL_INSTRUMENTATION_GENAI_MESSAGE_CONTENT_CAPTURE_STRATEGY = "OTEL_INSTRUMENTATION_GENAI_MESSAGE_CONTENT_CAPTURE_STRATEGY";
3
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_STORAGE_BASE_PATH = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_STORAGE_BASE_PATH";
4
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_UPLOAD_MODE = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_UPLOAD_MODE";
5
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_DOWNLOAD_ENABLED = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_DOWNLOAD_ENABLED";
6
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_DOWNLOAD_SSL_VERIFY = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_DOWNLOAD_SSL_VERIFY";
7
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_AUDIO_CONVERSION_ENABLED = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_AUDIO_CONVERSION_ENABLED";
8
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_LOCAL_FILE_ENABLED = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_LOCAL_FILE_ENABLED";
9
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_ALLOWED_ROOT_PATHS = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_ALLOWED_ROOT_PATHS";
10
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_UPLOADER = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_UPLOADER";
11
+ export declare const OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_PRE_UPLOADER = "OTEL_INSTRUMENTATION_GENAI_MULTIMODAL_PRE_UPLOADER";
12
+ //# sourceMappingURL=extended-environment-variables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-environment-variables.d.ts","sourceRoot":"","sources":["../src/extended-environment-variables.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,qDAAqD,0DACT,CAAC;AAC1D,eAAO,MAAM,2DAA2D,gEACT,CAAC;AAChE,eAAO,MAAM,uDAAuD,4DACT,CAAC;AAC5D,eAAO,MAAM,iDAAiD,sDACT,CAAC;AACtD,eAAO,MAAM,sDAAsD,2DACT,CAAC;AAC3D,eAAO,MAAM,yDAAyD,8DACT,CAAC;AAC9D,eAAO,MAAM,8DAA8D,mEACT,CAAC;AACnE,eAAO,MAAM,wDAAwD,6DACT,CAAC;AAC7D,eAAO,MAAM,wDAAwD,6DACT,CAAC;AAC7D,eAAO,MAAM,8CAA8C,mDACT,CAAC;AACnD,eAAO,MAAM,kDAAkD,uDACT,CAAC"}