@superblocksteam/telemetry 2.0.173-next.4 → 2.0.174

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 (304) hide show
  1. package/dist/browser/console-logging.js +7 -2
  2. package/dist/browser/console-logging.js.map +1 -1
  3. package/dist/browser/early-console-buffer.js +14 -12
  4. package/dist/browser/early-console-buffer.js.map +1 -1
  5. package/dist/browser/index.js +41 -12
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/browser/init.d.ts +1 -1
  8. package/dist/browser/init.d.ts.map +1 -1
  9. package/dist/browser/init.js +52 -42
  10. package/dist/browser/init.js.map +1 -1
  11. package/dist/browser/instrumentations.js +15 -11
  12. package/dist/browser/instrumentations.js.map +1 -1
  13. package/dist/browser/logs.d.ts +1 -1
  14. package/dist/browser/logs.d.ts.map +1 -1
  15. package/dist/browser/logs.js +18 -11
  16. package/dist/browser/logs.js.map +1 -1
  17. package/dist/browser/metrics.js +12 -9
  18. package/dist/browser/metrics.js.map +1 -1
  19. package/dist/browser/resilient-exporter.d.ts +1 -1
  20. package/dist/browser/resilient-exporter.d.ts.map +1 -1
  21. package/dist/browser/resilient-exporter.js +12 -8
  22. package/dist/browser/resilient-exporter.js.map +1 -1
  23. package/dist/browser/sanitizer.js +6 -2
  24. package/dist/browser/sanitizer.js.map +1 -1
  25. package/dist/browser/traced-socket.js +18 -14
  26. package/dist/browser/traced-socket.js.map +1 -1
  27. package/dist/common/contracts/tier2-traces.js +44 -33
  28. package/dist/common/contracts/tier2-traces.js.map +1 -1
  29. package/dist/common/deployment-type.js +8 -5
  30. package/dist/common/deployment-type.js.map +1 -1
  31. package/dist/common/guardrails.js +38 -26
  32. package/dist/common/guardrails.js.map +1 -1
  33. package/dist/common/index.js +24 -8
  34. package/dist/common/index.js.map +1 -1
  35. package/dist/common/log-sanitizer.js +55 -37
  36. package/dist/common/log-sanitizer.js.map +1 -1
  37. package/dist/common/policy-evaluator.d.ts +1 -1
  38. package/dist/common/policy-evaluator.d.ts.map +1 -1
  39. package/dist/common/policy-evaluator.js +9 -5
  40. package/dist/common/policy-evaluator.js.map +1 -1
  41. package/dist/common/resource.js +25 -18
  42. package/dist/common/resource.js.map +1 -1
  43. package/dist/common/tier-hints.js +22 -12
  44. package/dist/common/tier-hints.js.map +1 -1
  45. package/dist/common/trace-sanitizer.js +10 -6
  46. package/dist/common/trace-sanitizer.js.map +1 -1
  47. package/dist/common/traced-socket-types.js +2 -1
  48. package/dist/common/traced-socket-types.js.map +1 -1
  49. package/dist/index.js +38 -6
  50. package/dist/index.js.map +1 -1
  51. package/dist/lint/forbidden-attributes.js +24 -19
  52. package/dist/lint/forbidden-attributes.js.map +1 -1
  53. package/dist/lint/index.js +8 -1
  54. package/dist/lint/index.js.map +1 -1
  55. package/dist/llmobs/index.js +9 -2
  56. package/dist/llmobs/index.js.map +1 -1
  57. package/dist/llmobs/tier1-exporter.js +12 -6
  58. package/dist/llmobs/tier1-exporter.js.map +1 -1
  59. package/dist/llmobs/tier2-summarizer.js +5 -1
  60. package/dist/llmobs/tier2-summarizer.js.map +1 -1
  61. package/dist/node/dynamic-attribute-processor.js +7 -2
  62. package/dist/node/dynamic-attribute-processor.js.map +1 -1
  63. package/dist/node/exporters/resilient-exporter.d.ts +1 -1
  64. package/dist/node/exporters/resilient-exporter.d.ts.map +1 -1
  65. package/dist/node/exporters/resilient-exporter.js +12 -8
  66. package/dist/node/exporters/resilient-exporter.js.map +1 -1
  67. package/dist/node/index.js +26 -7
  68. package/dist/node/index.js.map +1 -1
  69. package/dist/node/init.d.ts +3 -3
  70. package/dist/node/init.d.ts.map +1 -1
  71. package/dist/node/init.js +72 -66
  72. package/dist/node/init.js.map +1 -1
  73. package/dist/node/local-obs-mode.js +4 -1
  74. package/dist/node/local-obs-mode.js.map +1 -1
  75. package/dist/node/log-processor.d.ts +1 -1
  76. package/dist/node/log-processor.d.ts.map +1 -1
  77. package/dist/node/log-processor.js +55 -47
  78. package/dist/node/log-processor.js.map +1 -1
  79. package/dist/node/metrics-client.js +5 -1
  80. package/dist/node/metrics-client.js.map +1 -1
  81. package/dist/node/safe-logger.js +12 -8
  82. package/dist/node/safe-logger.js.map +1 -1
  83. package/dist/node/sanitizing-processor.d.ts +2 -2
  84. package/dist/node/sanitizing-processor.d.ts.map +1 -1
  85. package/dist/node/sanitizing-processor.js +10 -6
  86. package/dist/node/sanitizing-processor.js.map +1 -1
  87. package/dist/node/service-tracers.js +10 -7
  88. package/dist/node/service-tracers.js.map +1 -1
  89. package/dist/node/traced-socket.d.ts +3 -3
  90. package/dist/node/traced-socket.d.ts.map +1 -1
  91. package/dist/node/traced-socket.js +52 -48
  92. package/dist/node/traced-socket.js.map +1 -1
  93. package/dist/npm-registry/emitter.js +47 -34
  94. package/dist/npm-registry/emitter.js.map +1 -1
  95. package/dist/npm-registry/index.js +19 -3
  96. package/dist/npm-registry/index.js.map +1 -1
  97. package/dist/npm-registry/sanitize.js +27 -16
  98. package/dist/npm-registry/sanitize.js.map +1 -1
  99. package/dist/npm-registry/spans.js +12 -7
  100. package/dist/npm-registry/spans.js.map +1 -1
  101. package/dist/testing/in-memory-exporter.d.ts +1 -1
  102. package/dist/testing/in-memory-exporter.d.ts.map +1 -1
  103. package/dist/testing/in-memory-exporter.js +12 -6
  104. package/dist/testing/in-memory-exporter.js.map +1 -1
  105. package/dist/testing/index.js +15 -3
  106. package/dist/testing/index.js.map +1 -1
  107. package/dist/testing/metrics-capture.js +15 -12
  108. package/dist/testing/metrics-capture.js.map +1 -1
  109. package/dist/testing/test-init.js +31 -24
  110. package/dist/testing/test-init.js.map +1 -1
  111. package/dist/types/index.js +17 -1
  112. package/dist/types/index.js.map +1 -1
  113. package/dist/types/policy.js +24 -21
  114. package/dist/types/policy.js.map +1 -1
  115. package/dist-esm/browser/console-logging.d.ts +18 -0
  116. package/dist-esm/browser/console-logging.d.ts.map +1 -0
  117. package/dist-esm/browser/console-logging.js +27 -0
  118. package/dist-esm/browser/console-logging.js.map +1 -0
  119. package/dist-esm/browser/early-console-buffer.d.ts +49 -0
  120. package/dist-esm/browser/early-console-buffer.d.ts.map +1 -0
  121. package/dist-esm/browser/early-console-buffer.js +181 -0
  122. package/dist-esm/browser/early-console-buffer.js.map +1 -0
  123. package/dist-esm/browser/index.d.ts +18 -0
  124. package/dist-esm/browser/index.d.ts.map +1 -0
  125. package/dist-esm/browser/index.js +23 -0
  126. package/dist-esm/browser/index.js.map +1 -0
  127. package/dist-esm/browser/init.d.ts +100 -0
  128. package/dist-esm/browser/init.d.ts.map +1 -0
  129. package/dist-esm/browser/init.js +317 -0
  130. package/dist-esm/browser/init.js.map +1 -0
  131. package/dist-esm/browser/instrumentations.d.ts +67 -0
  132. package/dist-esm/browser/instrumentations.d.ts.map +1 -0
  133. package/dist-esm/browser/instrumentations.js +79 -0
  134. package/dist-esm/browser/instrumentations.js.map +1 -0
  135. package/dist-esm/browser/logs.d.ts +57 -0
  136. package/dist-esm/browser/logs.d.ts.map +1 -0
  137. package/dist-esm/browser/logs.js +80 -0
  138. package/dist-esm/browser/logs.js.map +1 -0
  139. package/dist-esm/browser/metrics.d.ts +29 -0
  140. package/dist-esm/browser/metrics.d.ts.map +1 -0
  141. package/dist-esm/browser/metrics.js +46 -0
  142. package/dist-esm/browser/metrics.js.map +1 -0
  143. package/dist-esm/browser/resilient-exporter.d.ts +43 -0
  144. package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
  145. package/dist-esm/browser/resilient-exporter.js +84 -0
  146. package/dist-esm/browser/resilient-exporter.js.map +1 -0
  147. package/dist-esm/browser/sanitizer.d.ts +35 -0
  148. package/dist-esm/browser/sanitizer.d.ts.map +1 -0
  149. package/dist-esm/browser/sanitizer.js +207 -0
  150. package/dist-esm/browser/sanitizer.js.map +1 -0
  151. package/dist-esm/browser/traced-socket.d.ts +102 -0
  152. package/dist-esm/browser/traced-socket.d.ts.map +1 -0
  153. package/dist-esm/browser/traced-socket.js +199 -0
  154. package/dist-esm/browser/traced-socket.js.map +1 -0
  155. package/dist-esm/common/contracts/tier2-traces.d.ts +116 -0
  156. package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
  157. package/dist-esm/common/contracts/tier2-traces.js +725 -0
  158. package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
  159. package/dist-esm/common/deployment-type.d.ts +18 -0
  160. package/dist-esm/common/deployment-type.d.ts.map +1 -0
  161. package/dist-esm/common/deployment-type.js +27 -0
  162. package/dist-esm/common/deployment-type.js.map +1 -0
  163. package/dist-esm/common/guardrails.d.ts +132 -0
  164. package/dist-esm/common/guardrails.d.ts.map +1 -0
  165. package/dist-esm/common/guardrails.js +230 -0
  166. package/dist-esm/common/guardrails.js.map +1 -0
  167. package/dist-esm/common/index.d.ts +17 -0
  168. package/dist-esm/common/index.d.ts.map +1 -0
  169. package/dist-esm/common/index.js +17 -0
  170. package/dist-esm/common/index.js.map +1 -0
  171. package/dist-esm/common/log-sanitizer.d.ts +163 -0
  172. package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
  173. package/dist-esm/common/log-sanitizer.js +745 -0
  174. package/dist-esm/common/log-sanitizer.js.map +1 -0
  175. package/dist-esm/common/policy-evaluator.d.ts +103 -0
  176. package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
  177. package/dist-esm/common/policy-evaluator.js +196 -0
  178. package/dist-esm/common/policy-evaluator.js.map +1 -0
  179. package/dist-esm/common/resource.d.ts +79 -0
  180. package/dist-esm/common/resource.d.ts.map +1 -0
  181. package/dist-esm/common/resource.js +121 -0
  182. package/dist-esm/common/resource.js.map +1 -0
  183. package/dist-esm/common/tier-hints.d.ts +182 -0
  184. package/dist-esm/common/tier-hints.d.ts.map +1 -0
  185. package/dist-esm/common/tier-hints.js +199 -0
  186. package/dist-esm/common/tier-hints.js.map +1 -0
  187. package/dist-esm/common/trace-sanitizer.d.ts +82 -0
  188. package/dist-esm/common/trace-sanitizer.d.ts.map +1 -0
  189. package/dist-esm/common/trace-sanitizer.js +230 -0
  190. package/dist-esm/common/trace-sanitizer.js.map +1 -0
  191. package/dist-esm/common/traced-socket-types.d.ts +43 -0
  192. package/dist-esm/common/traced-socket-types.d.ts.map +1 -0
  193. package/dist-esm/common/traced-socket-types.js +16 -0
  194. package/dist-esm/common/traced-socket-types.js.map +1 -0
  195. package/dist-esm/index.d.ts +45 -0
  196. package/dist-esm/index.d.ts.map +1 -0
  197. package/dist-esm/index.js +56 -0
  198. package/dist-esm/index.js.map +1 -0
  199. package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
  200. package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
  201. package/dist-esm/lint/forbidden-attributes.js +210 -0
  202. package/dist-esm/lint/forbidden-attributes.js.map +1 -0
  203. package/dist-esm/lint/index.d.ts +9 -0
  204. package/dist-esm/lint/index.d.ts.map +1 -0
  205. package/dist-esm/lint/index.js +9 -0
  206. package/dist-esm/lint/index.js.map +1 -0
  207. package/dist-esm/llmobs/index.d.ts +22 -0
  208. package/dist-esm/llmobs/index.d.ts.map +1 -0
  209. package/dist-esm/llmobs/index.js +22 -0
  210. package/dist-esm/llmobs/index.js.map +1 -0
  211. package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
  212. package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
  213. package/dist-esm/llmobs/tier1-exporter.js +193 -0
  214. package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
  215. package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
  216. package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
  217. package/dist-esm/llmobs/tier2-summarizer.js +652 -0
  218. package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
  219. package/dist-esm/node/dynamic-attribute-processor.d.ts +43 -0
  220. package/dist-esm/node/dynamic-attribute-processor.d.ts.map +1 -0
  221. package/dist-esm/node/dynamic-attribute-processor.js +74 -0
  222. package/dist-esm/node/dynamic-attribute-processor.js.map +1 -0
  223. package/dist-esm/node/exporters/resilient-exporter.d.ts +91 -0
  224. package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
  225. package/dist-esm/node/exporters/resilient-exporter.js +132 -0
  226. package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
  227. package/dist-esm/node/index.d.ts +13 -0
  228. package/dist-esm/node/index.d.ts.map +1 -0
  229. package/dist-esm/node/index.js +13 -0
  230. package/dist-esm/node/index.js.map +1 -0
  231. package/dist-esm/node/init.d.ts +97 -0
  232. package/dist-esm/node/init.d.ts.map +1 -0
  233. package/dist-esm/node/init.js +359 -0
  234. package/dist-esm/node/init.js.map +1 -0
  235. package/dist-esm/node/local-obs-mode.d.ts +17 -0
  236. package/dist-esm/node/local-obs-mode.d.ts.map +1 -0
  237. package/dist-esm/node/local-obs-mode.js +19 -0
  238. package/dist-esm/node/local-obs-mode.js.map +1 -0
  239. package/dist-esm/node/log-processor.d.ts +132 -0
  240. package/dist-esm/node/log-processor.d.ts.map +1 -0
  241. package/dist-esm/node/log-processor.js +389 -0
  242. package/dist-esm/node/log-processor.js.map +1 -0
  243. package/dist-esm/node/metrics-client.d.ts +88 -0
  244. package/dist-esm/node/metrics-client.d.ts.map +1 -0
  245. package/dist-esm/node/metrics-client.js +205 -0
  246. package/dist-esm/node/metrics-client.js.map +1 -0
  247. package/dist-esm/node/safe-logger.d.ts +55 -0
  248. package/dist-esm/node/safe-logger.d.ts.map +1 -0
  249. package/dist-esm/node/safe-logger.js +154 -0
  250. package/dist-esm/node/safe-logger.js.map +1 -0
  251. package/dist-esm/node/sanitizing-processor.d.ts +67 -0
  252. package/dist-esm/node/sanitizing-processor.d.ts.map +1 -0
  253. package/dist-esm/node/sanitizing-processor.js +163 -0
  254. package/dist-esm/node/sanitizing-processor.js.map +1 -0
  255. package/dist-esm/node/service-tracers.d.ts +52 -0
  256. package/dist-esm/node/service-tracers.d.ts.map +1 -0
  257. package/dist-esm/node/service-tracers.js +78 -0
  258. package/dist-esm/node/service-tracers.js.map +1 -0
  259. package/dist-esm/node/traced-socket.d.ts +120 -0
  260. package/dist-esm/node/traced-socket.d.ts.map +1 -0
  261. package/dist-esm/node/traced-socket.js +334 -0
  262. package/dist-esm/node/traced-socket.js.map +1 -0
  263. package/dist-esm/npm-registry/emitter.d.ts +330 -0
  264. package/dist-esm/npm-registry/emitter.d.ts.map +1 -0
  265. package/dist-esm/npm-registry/emitter.js +546 -0
  266. package/dist-esm/npm-registry/emitter.js.map +1 -0
  267. package/dist-esm/npm-registry/index.d.ts +12 -0
  268. package/dist-esm/npm-registry/index.d.ts.map +1 -0
  269. package/dist-esm/npm-registry/index.js +12 -0
  270. package/dist-esm/npm-registry/index.js.map +1 -0
  271. package/dist-esm/npm-registry/sanitize.d.ts +174 -0
  272. package/dist-esm/npm-registry/sanitize.d.ts.map +1 -0
  273. package/dist-esm/npm-registry/sanitize.js +331 -0
  274. package/dist-esm/npm-registry/sanitize.js.map +1 -0
  275. package/dist-esm/npm-registry/spans.d.ts +61 -0
  276. package/dist-esm/npm-registry/spans.d.ts.map +1 -0
  277. package/dist-esm/npm-registry/spans.js +86 -0
  278. package/dist-esm/npm-registry/spans.js.map +1 -0
  279. package/dist-esm/package.json +1 -0
  280. package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
  281. package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
  282. package/dist-esm/testing/in-memory-exporter.js +250 -0
  283. package/dist-esm/testing/in-memory-exporter.js.map +1 -0
  284. package/dist-esm/testing/index.d.ts +9 -0
  285. package/dist-esm/testing/index.d.ts.map +1 -0
  286. package/dist-esm/testing/index.js +9 -0
  287. package/dist-esm/testing/index.js.map +1 -0
  288. package/dist-esm/testing/metrics-capture.d.ts +29 -0
  289. package/dist-esm/testing/metrics-capture.d.ts.map +1 -0
  290. package/dist-esm/testing/metrics-capture.js +71 -0
  291. package/dist-esm/testing/metrics-capture.js.map +1 -0
  292. package/dist-esm/testing/test-init.d.ts +80 -0
  293. package/dist-esm/testing/test-init.d.ts.map +1 -0
  294. package/dist-esm/testing/test-init.js +137 -0
  295. package/dist-esm/testing/test-init.js.map +1 -0
  296. package/dist-esm/types/index.d.ts +84 -0
  297. package/dist-esm/types/index.d.ts.map +1 -0
  298. package/dist-esm/types/index.js +7 -0
  299. package/dist-esm/types/index.js.map +1 -0
  300. package/dist-esm/types/policy.d.ts +92 -0
  301. package/dist-esm/types/policy.d.ts.map +1 -0
  302. package/dist-esm/types/policy.js +122 -0
  303. package/dist-esm/types/policy.js.map +1 -0
  304. package/package.json +17 -11
@@ -0,0 +1,210 @@
1
+ /**
2
+ * ESLint Rule: No Forbidden Telemetry Attributes
3
+ *
4
+ * This rule detects usage of forbidden attributes in span/metric instrumentation.
5
+ * It catches common leak paths before code is merged.
6
+ *
7
+ * Usage in eslint.config.js:
8
+ * ```
9
+ * import { noForbiddenTelemetryAttributes } from '@superblocksteam/telemetry/lint';
10
+ *
11
+ * export default [
12
+ * {
13
+ * plugins: {
14
+ * telemetry: { rules: { 'no-forbidden-attributes': noForbiddenTelemetryAttributes } }
15
+ * },
16
+ * rules: {
17
+ * 'telemetry/no-forbidden-attributes': 'error'
18
+ * }
19
+ * }
20
+ * ];
21
+ * ```
22
+ */
23
+ /* eslint-disable @typescript-eslint/no-explicit-any -- ESLint rule APIs use untyped AST nodes */
24
+ import { TIER2_FORBIDDEN_ATTRIBUTES } from "../common/contracts/tier2-traces.js";
25
+ import { RESOURCE_ONLY_ATTRIBUTES } from "../common/resource.js";
26
+ /**
27
+ * Forbidden attribute patterns for static analysis.
28
+ */
29
+ export const FORBIDDEN_ATTRIBUTE_PATTERNS = [
30
+ // Direct string literals
31
+ ...Array.from(TIER2_FORBIDDEN_ATTRIBUTES),
32
+ // Resource-only attributes
33
+ ...Array.from(RESOURCE_ONLY_ATTRIBUTES),
34
+ ];
35
+ /**
36
+ * ESLint rule metadata.
37
+ */
38
+ export const noForbiddenTelemetryAttributesMeta = {
39
+ type: "problem",
40
+ docs: {
41
+ description: "Disallow forbidden telemetry attributes in Tier 2 paths",
42
+ category: "Security",
43
+ recommended: true,
44
+ },
45
+ messages: {
46
+ forbiddenAttribute: "Attribute '{{name}}' is forbidden in Tier 2 telemetry. " +
47
+ "This data should only be in Tier 1 (local retention).",
48
+ resourceOnlyAttribute: "Attribute '{{name}}' should be a RESOURCE attribute, not a span attribute. " +
49
+ "Set it in initNodeTelemetry() config, not per-span.",
50
+ },
51
+ schema: [],
52
+ };
53
+ /**
54
+ * ESLint rule implementation.
55
+ *
56
+ * Detects patterns like:
57
+ * - span.setAttribute('prompt', value)
58
+ * - span.setAttributes({ prompt: value })
59
+ * - { 'prompt': value }
60
+ */
61
+ export function noForbiddenTelemetryAttributesCreate(context) {
62
+ const forbiddenSet = new Set(FORBIDDEN_ATTRIBUTE_PATTERNS);
63
+ const resourceOnlySet = RESOURCE_ONLY_ATTRIBUTES;
64
+ function checkAttributeName(node, name) {
65
+ if (TIER2_FORBIDDEN_ATTRIBUTES.has(name)) {
66
+ context.report({
67
+ node,
68
+ messageId: "forbiddenAttribute",
69
+ data: { name },
70
+ });
71
+ }
72
+ else if (resourceOnlySet.has(name)) {
73
+ context.report({
74
+ node,
75
+ messageId: "resourceOnlyAttribute",
76
+ data: { name },
77
+ });
78
+ }
79
+ }
80
+ return {
81
+ // Check span.setAttribute('forbidden', value)
82
+ CallExpression(node) {
83
+ if (node.callee.type === "MemberExpression" &&
84
+ node.callee.property.name === "setAttribute" &&
85
+ node.arguments.length >= 1 &&
86
+ node.arguments[0].type === "Literal" &&
87
+ typeof node.arguments[0].value === "string") {
88
+ checkAttributeName(node.arguments[0], node.arguments[0].value);
89
+ }
90
+ // Check span.setAttributes({ forbidden: value })
91
+ if (node.callee.type === "MemberExpression" &&
92
+ node.callee.property.name === "setAttributes" &&
93
+ node.arguments.length >= 1 &&
94
+ node.arguments[0].type === "ObjectExpression") {
95
+ for (const prop of node.arguments[0].properties) {
96
+ if (prop.key.type === "Literal" &&
97
+ typeof prop.key.value === "string") {
98
+ checkAttributeName(prop.key, prop.key.value);
99
+ }
100
+ else if (prop.key.type === "Identifier") {
101
+ checkAttributeName(prop.key, prop.key.name);
102
+ }
103
+ }
104
+ }
105
+ },
106
+ // Check object literals with forbidden keys in telemetry-related files
107
+ Property(node) {
108
+ // Only check if we're likely in a telemetry context
109
+ const filename = context.getFilename();
110
+ if (!filename.includes("telemetry") &&
111
+ !filename.includes("tracing") &&
112
+ !filename.includes("observability")) {
113
+ return;
114
+ }
115
+ let name = null;
116
+ if (node.key.type === "Literal" && typeof node.key.value === "string") {
117
+ name = node.key.value;
118
+ }
119
+ else if (node.key.type === "Identifier") {
120
+ name = node.key.name;
121
+ }
122
+ if (name && forbiddenSet.has(name)) {
123
+ checkAttributeName(node.key, name);
124
+ }
125
+ },
126
+ };
127
+ }
128
+ /**
129
+ * Complete ESLint rule export.
130
+ */
131
+ export const noForbiddenTelemetryAttributes = {
132
+ meta: noForbiddenTelemetryAttributesMeta,
133
+ create: noForbiddenTelemetryAttributesCreate,
134
+ };
135
+ /**
136
+ * ESLint rule: No Direct OTEL SDK Usage
137
+ *
138
+ * Detects direct usage of NodeSDK or WebTracerProvider outside the telemetry package.
139
+ */
140
+ export const noDirectOtelSdkMeta = {
141
+ type: "problem",
142
+ docs: {
143
+ description: "Disallow direct OpenTelemetry SDK usage outside telemetry package",
144
+ category: "Best Practices",
145
+ recommended: true,
146
+ },
147
+ messages: {
148
+ directSdkUsage: "Direct usage of '{{name}}' is not allowed. " +
149
+ "Use @superblocksteam/telemetry bootstrap functions instead.",
150
+ },
151
+ schema: [],
152
+ };
153
+ /**
154
+ * Forbidden OTEL SDK imports.
155
+ */
156
+ const FORBIDDEN_SDK_IMPORTS = [
157
+ "NodeSDK",
158
+ "WebTracerProvider",
159
+ "NodeTracerProvider",
160
+ "BasicTracerProvider",
161
+ ];
162
+ export function noDirectOtelSdkCreate(context) {
163
+ const filename = context.getFilename();
164
+ // Allow in telemetry package itself
165
+ if (filename.includes("packages/telemetry")) {
166
+ return {};
167
+ }
168
+ return {
169
+ ImportSpecifier(node) {
170
+ const importedName = node.imported.name;
171
+ if (FORBIDDEN_SDK_IMPORTS.includes(importedName)) {
172
+ context.report({
173
+ node,
174
+ messageId: "directSdkUsage",
175
+ data: { name: importedName },
176
+ });
177
+ }
178
+ },
179
+ // Also check require() calls
180
+ CallExpression(node) {
181
+ if (node.callee.name === "require" &&
182
+ node.arguments.length === 1 &&
183
+ node.arguments[0].type === "Literal") {
184
+ const requirePath = node.arguments[0].value;
185
+ if (typeof requirePath === "string" &&
186
+ (requirePath.includes("@opentelemetry/sdk-node") ||
187
+ requirePath.includes("@opentelemetry/sdk-trace-node") ||
188
+ requirePath.includes("@opentelemetry/sdk-trace-web"))) {
189
+ context.report({
190
+ node,
191
+ messageId: "directSdkUsage",
192
+ data: { name: requirePath },
193
+ });
194
+ }
195
+ }
196
+ },
197
+ };
198
+ }
199
+ export const noDirectOtelSdk = {
200
+ meta: noDirectOtelSdkMeta,
201
+ create: noDirectOtelSdkCreate,
202
+ };
203
+ /**
204
+ * All telemetry ESLint rules.
205
+ */
206
+ export const telemetryRules = {
207
+ "no-forbidden-attributes": noForbiddenTelemetryAttributes,
208
+ "no-direct-otel-sdk": noDirectOtelSdk,
209
+ };
210
+ //# sourceMappingURL=forbidden-attributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forbidden-attributes.js","sourceRoot":"","sources":["../../src/lint/forbidden-attributes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Telemetry ESLint Rules
3
+ *
4
+ * Lint rules for enforcing telemetry best practices:
5
+ * - no-forbidden-attributes: Prevents Tier 1 data in Tier 2 paths
6
+ * - no-direct-otel-sdk: Enforces use of telemetry bootstrap
7
+ */
8
+ export { noForbiddenTelemetryAttributes, noDirectOtelSdk, telemetryRules, FORBIDDEN_ATTRIBUTE_PATTERNS, } from "./forbidden-attributes.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,cAAc,EACd,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Telemetry ESLint Rules
3
+ *
4
+ * Lint rules for enforcing telemetry best practices:
5
+ * - no-forbidden-attributes: Prevents Tier 1 data in Tier 2 paths
6
+ * - no-direct-otel-sdk: Enforces use of telemetry bootstrap
7
+ */
8
+ export { noForbiddenTelemetryAttributes, noDirectOtelSdk, telemetryRules, FORBIDDEN_ATTRIBUTE_PATTERNS, } from "./forbidden-attributes.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,cAAc,EACd,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * LLMObs Tiered Telemetry
3
+ *
4
+ * This module provides tiered telemetry for LLMObs (LLM Observability) data:
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * createTier1LLMObsExporter,
10
+ * LLMObsTier2Summarizer,
11
+ * } from '@superblocksteam/telemetry/llmobs';
12
+ *
13
+ * // Tier 1: Local storage
14
+ * const { exporter, store } = createTier1LLMObsExporter();
15
+ *
16
+ * // Tier 2: Summarize for OTEL-aligned metrics
17
+ * const summarizer = new LLMObsTier2Summarizer(metricsClient);
18
+ * ```
19
+ */
20
+ export { Tier1LLMObsExporter, InMemoryLLMObsStore, createTier1LLMObsExporter, type LLMObsLocalStore, } from "./tier1-exporter.js";
21
+ export { LLMObsTier2Summarizer, type LLMSpanSummary, type ToolSpanSummary, type LLMErrorCategory, type LLMFinishReason, type LLMProvider, type LLMRequestMetricLabels, type TokenMetricLabels, type ToolCallMetricLabels, type Tier2MetricsClient, } from "./tier2-summarizer.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llmobs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * LLMObs Tiered Telemetry
3
+ *
4
+ * This module provides tiered telemetry for LLMObs (LLM Observability) data:
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * createTier1LLMObsExporter,
10
+ * LLMObsTier2Summarizer,
11
+ * } from '@superblocksteam/telemetry/llmobs';
12
+ *
13
+ * // Tier 1: Local storage
14
+ * const { exporter, store } = createTier1LLMObsExporter();
15
+ *
16
+ * // Tier 2: Summarize for OTEL-aligned metrics
17
+ * const summarizer = new LLMObsTier2Summarizer(metricsClient);
18
+ * ```
19
+ */
20
+ export { Tier1LLMObsExporter, InMemoryLLMObsStore, createTier1LLMObsExporter, } from "./tier1-exporter.js";
21
+ export { LLMObsTier2Summarizer, } from "./tier2-summarizer.js";
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llmobs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,GAE1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,qBAAqB,GAUtB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Tier 1 LLMObs Exporter
3
+ *
4
+ * Stores full-fidelity LLMObs spans locally for debugging.
5
+ * These spans contain prompts, code, tool IO - NEVER exported for cloud-prem.
6
+ *
7
+ * For cloud deployments, Tier 1 data can be exported (same trust boundary).
8
+ * For cloud-prem deployments, Tier 1 data stays local only.
9
+ */
10
+ import type { ExportResult } from "@opentelemetry/core";
11
+ import type { SpanExporter, ReadableSpan } from "@opentelemetry/sdk-trace-base";
12
+ /**
13
+ * Storage interface for Tier 1 LLMObs spans.
14
+ *
15
+ * Provides queryable access for local debugging.
16
+ * Implementation can be in-memory, filesystem, or local database.
17
+ */
18
+ export interface LLMObsLocalStore {
19
+ /**
20
+ * Store a span for later retrieval.
21
+ *
22
+ * @param span - The span to store
23
+ */
24
+ store(span: ReadableSpan): void;
25
+ /**
26
+ * Query spans by session ID.
27
+ *
28
+ * @param sessionId - Session ID to query
29
+ * @returns Matching spans
30
+ */
31
+ query(sessionId: string): ReadableSpan[];
32
+ /**
33
+ * Clear all stored spans.
34
+ */
35
+ clear(): void;
36
+ /**
37
+ * Get the count of stored spans.
38
+ */
39
+ size(): number;
40
+ }
41
+ /**
42
+ * In-memory implementation of LLMObsLocalStore.
43
+ *
44
+ * Suitable for development and short-lived processes.
45
+ * Spans are automatically evicted when limits are reached.
46
+ */
47
+ export declare class InMemoryLLMObsStore implements LLMObsLocalStore {
48
+ private readonly spans;
49
+ private readonly maxSpansPerSession;
50
+ private readonly maxSessions;
51
+ private totalSpanCount;
52
+ /**
53
+ * Create an in-memory LLMObs store.
54
+ *
55
+ * @param options - Configuration options
56
+ * @param options.maxSpansPerSession - Maximum spans to retain per session (default: 1000)
57
+ * @param options.maxSessions - Maximum sessions to retain (default: 100)
58
+ */
59
+ constructor(options?: {
60
+ maxSpansPerSession?: number;
61
+ maxSessions?: number;
62
+ });
63
+ store(span: ReadableSpan): void;
64
+ query(sessionId: string): ReadableSpan[];
65
+ clear(): void;
66
+ size(): number;
67
+ /**
68
+ * Get all session IDs.
69
+ *
70
+ * @returns Array of session IDs
71
+ */
72
+ getSessions(): string[];
73
+ /**
74
+ * Extract session ID from span attributes.
75
+ */
76
+ private getSessionId;
77
+ }
78
+ /**
79
+ * Tier 1 LLMObs Exporter.
80
+ *
81
+ * Exports LLMObs spans to local storage only.
82
+ * These spans contain full fidelity debugging data (prompts, code, tool IO).
83
+ * NEVER exported to external backends in cloud-prem deployments.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const store = new InMemoryLLMObsStore();
88
+ * const exporter = new Tier1LLMObsExporter(store);
89
+ *
90
+ * // Later, query for debugging
91
+ * const spans = store.query(sessionId);
92
+ * ```
93
+ */
94
+ export declare class Tier1LLMObsExporter implements SpanExporter {
95
+ private readonly localStore;
96
+ private readonly debugLogging;
97
+ private isShutdown;
98
+ /**
99
+ * Create a Tier 1 LLMObs exporter.
100
+ *
101
+ * @param localStore - Storage for local spans
102
+ * @param options - Configuration options
103
+ * @param options.debugLogging - Enable debug logging (default: false)
104
+ */
105
+ constructor(localStore: LLMObsLocalStore, options?: {
106
+ debugLogging?: boolean;
107
+ });
108
+ /**
109
+ * Export spans to local storage.
110
+ *
111
+ * @param spans - Spans to export
112
+ * @param resultCallback - Callback with export result
113
+ */
114
+ export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
115
+ /**
116
+ * Shutdown the exporter.
117
+ */
118
+ shutdown(): Promise<void>;
119
+ /**
120
+ * Force flush (no-op for local storage).
121
+ */
122
+ forceFlush(): Promise<void>;
123
+ /**
124
+ * Check if a span is an LLMObs span.
125
+ */
126
+ private isLLMObsSpan;
127
+ /**
128
+ * Get span duration in milliseconds.
129
+ */
130
+ private getDurationMs;
131
+ }
132
+ /**
133
+ * Create a Tier 1 LLMObs exporter with in-memory storage.
134
+ *
135
+ * @param options - Configuration options
136
+ * @returns Exporter and store instances
137
+ */
138
+ export declare function createTier1LLMObsExporter(options?: {
139
+ maxSpansPerSession?: number;
140
+ maxSessions?: number;
141
+ debugLogging?: boolean;
142
+ }): {
143
+ exporter: Tier1LLMObsExporter;
144
+ store: InMemoryLLMObsStore;
145
+ };
146
+ //# sourceMappingURL=tier1-exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1-exporter.d.ts","sourceRoot":"","sources":["../../src/llmobs/tier1-exporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAEhC;;;;;OAKG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IAEzC;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;IAC1D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAChE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,cAAc,CAAK;IAE3B;;;;;;OAMG;gBAED,OAAO,GAAE;QAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO;IAMrE,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IA4B/B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE;IAIxC,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,OAAO,CAAC,YAAY;CAOrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;;OAMG;gBAED,UAAU,EAAE,gBAAgB,EAC5B,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO;IAM1C;;;;;OAKG;IACH,MAAM,CACJ,KAAK,EAAE,YAAY,EAAE,EACrB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,IAAI;IA4BP;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,aAAa;CAKtB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAShE"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Tier 1 LLMObs Exporter
3
+ *
4
+ * Stores full-fidelity LLMObs spans locally for debugging.
5
+ * These spans contain prompts, code, tool IO - NEVER exported for cloud-prem.
6
+ *
7
+ * For cloud deployments, Tier 1 data can be exported (same trust boundary).
8
+ * For cloud-prem deployments, Tier 1 data stays local only.
9
+ */
10
+ import { ExportResultCode } from "@opentelemetry/core";
11
+ /**
12
+ * In-memory implementation of LLMObsLocalStore.
13
+ *
14
+ * Suitable for development and short-lived processes.
15
+ * Spans are automatically evicted when limits are reached.
16
+ */
17
+ export class InMemoryLLMObsStore {
18
+ spans = new Map();
19
+ maxSpansPerSession;
20
+ maxSessions;
21
+ totalSpanCount = 0;
22
+ /**
23
+ * Create an in-memory LLMObs store.
24
+ *
25
+ * @param options - Configuration options
26
+ * @param options.maxSpansPerSession - Maximum spans to retain per session (default: 1000)
27
+ * @param options.maxSessions - Maximum sessions to retain (default: 100)
28
+ */
29
+ constructor(options = {}) {
30
+ this.maxSpansPerSession = options.maxSpansPerSession ?? 1000;
31
+ this.maxSessions = options.maxSessions ?? 100;
32
+ }
33
+ store(span) {
34
+ const sessionId = this.getSessionId(span) || "default";
35
+ // Create session if doesn't exist
36
+ if (!this.spans.has(sessionId)) {
37
+ // Evict oldest session if at capacity
38
+ if (this.spans.size >= this.maxSessions) {
39
+ const oldestSession = this.spans.keys().next().value;
40
+ if (oldestSession) {
41
+ const evictedSpans = this.spans.get(oldestSession)?.length ?? 0;
42
+ this.totalSpanCount -= evictedSpans;
43
+ this.spans.delete(oldestSession);
44
+ }
45
+ }
46
+ this.spans.set(sessionId, []);
47
+ }
48
+ const sessionSpans = this.spans.get(sessionId);
49
+ sessionSpans.push(span);
50
+ this.totalSpanCount++;
51
+ // Evict oldest spans in session if at capacity
52
+ if (sessionSpans.length > this.maxSpansPerSession) {
53
+ sessionSpans.shift();
54
+ this.totalSpanCount--;
55
+ }
56
+ }
57
+ query(sessionId) {
58
+ return this.spans.get(sessionId) ?? [];
59
+ }
60
+ clear() {
61
+ this.spans.clear();
62
+ this.totalSpanCount = 0;
63
+ }
64
+ size() {
65
+ return this.totalSpanCount;
66
+ }
67
+ /**
68
+ * Get all session IDs.
69
+ *
70
+ * @returns Array of session IDs
71
+ */
72
+ getSessions() {
73
+ return Array.from(this.spans.keys());
74
+ }
75
+ /**
76
+ * Extract session ID from span attributes.
77
+ */
78
+ getSessionId(span) {
79
+ return (span.attributes["llmobs.session_id"] ||
80
+ span.attributes["session.id"] ||
81
+ span.attributes["session_id"]);
82
+ }
83
+ }
84
+ /**
85
+ * Tier 1 LLMObs Exporter.
86
+ *
87
+ * Exports LLMObs spans to local storage only.
88
+ * These spans contain full fidelity debugging data (prompts, code, tool IO).
89
+ * NEVER exported to external backends in cloud-prem deployments.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const store = new InMemoryLLMObsStore();
94
+ * const exporter = new Tier1LLMObsExporter(store);
95
+ *
96
+ * // Later, query for debugging
97
+ * const spans = store.query(sessionId);
98
+ * ```
99
+ */
100
+ export class Tier1LLMObsExporter {
101
+ localStore;
102
+ debugLogging;
103
+ isShutdown = false;
104
+ /**
105
+ * Create a Tier 1 LLMObs exporter.
106
+ *
107
+ * @param localStore - Storage for local spans
108
+ * @param options - Configuration options
109
+ * @param options.debugLogging - Enable debug logging (default: false)
110
+ */
111
+ constructor(localStore, options = {}) {
112
+ this.localStore = localStore;
113
+ this.debugLogging = options.debugLogging ?? false;
114
+ }
115
+ /**
116
+ * Export spans to local storage.
117
+ *
118
+ * @param spans - Spans to export
119
+ * @param resultCallback - Callback with export result
120
+ */
121
+ export(spans, resultCallback) {
122
+ if (this.isShutdown) {
123
+ resultCallback({
124
+ code: ExportResultCode.FAILED,
125
+ error: new Error("Exporter is shutdown"),
126
+ });
127
+ return;
128
+ }
129
+ for (const span of spans) {
130
+ // Only store LLMObs-related spans
131
+ if (this.isLLMObsSpan(span)) {
132
+ this.localStore.store(span);
133
+ if (this.debugLogging) {
134
+ console.debug("[LLMObs Tier 1]", span.name, {
135
+ traceId: span.spanContext().traceId,
136
+ duration: this.getDurationMs(span),
137
+ hasInput: !!span.attributes["llmobs.input"],
138
+ hasOutput: !!span.attributes["llmobs.output"],
139
+ });
140
+ }
141
+ }
142
+ }
143
+ resultCallback({ code: ExportResultCode.SUCCESS });
144
+ }
145
+ /**
146
+ * Shutdown the exporter.
147
+ */
148
+ async shutdown() {
149
+ this.isShutdown = true;
150
+ }
151
+ /**
152
+ * Force flush (no-op for local storage).
153
+ */
154
+ async forceFlush() {
155
+ // No-op for local storage
156
+ }
157
+ /**
158
+ * Check if a span is an LLMObs span.
159
+ */
160
+ isLLMObsSpan(span) {
161
+ return (span.name.startsWith("ai.") ||
162
+ span.name.startsWith("llmobs.") ||
163
+ span.name.startsWith("llm.") ||
164
+ span.name.startsWith("tool.") ||
165
+ span.name.startsWith("clark.") ||
166
+ !!span.attributes["llmobs.span_kind"]);
167
+ }
168
+ /**
169
+ * Get span duration in milliseconds.
170
+ */
171
+ getDurationMs(span) {
172
+ const [startSecs, startNanos] = span.startTime;
173
+ const [endSecs, endNanos] = span.endTime;
174
+ return (endSecs - startSecs) * 1000 + (endNanos - startNanos) / 1e6;
175
+ }
176
+ }
177
+ /**
178
+ * Create a Tier 1 LLMObs exporter with in-memory storage.
179
+ *
180
+ * @param options - Configuration options
181
+ * @returns Exporter and store instances
182
+ */
183
+ export function createTier1LLMObsExporter(options) {
184
+ const store = new InMemoryLLMObsStore({
185
+ maxSpansPerSession: options?.maxSpansPerSession,
186
+ maxSessions: options?.maxSessions,
187
+ });
188
+ const exporter = new Tier1LLMObsExporter(store, {
189
+ debugLogging: options?.debugLogging,
190
+ });
191
+ return { exporter, store };
192
+ }
193
+ //# sourceMappingURL=tier1-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1-exporter.js","sourceRoot":"","sources":["../../src/llmobs/tier1-exporter.ts"],"names":[],"mappings":"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"}