@llmtracer/sdk 1.1.0 → 2.0.8

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 (102) hide show
  1. package/dist/cjs/caller.d.ts +6 -0
  2. package/dist/cjs/caller.d.ts.map +1 -0
  3. package/dist/cjs/caller.js +62 -0
  4. package/dist/cjs/caller.js.map +1 -0
  5. package/dist/cjs/config.d.ts +7 -0
  6. package/dist/cjs/config.d.ts.map +1 -0
  7. package/dist/cjs/config.js +10 -0
  8. package/dist/cjs/config.js.map +1 -0
  9. package/dist/cjs/context.d.ts +9 -0
  10. package/dist/cjs/context.d.ts.map +1 -0
  11. package/dist/cjs/context.js +21 -0
  12. package/dist/cjs/context.js.map +1 -0
  13. package/dist/cjs/index.d.ts +20 -0
  14. package/dist/cjs/index.d.ts.map +1 -0
  15. package/dist/cjs/index.js +94 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/patcher.d.ts +5 -0
  18. package/dist/cjs/patcher.d.ts.map +1 -0
  19. package/dist/cjs/patcher.js +131 -0
  20. package/dist/cjs/patcher.js.map +1 -0
  21. package/dist/cjs/providers/anthropic.d.ts +4 -0
  22. package/dist/cjs/providers/anthropic.d.ts.map +1 -0
  23. package/dist/cjs/providers/anthropic.js +126 -0
  24. package/dist/cjs/providers/anthropic.js.map +1 -0
  25. package/dist/cjs/providers/google.d.ts +4 -0
  26. package/dist/cjs/providers/google.d.ts.map +1 -0
  27. package/dist/cjs/providers/google.js +133 -0
  28. package/dist/cjs/providers/google.js.map +1 -0
  29. package/dist/cjs/providers/index.d.ts +4 -0
  30. package/dist/cjs/providers/index.d.ts.map +1 -0
  31. package/dist/cjs/providers/index.js +13 -0
  32. package/dist/cjs/providers/index.js.map +1 -0
  33. package/dist/cjs/providers/openai.d.ts +4 -0
  34. package/dist/cjs/providers/openai.d.ts.map +1 -0
  35. package/dist/cjs/providers/openai.js +123 -0
  36. package/dist/cjs/providers/openai.js.map +1 -0
  37. package/dist/cjs/schema.d.ts +18 -0
  38. package/dist/cjs/schema.d.ts.map +1 -0
  39. package/dist/cjs/schema.js +98 -0
  40. package/dist/cjs/schema.js.map +1 -0
  41. package/dist/cjs/transport.d.ts +15 -0
  42. package/dist/cjs/transport.d.ts.map +1 -0
  43. package/dist/cjs/transport.js +130 -0
  44. package/dist/cjs/transport.js.map +1 -0
  45. package/dist/cjs/wrapper.d.ts +3 -0
  46. package/dist/cjs/wrapper.d.ts.map +1 -0
  47. package/dist/cjs/wrapper.js +97 -0
  48. package/dist/cjs/wrapper.js.map +1 -0
  49. package/dist/esm/caller.d.ts +6 -0
  50. package/dist/esm/caller.d.ts.map +1 -0
  51. package/dist/esm/caller.js +59 -0
  52. package/dist/esm/caller.js.map +1 -0
  53. package/dist/esm/config.d.ts +7 -0
  54. package/dist/esm/config.d.ts.map +1 -0
  55. package/dist/esm/config.js +7 -0
  56. package/dist/esm/config.js.map +1 -0
  57. package/dist/esm/context.d.ts +9 -0
  58. package/dist/esm/context.d.ts.map +1 -0
  59. package/dist/esm/context.js +17 -0
  60. package/dist/esm/context.js.map +1 -0
  61. package/dist/esm/index.d.ts +20 -0
  62. package/dist/esm/index.d.ts.map +1 -0
  63. package/dist/esm/index.js +54 -0
  64. package/dist/esm/index.js.map +1 -0
  65. package/dist/esm/package.json +1 -0
  66. package/dist/esm/patcher.d.ts +5 -0
  67. package/dist/esm/patcher.d.ts.map +1 -0
  68. package/dist/esm/patcher.js +125 -0
  69. package/dist/esm/patcher.js.map +1 -0
  70. package/dist/esm/providers/anthropic.d.ts +4 -0
  71. package/dist/esm/providers/anthropic.d.ts.map +1 -0
  72. package/dist/esm/providers/anthropic.js +89 -0
  73. package/dist/esm/providers/anthropic.js.map +1 -0
  74. package/dist/esm/providers/google.d.ts +4 -0
  75. package/dist/esm/providers/google.d.ts.map +1 -0
  76. package/dist/esm/providers/google.js +96 -0
  77. package/dist/esm/providers/google.js.map +1 -0
  78. package/dist/esm/providers/index.d.ts +4 -0
  79. package/dist/esm/providers/index.d.ts.map +1 -0
  80. package/dist/esm/providers/index.js +4 -0
  81. package/dist/esm/providers/index.js.map +1 -0
  82. package/dist/esm/providers/openai.d.ts +4 -0
  83. package/dist/esm/providers/openai.d.ts.map +1 -0
  84. package/dist/esm/providers/openai.js +86 -0
  85. package/dist/esm/providers/openai.js.map +1 -0
  86. package/dist/esm/schema.d.ts +18 -0
  87. package/dist/esm/schema.d.ts.map +1 -0
  88. package/dist/esm/schema.js +93 -0
  89. package/dist/esm/schema.js.map +1 -0
  90. package/dist/esm/transport.d.ts +15 -0
  91. package/dist/esm/transport.d.ts.map +1 -0
  92. package/dist/esm/transport.js +122 -0
  93. package/dist/esm/transport.js.map +1 -0
  94. package/dist/esm/wrapper.d.ts +3 -0
  95. package/dist/esm/wrapper.d.ts.map +1 -0
  96. package/dist/esm/wrapper.js +61 -0
  97. package/dist/esm/wrapper.js.map +1 -0
  98. package/package.json +52 -11
  99. package/dist/index.d.ts +0 -118
  100. package/dist/index.d.ts.map +0 -1
  101. package/dist/index.js +0 -568
  102. package/dist/index.js.map +0 -1
@@ -0,0 +1,96 @@
1
+ import { config } from '../config';
2
+ import { buildEvent, printCapture } from '../schema';
3
+ import * as transport from '../transport';
4
+ /**
5
+ * Extract token counts from a Google GenAI response.
6
+ * The JS SDK may use camelCase while Python uses snake_case — we check both.
7
+ */
8
+ function extractTokens(metadata) {
9
+ const inputTokens = metadata?.input_tokens ?? metadata?.inputTokens ??
10
+ metadata?.promptTokenCount ?? metadata?.prompt_token_count ?? 0;
11
+ const outputTokens = metadata?.output_tokens ?? metadata?.outputTokens ??
12
+ metadata?.candidatesTokenCount ?? metadata?.candidates_token_count ?? 0;
13
+ const cachedTokens = metadata?.cached_content_token_count ?? metadata?.cachedContentTokenCount ?? 0;
14
+ const thoughtsTokens = metadata?.thoughts_token_count ?? metadata?.thoughtsTokenCount ?? 0;
15
+ const toolUseTokens = metadata?.tool_use_prompt_token_count ?? metadata?.toolUsePromptTokenCount ?? 0;
16
+ const totalReported = metadata?.total_token_count ?? metadata?.totalTokenCount ?? 0;
17
+ return { inputTokens, outputTokens, cachedTokens, thoughtsTokens, toolUseTokens, totalReported };
18
+ }
19
+ export function parseGoogleResponse(result) {
20
+ // Usage metadata may be at result.usageMetadata or result.usage_metadata
21
+ const metadata = result?.usageMetadata ?? result?.usage_metadata;
22
+ const { inputTokens, outputTokens, cachedTokens, thoughtsTokens, toolUseTokens, totalReported } = extractTokens(metadata);
23
+ if (config.debug) {
24
+ console.log(`[llmtracer] Google tokens — base_in=${inputTokens} cached=${cachedTokens} tools=${toolUseTokens} base_out=${outputTokens} thoughts=${thoughtsTokens} total_reported=${totalReported}`);
25
+ }
26
+ return {
27
+ provider: 'google',
28
+ model: result?.model ?? result?.modelVersion ?? 'unknown',
29
+ input_tokens: inputTokens + cachedTokens + toolUseTokens,
30
+ output_tokens: outputTokens + thoughtsTokens,
31
+ status: 'success',
32
+ };
33
+ }
34
+ export function wrapGoogleStream(result, context, elapsedMs, args) {
35
+ let model = 'unknown';
36
+ let lastMetadata = null;
37
+ function record() {
38
+ const { inputTokens, outputTokens, cachedTokens, thoughtsTokens, toolUseTokens, totalReported } = extractTokens(lastMetadata);
39
+ if (config.debug) {
40
+ console.log(`[llmtracer] Google tokens — base_in=${inputTokens} cached=${cachedTokens} tools=${toolUseTokens} base_out=${outputTokens} thoughts=${thoughtsTokens} total_reported=${totalReported}`);
41
+ }
42
+ const event = buildEvent(context, {
43
+ provider: 'google',
44
+ model,
45
+ input_tokens: inputTokens + cachedTokens + toolUseTokens,
46
+ output_tokens: outputTokens + thoughtsTokens,
47
+ status: 'success',
48
+ }, elapsedMs);
49
+ transport.enqueue(event);
50
+ if (config.debug)
51
+ printCapture(event);
52
+ }
53
+ return new Proxy(result, {
54
+ get(target, prop) {
55
+ if (prop === Symbol.asyncIterator) {
56
+ return function () {
57
+ const originalIterator = target[Symbol.asyncIterator]();
58
+ return {
59
+ async next() {
60
+ const iterResult = await originalIterator.next();
61
+ if (!iterResult.done) {
62
+ const chunk = iterResult.value;
63
+ // Extract model from chunk if available
64
+ if (chunk?.model || chunk?.modelVersion) {
65
+ model = chunk.model ?? chunk.modelVersion ?? model;
66
+ }
67
+ // Accumulate usage metadata — last chunk typically has the final totals
68
+ const metadata = chunk?.usageMetadata ?? chunk?.usage_metadata;
69
+ if (metadata) {
70
+ lastMetadata = metadata;
71
+ }
72
+ }
73
+ if (iterResult.done) {
74
+ try {
75
+ record();
76
+ }
77
+ catch {
78
+ // swallow
79
+ }
80
+ }
81
+ return iterResult;
82
+ },
83
+ return: originalIterator.return?.bind(originalIterator),
84
+ throw: originalIterator.throw?.bind(originalIterator),
85
+ };
86
+ };
87
+ }
88
+ const value = target[prop];
89
+ if (typeof value === 'function') {
90
+ return value.bind(target);
91
+ }
92
+ return value;
93
+ },
94
+ });
95
+ }
96
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/providers/google.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { parseOpenAIResponse, wrapOpenAIStream } from './openai';
2
+ export { parseAnthropicResponse, wrapAnthropicStream } from './anthropic';
3
+ export { parseGoogleResponse, wrapGoogleStream } from './google';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { parseOpenAIResponse, wrapOpenAIStream } from './openai';
2
+ export { parseAnthropicResponse, wrapAnthropicStream } from './anthropic';
3
+ export { parseGoogleResponse, wrapGoogleStream } from './google';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ContextData, ResponseData } from '../schema';
2
+ export declare function parseOpenAIResponse(result: any): ResponseData;
3
+ export declare function wrapOpenAIStream(result: any, context: ContextData, elapsedMs: number, args: any[]): any;
4
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGhF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG,GAAG,YAAY,CAoB7D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAqEvG"}
@@ -0,0 +1,86 @@
1
+ import { config } from '../config';
2
+ import { buildEvent, printCapture } from '../schema';
3
+ import * as transport from '../transport';
4
+ export function parseOpenAIResponse(result) {
5
+ const usage = result?.usage;
6
+ const inputTokens = usage?.prompt_tokens || 0;
7
+ const outputTokens = usage?.completion_tokens || 0;
8
+ if (config.debug) {
9
+ const reasoning = usage?.completion_tokens_details?.reasoning_tokens || 0;
10
+ const cached = usage?.prompt_tokens_details?.cached_tokens || 0;
11
+ console.log(`[llmtracer] OpenAI tokens — in=${inputTokens} out=${outputTokens} reasoning=${reasoning} cached=${cached}`);
12
+ }
13
+ return {
14
+ provider: 'openai',
15
+ model: result?.model || 'unknown',
16
+ input_tokens: inputTokens,
17
+ output_tokens: outputTokens,
18
+ status: 'success',
19
+ };
20
+ }
21
+ export function wrapOpenAIStream(result, context, elapsedMs, args) {
22
+ const chunks = [];
23
+ function record() {
24
+ // Look for usage in final chunks (OpenAI includes it when stream_options.include_usage = true)
25
+ let usage = null;
26
+ for (let i = chunks.length - 1; i >= 0; i--) {
27
+ if (chunks[i]?.usage) {
28
+ usage = chunks[i].usage;
29
+ break;
30
+ }
31
+ }
32
+ const model = chunks[0]?.model || 'unknown';
33
+ const inputTokens = usage?.prompt_tokens || 0;
34
+ const outputTokens = usage?.completion_tokens || 0;
35
+ if (config.debug) {
36
+ const reasoning = usage?.completion_tokens_details?.reasoning_tokens || 0;
37
+ const cached = usage?.prompt_tokens_details?.cached_tokens || 0;
38
+ console.log(`[llmtracer] OpenAI tokens — in=${inputTokens} out=${outputTokens} reasoning=${reasoning} cached=${cached}`);
39
+ }
40
+ const event = buildEvent(context, {
41
+ provider: 'openai',
42
+ model,
43
+ input_tokens: inputTokens,
44
+ output_tokens: outputTokens,
45
+ status: 'success',
46
+ }, elapsedMs);
47
+ transport.enqueue(event);
48
+ if (config.debug)
49
+ printCapture(event);
50
+ }
51
+ // Create a proxy that wraps the async iterator while forwarding everything else
52
+ return new Proxy(result, {
53
+ get(target, prop) {
54
+ if (prop === Symbol.asyncIterator) {
55
+ return function () {
56
+ const originalIterator = target[Symbol.asyncIterator]();
57
+ return {
58
+ async next() {
59
+ const iterResult = await originalIterator.next();
60
+ if (!iterResult.done) {
61
+ chunks.push(iterResult.value);
62
+ }
63
+ if (iterResult.done) {
64
+ try {
65
+ record();
66
+ }
67
+ catch {
68
+ // swallow
69
+ }
70
+ }
71
+ return iterResult;
72
+ },
73
+ return: originalIterator.return?.bind(originalIterator),
74
+ throw: originalIterator.throw?.bind(originalIterator),
75
+ };
76
+ };
77
+ }
78
+ const value = target[prop];
79
+ if (typeof value === 'function') {
80
+ return value.bind(target);
81
+ }
82
+ return value;
83
+ },
84
+ });
85
+ }
86
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { TraceContext } from './context';
2
+ import { getCallerInfo } from './caller';
3
+ export interface ContextData {
4
+ context: TraceContext | undefined;
5
+ caller: ReturnType<typeof getCallerInfo>;
6
+ provider: string;
7
+ }
8
+ export interface ResponseData {
9
+ provider: string;
10
+ model: string;
11
+ input_tokens: number;
12
+ output_tokens: number;
13
+ status: string;
14
+ }
15
+ export declare function buildContext(provider: string, args: any[]): ContextData;
16
+ export declare function buildEvent(contextData: ContextData, responseData: ResponseData, latencyMs: number): Record<string, any>;
17
+ export declare function printCapture(event: Record<string, any>): void;
18
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAc,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKzC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,WAAW,CAMvE;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuBvH;AAwCD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAyB7D"}
@@ -0,0 +1,93 @@
1
+ import { randomUUID } from 'crypto';
2
+ import { getCurrent } from './context';
3
+ import { getCallerInfo } from './caller';
4
+ const SDK_VERSION = '2.0.8';
5
+ const SDK_LANGUAGE = 'typescript';
6
+ export function buildContext(provider, args) {
7
+ return {
8
+ context: getCurrent(),
9
+ caller: getCallerInfo(),
10
+ provider,
11
+ };
12
+ }
13
+ export function buildEvent(contextData, responseData, latencyMs) {
14
+ const event = {
15
+ event_id: randomUUID(),
16
+ timestamp: new Date().toISOString(),
17
+ latency_ms: latencyMs,
18
+ sdk_version: SDK_VERSION,
19
+ sdk_language: SDK_LANGUAGE,
20
+ ...responseData,
21
+ ...contextData.caller,
22
+ };
23
+ if (contextData.context) {
24
+ event.trace_id = contextData.context.traceId;
25
+ event.span_id = contextData.context.spanId;
26
+ if (contextData.context.parentSpanId) {
27
+ event.parent_span_id = contextData.context.parentSpanId;
28
+ }
29
+ if (contextData.context.tags && Object.keys(contextData.context.tags).length > 0) {
30
+ event.tags = { ...contextData.context.tags };
31
+ }
32
+ }
33
+ return event;
34
+ }
35
+ // Cost lookup table for debug printing (per 1M tokens)
36
+ const COST_PER_M = {
37
+ 'gpt-4o': [2.5, 10],
38
+ 'gpt-4o-mini': [0.15, 0.6],
39
+ 'gpt-4-turbo': [10, 30],
40
+ 'gpt-4': [30, 60],
41
+ 'gpt-3.5-turbo': [0.5, 1.5],
42
+ 'o1': [15, 60],
43
+ 'o1-mini': [3, 12],
44
+ 'o3-mini': [1.1, 4.4],
45
+ 'claude-3-5-sonnet': [3, 15],
46
+ 'claude-3-5-haiku': [0.8, 4],
47
+ 'claude-3-opus': [15, 75],
48
+ 'claude-sonnet-4-5': [3, 15],
49
+ 'claude-haiku-4-5': [0.8, 4],
50
+ 'claude-opus-4-6': [15, 75],
51
+ 'gemini-2.5-pro': [1.25, 10],
52
+ 'gemini-2.5-flash': [0.15, 0.6],
53
+ 'gemini-2.0-flash': [0.1, 0.4],
54
+ 'gemini-1.5-pro': [1.25, 5],
55
+ 'gemini-1.5-flash': [0.075, 0.3],
56
+ };
57
+ function estimateCost(model, inputTokens, outputTokens) {
58
+ // Try exact match first, then prefix match
59
+ let rates = COST_PER_M[model];
60
+ if (!rates) {
61
+ for (const key of Object.keys(COST_PER_M)) {
62
+ if (model.startsWith(key)) {
63
+ rates = COST_PER_M[key];
64
+ break;
65
+ }
66
+ }
67
+ }
68
+ if (!rates)
69
+ return 0;
70
+ return (inputTokens * rates[0] + outputTokens * rates[1]) / 1000000;
71
+ }
72
+ export function printCapture(event) {
73
+ const model = event.model || 'unknown';
74
+ const input = (event.input_tokens || 0).toLocaleString();
75
+ const output = (event.output_tokens || 0).toLocaleString();
76
+ const cost = estimateCost(model, event.input_tokens || 0, event.output_tokens || 0);
77
+ const latency = ((event.latency_ms || 0) / 1000).toFixed(1);
78
+ let file = '';
79
+ if (event.caller_file) {
80
+ const parts = event.caller_file.replace(/\\/g, '/').split('/');
81
+ const filename = parts[parts.length - 1];
82
+ file = event.caller_line ? `${filename}:${event.caller_line}` : filename;
83
+ }
84
+ let traceInfo = '';
85
+ if (event.tags) {
86
+ const firstValue = Object.values(event.tags)[0];
87
+ if (firstValue)
88
+ traceInfo = ` trace:${firstValue}`;
89
+ }
90
+ const costStr = cost > 0 ? ` $${cost.toFixed(4)}` : '';
91
+ console.log(`[llmtracer] ${event.provider}/${model} ${input}\u2192${output} tokens${costStr} ${latency}s (${file})${traceInfo}`);
92
+ }
93
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare function start(): void;
2
+ export declare function enqueue(event: Record<string, any>): void;
3
+ export declare function flush(): Promise<void>;
4
+ export declare function stop(): void;
5
+ export declare function getQueueLength(): number;
6
+ declare function exitFlush(): void;
7
+ declare function registerExitHandlers(): void;
8
+ export declare const _testExports: {
9
+ exitFlush: typeof exitFlush;
10
+ registerExitHandlers: typeof registerExitHandlers;
11
+ readonly exitHandlersRegistered: boolean;
12
+ resetExitFlag(): void;
13
+ };
14
+ export {};
15
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAOA,wBAAgB,KAAK,IAAI,IAAI,CAI5B;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAWxD;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C;AAED,wBAAgB,IAAI,IAAI,IAAI,CAO3B;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAiCD,iBAAS,SAAS,IAAI,IAAI,CAoBzB;AAED,iBAAS,oBAAoB,IAAI,IAAI,CAqBpC;AAGD,eAAO,MAAM,YAAY;;;;;CAKxB,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { config } from './config';
2
+ let eventQueue = [];
3
+ let flushTimer = null;
4
+ let firstBatch = true;
5
+ let exitHandlersRegistered = false;
6
+ export function start() {
7
+ // Reset state for fresh start
8
+ firstBatch = true;
9
+ registerExitHandlers();
10
+ }
11
+ export function enqueue(event) {
12
+ eventQueue.push(event);
13
+ if (firstBatch) {
14
+ firstBatch = false;
15
+ // Flush immediately on first event
16
+ setImmediate(() => doFlush());
17
+ // Start regular 5s interval
18
+ flushTimer = setInterval(() => doFlush(), 5000);
19
+ flushTimer.unref();
20
+ }
21
+ }
22
+ export async function flush() {
23
+ await doFlush();
24
+ }
25
+ export function stop() {
26
+ if (flushTimer) {
27
+ clearInterval(flushTimer);
28
+ flushTimer = null;
29
+ }
30
+ eventQueue = [];
31
+ firstBatch = true;
32
+ }
33
+ export function getQueueLength() {
34
+ return eventQueue.length;
35
+ }
36
+ async function doFlush(timeoutMs = 10000) {
37
+ if (eventQueue.length === 0)
38
+ return;
39
+ const events = eventQueue.splice(0);
40
+ try {
41
+ const payload = JSON.stringify({ events });
42
+ const response = await fetch(config.endpoint, {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ 'Authorization': `Bearer ${config.apiKey}`,
47
+ },
48
+ body: payload,
49
+ signal: AbortSignal.timeout(timeoutMs),
50
+ });
51
+ if (config.debug) {
52
+ console.log(`[llmtracer] Flushed ${events.length} events \u2192 ${response.status}`);
53
+ }
54
+ }
55
+ catch (e) {
56
+ if (config.debug) {
57
+ console.log(`[llmtracer] Flush failed: ${e}`);
58
+ }
59
+ // Re-queue up to 100 events for retry
60
+ const requeue = events.slice(0, 100);
61
+ eventQueue.unshift(...requeue);
62
+ }
63
+ }
64
+ function exitFlush() {
65
+ try {
66
+ if (eventQueue.length === 0)
67
+ return;
68
+ const events = eventQueue.splice(0);
69
+ const payload = JSON.stringify({ events });
70
+ // Best-effort flush with short timeout — never log, never throw
71
+ fetch(config.endpoint, {
72
+ method: 'POST',
73
+ headers: {
74
+ 'Content-Type': 'application/json',
75
+ 'Authorization': `Bearer ${config.apiKey}`,
76
+ },
77
+ body: payload,
78
+ signal: AbortSignal.timeout(3000),
79
+ }).catch(() => { });
80
+ }
81
+ catch {
82
+ // crash-proof: swallow everything
83
+ }
84
+ }
85
+ function registerExitHandlers() {
86
+ if (exitHandlersRegistered)
87
+ return;
88
+ exitHandlersRegistered = true;
89
+ try {
90
+ process.on('beforeExit', () => {
91
+ try {
92
+ exitFlush();
93
+ }
94
+ catch { /* swallow */ }
95
+ });
96
+ process.on('SIGINT', () => {
97
+ try {
98
+ exitFlush();
99
+ }
100
+ catch { /* swallow */ }
101
+ process.exit(0);
102
+ });
103
+ process.on('SIGTERM', () => {
104
+ try {
105
+ exitFlush();
106
+ }
107
+ catch { /* swallow */ }
108
+ process.exit(0);
109
+ });
110
+ }
111
+ catch {
112
+ // crash-proof: if process.on fails, just skip
113
+ }
114
+ }
115
+ // Export for testing only
116
+ export const _testExports = {
117
+ exitFlush,
118
+ registerExitHandlers,
119
+ get exitHandlersRegistered() { return exitHandlersRegistered; },
120
+ resetExitFlag() { exitHandlersRegistered = false; },
121
+ };
122
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ResponseData } from './schema';
2
+ export declare function makeAsyncWrapper(originalFn: Function, provider: string, parseResponseFn: (result: any) => ResponseData, wrapStreamFn: (result: any, context: any, elapsedMs: number, args: any[]) => any): Function;
3
+ //# sourceMappingURL=wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,YAAY,EAAE,MAAM,UAAU,CAAC;AAGhF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,QAAQ,EACpB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,YAAY,EAC9C,YAAY,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAC/E,QAAQ,CA2DV"}
@@ -0,0 +1,61 @@
1
+ import { config } from './config';
2
+ import { buildContext, buildEvent, printCapture } from './schema';
3
+ import * as transport from './transport';
4
+ export function makeAsyncWrapper(originalFn, provider, parseResponseFn, wrapStreamFn) {
5
+ const wrapped = async function (...args) {
6
+ if (!config.enabled) {
7
+ return originalFn.apply(this, args);
8
+ }
9
+ // 1. Capture context (safe, no-throw)
10
+ let context = null;
11
+ try {
12
+ context = buildContext(provider, args);
13
+ }
14
+ catch {
15
+ // context stays null
16
+ }
17
+ // 2. Detect streaming
18
+ const isStream = args[0]?.stream === true;
19
+ // 2b. For OpenAI streams, inject stream_options to get usage data
20
+ if (isStream && provider === 'openai') {
21
+ try {
22
+ if (!args[0].stream_options?.include_usage) {
23
+ args[0] = { ...args[0], stream_options: { ...args[0].stream_options, include_usage: true } };
24
+ }
25
+ }
26
+ catch {
27
+ // swallow — never modify args if something goes wrong
28
+ }
29
+ }
30
+ // 3. ALWAYS call original — never blocked, never modified
31
+ const start = performance.now();
32
+ const result = await originalFn.apply(this, args);
33
+ const elapsedMs = Math.round(performance.now() - start);
34
+ // 4. Handle streaming result
35
+ if (isStream && context) {
36
+ try {
37
+ return wrapStreamFn(result, context, elapsedMs, args);
38
+ }
39
+ catch {
40
+ return result;
41
+ }
42
+ }
43
+ // 5. Handle non-streaming result
44
+ if (context) {
45
+ try {
46
+ const event = buildEvent(context, parseResponseFn(result), elapsedMs);
47
+ transport.enqueue(event);
48
+ if (config.debug)
49
+ printCapture(event);
50
+ }
51
+ catch {
52
+ // swallow silently
53
+ }
54
+ }
55
+ return result;
56
+ };
57
+ // Preserve function name for debugging
58
+ Object.defineProperty(wrapped, 'name', { value: originalFn.name });
59
+ return wrapped;
60
+ }
61
+ //# sourceMappingURL=wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../src/wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAC;AAChF,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAC9B,UAAoB,EACpB,QAAgB,EAChB,eAA8C,EAC9C,YAAgF;IAEhF,MAAM,OAAO,GAAG,KAAK,WAAsB,GAAG,IAAW;QACvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,sCAAsC;QACtC,IAAI,OAAO,GAAQ,IAAI,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAE1C,kEAAkE;QAClE,IAAI,QAAQ,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,CAAC;oBAC3C,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC;gBAC/F,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,sDAAsD;YACxD,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QAExD,6BAA6B;QAC7B,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;gBACtE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACzB,IAAI,MAAM,CAAC,KAAK;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,mBAAmB;YACrB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,uCAAuC;IACvC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,OAAO,OAAO,CAAC;AACjB,CAAC"}