langwatch 0.3.0-prerelease.1 → 0.3.0-prerelease.2

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 (184) hide show
  1. package/dist/chunk-4BZATFKJ.mjs +181 -0
  2. package/dist/chunk-4BZATFKJ.mjs.map +1 -0
  3. package/dist/chunk-CSC3CMIT.mjs +118 -0
  4. package/dist/chunk-CSC3CMIT.mjs.map +1 -0
  5. package/dist/chunk-F63YKTXA.mjs +47 -0
  6. package/dist/chunk-F63YKTXA.mjs.map +1 -0
  7. package/dist/chunk-G3AUABT7.js +4 -0
  8. package/dist/chunk-G3AUABT7.js.map +1 -0
  9. package/dist/chunk-HPC6Z7J4.js +118 -0
  10. package/dist/chunk-HPC6Z7J4.js.map +1 -0
  11. package/dist/chunk-KGDAENGD.js +50 -0
  12. package/dist/chunk-KGDAENGD.js.map +1 -0
  13. package/dist/chunk-LD74LVRU.js +47 -0
  14. package/dist/chunk-LD74LVRU.js.map +1 -0
  15. package/dist/chunk-OM7VY3XT.mjs +4 -0
  16. package/dist/chunk-OM7VY3XT.mjs.map +1 -0
  17. package/dist/chunk-PCQVQ7SB.js +45 -0
  18. package/dist/chunk-PCQVQ7SB.js.map +1 -0
  19. package/dist/chunk-PMBEK6YE.mjs +424 -0
  20. package/dist/chunk-PMBEK6YE.mjs.map +1 -0
  21. package/dist/chunk-PR3JDWC3.mjs +50 -0
  22. package/dist/chunk-PR3JDWC3.mjs.map +1 -0
  23. package/dist/chunk-PTJ6AAI7.js +360 -0
  24. package/dist/chunk-PTJ6AAI7.js.map +1 -0
  25. package/dist/chunk-QEWDG5QE.mjs +45 -0
  26. package/dist/chunk-QEWDG5QE.mjs.map +1 -0
  27. package/dist/chunk-REUCVT7A.mjs +39 -0
  28. package/dist/chunk-REUCVT7A.mjs.map +1 -0
  29. package/dist/chunk-SVJ7SCGB.js +424 -0
  30. package/dist/chunk-SVJ7SCGB.js.map +1 -0
  31. package/dist/chunk-VJSOCNPA.js +181 -0
  32. package/dist/chunk-VJSOCNPA.js.map +1 -0
  33. package/dist/chunk-WM2GRSRW.js +39 -0
  34. package/dist/chunk-WM2GRSRW.js.map +1 -0
  35. package/dist/chunk-Z5J5UI5E.mjs +360 -0
  36. package/dist/chunk-Z5J5UI5E.mjs.map +1 -0
  37. package/dist/client-B2HqIKg6.d.ts +51 -0
  38. package/dist/client-XyCqclCi.d.mts +51 -0
  39. package/dist/client-browser.d.mts +8 -0
  40. package/dist/client-browser.d.ts +8 -0
  41. package/dist/client-browser.js +83 -0
  42. package/dist/client-browser.js.map +1 -0
  43. package/dist/client-browser.mjs +83 -0
  44. package/dist/client-browser.mjs.map +1 -0
  45. package/dist/client-node.d.mts +8 -0
  46. package/dist/client-node.d.ts +8 -0
  47. package/dist/client-node.js +90 -0
  48. package/dist/client-node.js.map +1 -0
  49. package/dist/client-node.mjs +90 -0
  50. package/dist/client-node.mjs.map +1 -0
  51. package/dist/evaluation/index.d.mts +897 -0
  52. package/dist/evaluation/index.d.ts +897 -0
  53. package/dist/evaluation/index.js +13 -0
  54. package/dist/evaluation/index.js.map +1 -0
  55. package/dist/evaluation/index.mjs +13 -0
  56. package/dist/evaluation/index.mjs.map +1 -0
  57. package/dist/filterable-batch-span-processor-zO5kcjBY.d.mts +64 -0
  58. package/dist/filterable-batch-span-processor-zO5kcjBY.d.ts +64 -0
  59. package/dist/index.d.mts +48 -0
  60. package/{src/observability/exporters/langwatch-exporter.ts → dist/index.d.ts} +13 -18
  61. package/dist/index.js +30 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/index.mjs +30 -0
  64. package/dist/index.mjs.map +1 -0
  65. package/dist/observability/index.d.mts +260 -0
  66. package/dist/observability/index.d.ts +260 -0
  67. package/dist/observability/index.js +20 -0
  68. package/dist/observability/index.js.map +1 -0
  69. package/dist/observability/index.mjs +20 -0
  70. package/dist/observability/index.mjs.map +1 -0
  71. package/dist/observability/instrumentation/langchain/index.d.mts +40 -0
  72. package/dist/observability/instrumentation/langchain/index.d.ts +40 -0
  73. package/dist/observability/instrumentation/langchain/index.js +666 -0
  74. package/dist/observability/instrumentation/langchain/index.js.map +1 -0
  75. package/dist/observability/instrumentation/langchain/index.mjs +666 -0
  76. package/dist/observability/instrumentation/langchain/index.mjs.map +1 -0
  77. package/dist/prompt/index.d.mts +10 -0
  78. package/dist/prompt/index.d.ts +10 -0
  79. package/dist/prompt/index.js +18 -0
  80. package/dist/prompt/index.js.map +1 -0
  81. package/dist/prompt/index.mjs +18 -0
  82. package/dist/prompt/index.mjs.map +1 -0
  83. package/dist/prompt-BXJWdbQp.d.mts +1967 -0
  84. package/dist/prompt-BXJWdbQp.d.ts +1967 -0
  85. package/dist/record-evaluation-CmxMXa-3.d.mts +25 -0
  86. package/dist/record-evaluation-CmxMXa-3.d.ts +25 -0
  87. package/dist/trace-D-bZOuqb.d.mts +622 -0
  88. package/dist/trace-G2312klE.d.ts +622 -0
  89. package/package.json +9 -4
  90. package/.editorconfig +0 -16
  91. package/.eslintrc.cjs +0 -37
  92. package/copy-types.sh +0 -28
  93. package/examples/langchain/.env.example +0 -2
  94. package/examples/langchain/README.md +0 -42
  95. package/examples/langchain/package-lock.json +0 -2930
  96. package/examples/langchain/package.json +0 -27
  97. package/examples/langchain/src/cli-markdown.d.ts +0 -137
  98. package/examples/langchain/src/index.ts +0 -109
  99. package/examples/langchain/tsconfig.json +0 -25
  100. package/examples/langgraph/.env.example +0 -2
  101. package/examples/langgraph/README.md +0 -42
  102. package/examples/langgraph/package-lock.json +0 -3031
  103. package/examples/langgraph/package.json +0 -28
  104. package/examples/langgraph/src/cli-markdown.d.ts +0 -137
  105. package/examples/langgraph/src/index.ts +0 -196
  106. package/examples/langgraph/tsconfig.json +0 -25
  107. package/examples/mastra/.env.example +0 -2
  108. package/examples/mastra/README.md +0 -57
  109. package/examples/mastra/package-lock.json +0 -5296
  110. package/examples/mastra/package.json +0 -32
  111. package/examples/mastra/src/cli-markdown.d.ts +0 -137
  112. package/examples/mastra/src/index.ts +0 -120
  113. package/examples/mastra/src/mastra/agents/weather-agent.ts +0 -30
  114. package/examples/mastra/src/mastra/index.ts +0 -21
  115. package/examples/mastra/src/mastra/tools/weather-tool.ts +0 -102
  116. package/examples/mastra/tsconfig.json +0 -25
  117. package/examples/vercel-ai/.env.example +0 -2
  118. package/examples/vercel-ai/README.md +0 -38
  119. package/examples/vercel-ai/package-lock.json +0 -2571
  120. package/examples/vercel-ai/package.json +0 -27
  121. package/examples/vercel-ai/src/cli-markdown.d.ts +0 -137
  122. package/examples/vercel-ai/src/index.ts +0 -110
  123. package/examples/vercel-ai/src/instrumentation.ts +0 -9
  124. package/examples/vercel-ai/tsconfig.json +0 -25
  125. package/src/__tests__/client-browser.test.ts +0 -92
  126. package/src/__tests__/client-node.test.ts +0 -76
  127. package/src/__tests__/client.test.ts +0 -71
  128. package/src/__tests__/integration/client-browser.test.ts +0 -46
  129. package/src/__tests__/integration/client-node.test.ts +0 -46
  130. package/src/client-browser.ts +0 -70
  131. package/src/client-node.ts +0 -82
  132. package/src/client-shared.ts +0 -72
  133. package/src/client.ts +0 -119
  134. package/src/evaluation/__tests__/record-evaluation.test.ts +0 -112
  135. package/src/evaluation/__tests__/run-evaluation.test.ts +0 -171
  136. package/src/evaluation/index.ts +0 -2
  137. package/src/evaluation/record-evaluation.ts +0 -101
  138. package/src/evaluation/run-evaluation.ts +0 -133
  139. package/src/evaluation/tracer.ts +0 -3
  140. package/src/evaluation/types.ts +0 -23
  141. package/src/index.ts +0 -13
  142. package/src/internal/api/__tests__/errors.test.ts +0 -98
  143. package/src/internal/api/client.ts +0 -30
  144. package/src/internal/api/errors.ts +0 -32
  145. package/src/internal/generated/openapi/.gitkeep +0 -0
  146. package/src/internal/generated/types/.gitkeep +0 -0
  147. package/src/observability/__tests__/integration/base.test.ts +0 -74
  148. package/src/observability/__tests__/integration/browser-setup-ordering.test.ts +0 -60
  149. package/src/observability/__tests__/integration/complex-nested-spans.test.ts +0 -29
  150. package/src/observability/__tests__/integration/error-handling.test.ts +0 -24
  151. package/src/observability/__tests__/integration/langwatch-disabled-otel.test.ts +0 -24
  152. package/src/observability/__tests__/integration/langwatch-first-then-vercel.test.ts +0 -24
  153. package/src/observability/__tests__/integration/multiple-setup-attempts.test.ts +0 -27
  154. package/src/observability/__tests__/integration/otel-ordering.test.ts +0 -27
  155. package/src/observability/__tests__/integration/vercel-configurations.test.ts +0 -20
  156. package/src/observability/__tests__/integration/vercel-first-then-langwatch.test.ts +0 -27
  157. package/src/observability/__tests__/span.test.ts +0 -214
  158. package/src/observability/__tests__/trace.test.ts +0 -180
  159. package/src/observability/exporters/index.ts +0 -1
  160. package/src/observability/index.ts +0 -4
  161. package/src/observability/instrumentation/langchain/__tests__/integration/langchain-chatbot.test.ts +0 -112
  162. package/src/observability/instrumentation/langchain/__tests__/langchain.test.ts +0 -284
  163. package/src/observability/instrumentation/langchain/index.ts +0 -624
  164. package/src/observability/processors/__tests__/filterable-batch-span-exporter.test.ts +0 -98
  165. package/src/observability/processors/filterable-batch-span-processor.ts +0 -99
  166. package/src/observability/processors/index.ts +0 -1
  167. package/src/observability/semconv/attributes.ts +0 -185
  168. package/src/observability/semconv/events.ts +0 -42
  169. package/src/observability/semconv/index.ts +0 -16
  170. package/src/observability/semconv/values.ts +0 -159
  171. package/src/observability/span.ts +0 -728
  172. package/src/observability/trace.ts +0 -301
  173. package/src/prompt/__tests__/prompt.test.ts +0 -139
  174. package/src/prompt/get-prompt-version.ts +0 -49
  175. package/src/prompt/get-prompt.ts +0 -44
  176. package/src/prompt/index.ts +0 -3
  177. package/src/prompt/prompt.ts +0 -133
  178. package/src/prompt/service.ts +0 -221
  179. package/src/prompt/tracer.ts +0 -3
  180. package/src/prompt/types.ts +0 -0
  181. package/ts-to-zod.config.js +0 -35
  182. package/tsconfig.json +0 -26
  183. package/tsup.config.ts +0 -20
  184. package/vitest.config.ts +0 -9
@@ -1,27 +0,0 @@
1
- {
2
- "name": "vercel-ai-sdk-example",
3
- "version": "1.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "start": "tsc && dotenv -- node dist/index.js",
8
- "build": "tsc",
9
- "test": "echo \"Error: no test specified\" && exit 1"
10
- },
11
- "keywords": [],
12
- "author": "LangWatch",
13
- "type": "module",
14
- "license": "MIT",
15
- "dependencies": {
16
- "@ai-sdk/openai": "^2.0.0",
17
- "@opentelemetry/context-async-hooks": "^2.0.1",
18
- "@opentelemetry/sdk-node": "^0.203.0",
19
- "ai": "^5.0.0",
20
- "cli-markdown": "^3.5.1",
21
- "dotenv-cli": "^10.0.0",
22
- "langwatch": "file:../../"
23
- },
24
- "devDependencies": {
25
- "typescript": "^5.9.2"
26
- }
27
- }
@@ -1,137 +0,0 @@
1
- declare module 'cli-markdown' {
2
- export interface CliMarkdownOptions {
3
- /**
4
- * Custom styles for different markdown elements
5
- */
6
- styles?: {
7
- /**
8
- * Style for headings (h1, h2, h3, etc.)
9
- */
10
- heading?: string;
11
- /**
12
- * Style for bold text
13
- */
14
- bold?: string;
15
- /**
16
- * Style for italic text
17
- */
18
- italic?: string;
19
- /**
20
- * Style for code blocks
21
- */
22
- code?: string;
23
- /**
24
- * Style for inline code
25
- */
26
- inlineCode?: string;
27
- /**
28
- * Style for links
29
- */
30
- link?: string;
31
- /**
32
- * Style for lists
33
- */
34
- list?: string;
35
- /**
36
- * Style for blockquotes
37
- */
38
- blockquote?: string;
39
- /**
40
- * Style for horizontal rules
41
- */
42
- hr?: string;
43
- };
44
- /**
45
- * Whether to preserve line breaks
46
- */
47
- preserveLineBreaks?: boolean;
48
- /**
49
- * Custom renderer functions for different markdown elements
50
- */
51
- renderers?: {
52
- /**
53
- * Custom renderer for headings
54
- */
55
- heading?: (text: string, level: number) => string;
56
- /**
57
- * Custom renderer for paragraphs
58
- */
59
- paragraph?: (text: string) => string;
60
- /**
61
- * Custom renderer for lists
62
- */
63
- list?: (items: string[], ordered: boolean) => string;
64
- /**
65
- * Custom renderer for list items
66
- */
67
- listItem?: (text: string, index: number) => string;
68
- /**
69
- * Custom renderer for code blocks
70
- */
71
- code?: (code: string, language?: string) => string;
72
- /**
73
- * Custom renderer for inline code
74
- */
75
- inlineCode?: (code: string) => string;
76
- /**
77
- * Custom renderer for links
78
- */
79
- link?: (text: string, url: string) => string;
80
- /**
81
- * Custom renderer for images
82
- */
83
- image?: (alt: string, url: string) => string;
84
- /**
85
- * Custom renderer for blockquotes
86
- */
87
- blockquote?: (text: string) => string;
88
- /**
89
- * Custom renderer for horizontal rules
90
- */
91
- hr?: () => string;
92
- /**
93
- * Custom renderer for emphasis (bold/italic)
94
- */
95
- emphasis?: (text: string, type: 'bold' | 'italic') => string;
96
- };
97
- /**
98
- * Maximum width for text wrapping
99
- */
100
- maxWidth?: number;
101
- /**
102
- * Whether to enable ANSI color codes
103
- */
104
- colors?: boolean;
105
- /**
106
- * Custom color theme
107
- */
108
- theme?: {
109
- /**
110
- * Color for headings
111
- */
112
- heading?: string;
113
- /**
114
- * Color for links
115
- */
116
- link?: string;
117
- /**
118
- * Color for code
119
- */
120
- code?: string;
121
- /**
122
- * Color for blockquotes
123
- */
124
- blockquote?: string;
125
- };
126
- }
127
-
128
- /**
129
- * Converts markdown text to formatted CLI output
130
- * @param markdown - The markdown text to convert
131
- * @param options - Configuration options for the conversion
132
- * @returns Formatted CLI text
133
- */
134
- function cliMarkdown(markdown: string, options?: CliMarkdownOptions): string;
135
-
136
- export = cliMarkdown;
137
- }
@@ -1,110 +0,0 @@
1
- import { setupLangWatch } from "langwatch/node";
2
- import { getLangWatchTracer } from "langwatch";
3
- import { semconv } from "langwatch/observability";
4
- import { openai } from "@ai-sdk/openai";
5
- import { generateText } from "ai";
6
- import * as readline from "readline";
7
- import cliMarkdown from "cli-markdown";
8
-
9
- await setupLangWatch();
10
-
11
- const tracer = getLangWatchTracer("vercel-ai-sdk-example");
12
-
13
- async function main() {
14
- const threadId = crypto.randomUUID();
15
-
16
- const rl = readline.createInterface({
17
- input: process.stdin,
18
- output: process.stdout,
19
- });
20
-
21
- console.log('🤖 AI Chatbot started! Type "quit" to exit.');
22
- console.log("---");
23
-
24
- const conversationHistory: Array<{
25
- role: "user" | "assistant" | "system";
26
- content: string;
27
- }> = [
28
- {
29
- role: "system",
30
- content:
31
- "You are a helpful assistant that can answer questions and help with tasks. You may use markdown to format your responses.",
32
- },
33
- ];
34
-
35
- while (true) {
36
- let finish = false;
37
-
38
- await tracer.withActiveSpan("iteration", {
39
- attributes: {
40
- [semconv.ATTR_LANGWATCH_THREAD_ID]: threadId,
41
- },
42
- }, async (span) => {
43
- try {
44
- // Get user input
45
- const userInput = await new Promise<string>((resolve) => {
46
- rl.question("You: ", resolve);
47
- });
48
-
49
- // Check for exit command
50
- if (
51
- userInput.toLowerCase() === "quit" ||
52
- userInput.toLowerCase() === "exit"
53
- ) {
54
- console.log("👋 Goodbye!");
55
- finish = true;
56
- return;
57
- }
58
-
59
- // Skip empty input
60
- if (!userInput.trim()) {
61
- return;
62
- }
63
-
64
- // Add user message to conversation history
65
- conversationHistory.push({ role: "user", content: userInput });
66
-
67
- // Generate AI response
68
- console.log("🤖 Thinking...");
69
-
70
- const result = await generateText({
71
- model: openai("gpt-4.1-mini"),
72
- messages: conversationHistory,
73
- experimental_telemetry: { isEnabled: true },
74
- });
75
-
76
- const aiResponse = result.text;
77
-
78
- // Add AI response to conversation history
79
- conversationHistory.push({ role: "assistant", content: aiResponse });
80
-
81
- // Display AI response with markdown formatting
82
- console.log("AI:");
83
- console.log(
84
- `${cliMarkdown(aiResponse, {
85
- colors: true,
86
- maxWidth: 80,
87
- theme: {
88
- heading: "cyan",
89
- link: "blue",
90
- code: "green",
91
- blockquote: "yellow",
92
- },
93
- })}---`,
94
- );
95
- } catch (error) {
96
- console.error("❌ Error:", error);
97
- console.log("Please try again.");
98
- }
99
- });
100
-
101
- if (finish) {
102
- break;
103
- }
104
- }
105
-
106
- rl.close();
107
- }
108
-
109
- // Run the chatbot
110
- main().catch(console.error);
@@ -1,9 +0,0 @@
1
- import { registerOTel } from '@vercel/otel';
2
-
3
- export function register() {
4
- registerOTel({
5
- serviceName: 'vercel-ai-sdk-example',
6
- // Note: LangWatch SDK automatically sets up the trace exporter,
7
- // so no manual configuration is needed here
8
- });
9
- }
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "node16",
5
- "moduleResolution": "node16",
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "allowSyntheticDefaultImports": true,
13
- "resolveJsonModule": true,
14
- "declaration": true,
15
- "declarationMap": true,
16
- "sourceMap": true
17
- },
18
- "include": [
19
- "src/**/*"
20
- ],
21
- "exclude": [
22
- "node_modules",
23
- "dist"
24
- ]
25
- }
@@ -1,92 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
-
3
- // Mock window object for Node.js test environment
4
- const mockWindow = {
5
- addEventListener: vi.fn(),
6
- removeEventListener: vi.fn(),
7
- };
8
- global.window = mockWindow as any;
9
-
10
- vi.mock('@opentelemetry/sdk-trace-web', () => ({
11
- WebTracerProvider: vi.fn().mockImplementation(function (this: any, opts: any) {
12
- this.opts = opts;
13
- this.register = vi.fn();
14
- this.shutdown = vi.fn();
15
- }),
16
- BatchSpanProcessor: vi.fn().mockImplementation((exporter) => ({ exporter }))
17
- }));
18
- vi.mock('@opentelemetry/exporter-trace-otlp-http', () => ({
19
- OTLPTraceExporter: vi.fn().mockImplementation((opts) => ({
20
- url: opts.url,
21
- headers: opts.headers
22
- }))
23
- }));
24
- vi.mock('@opentelemetry/context-zone', () => ({
25
- ZoneContextManager: vi.fn().mockImplementation(() => ({}))
26
- }));
27
- vi.mock('@opentelemetry/propagator-b3', () => ({
28
- B3Propagator: vi.fn().mockImplementation(() => ({}))
29
- }));
30
- vi.mock('../observability/processors', () => ({
31
- FilterableBatchSpanProcessor: vi.fn().mockImplementation((exporter) => ({ exporter }))
32
- }));
33
-
34
- describe('client-browser setup', () => {
35
- let clientBrowser: any;
36
- let client: any;
37
- let WebTracerProvider: any;
38
- let FilterableBatchSpanProcessor: any;
39
- let OTLPTraceExporter: any;
40
-
41
- beforeEach(async () => {
42
- vi.clearAllMocks();
43
- vi.resetModules();
44
-
45
- mockWindow.addEventListener.mockClear();
46
-
47
- // Import fresh modules for each test to get clean state
48
- clientBrowser = await import('../client-browser.js');
49
- client = await import('../client.js');
50
-
51
- // Set config after importing modules
52
- client.setConfig({ apiKey: undefined, endpoint: undefined });
53
-
54
- // Import the mocked modules before each test to get fresh spies
55
- const sdkTraceWeb = await vi.importMock<any>('@opentelemetry/sdk-trace-web');
56
- WebTracerProvider = sdkTraceWeb.WebTracerProvider;
57
- const processors = await vi.importMock<any>('../observability/processors');
58
- FilterableBatchSpanProcessor = processors.FilterableBatchSpanProcessor;
59
- const otlpExporter = await vi.importMock<any>('@opentelemetry/exporter-trace-otlp-http');
60
- OTLPTraceExporter = otlpExporter.OTLPTraceExporter;
61
- });
62
-
63
- afterEach(() => {
64
- // Clean up global state by clearing the module cache
65
- vi.resetModules();
66
- });
67
-
68
- it('calls setConfig and sets up WebTracerProvider with correct options', async () => {
69
- await clientBrowser.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', skipOpenTelemetrySetup: false });
70
- expect(WebTracerProvider).toHaveBeenCalledTimes(1);
71
- const opts = WebTracerProvider.mock.instances[0].opts;
72
- expect(opts.spanProcessors[0].exporter.headers.Authorization).toBe('Bearer abc');
73
- expect(opts.spanProcessors[0].exporter.url).toContain('/api/otel/v1/traces');
74
- expect(mockWindow.addEventListener).toHaveBeenCalledWith('beforeunload', expect.any(Function));
75
- });
76
-
77
- it('calls shutdown on existing provider if setup is called again', async () => {
78
- await clientBrowser.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', skipOpenTelemetrySetup: false });
79
- const providerInstance = WebTracerProvider.mock.instances[0];
80
-
81
- // The current implementation prevents multiple setup calls, so we test the shutdown behavior differently
82
- // We'll test that the provider instance has a shutdown method that can be called
83
- expect(providerInstance.shutdown).toBeDefined();
84
- expect(typeof providerInstance.shutdown).toBe('function');
85
- });
86
-
87
- it('does not set up WebTracerProvider if skipOpenTelemetrySetup is true', async () => {
88
- await clientBrowser.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', skipOpenTelemetrySetup: true });
89
- expect(WebTracerProvider).not.toHaveBeenCalled();
90
- expect(mockWindow.addEventListener).not.toHaveBeenCalled();
91
- });
92
- });
@@ -1,76 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
-
3
- // Mock the modules before importing
4
- vi.mock('@opentelemetry/sdk-node', () => ({
5
- NodeSDK: vi.fn().mockImplementation(function (this: any, opts: any) {
6
- this.opts = opts;
7
- this.start = vi.fn();
8
- this.shutdown = vi.fn();
9
- })
10
- }));
11
- vi.mock('@opentelemetry/sdk-trace-base', () => ({
12
- BatchSpanProcessor: vi.fn().mockImplementation((exporter) => ({ exporter }))
13
- }));
14
- vi.mock('@opentelemetry/exporter-trace-otlp-http', () => ({
15
- OTLPTraceExporter: vi.fn().mockImplementation((opts) => opts)
16
- }));
17
- vi.mock('../observability', () => ({
18
- FilterableBatchSpanProcessor: vi.fn().mockImplementation((exporter) => ({ exporter }))
19
- }));
20
-
21
- describe('client-node setup', () => {
22
- let clientNode: any;
23
- let client: any;
24
- let NodeSDK: any;
25
- let BatchSpanProcessor: any;
26
- let OTLPTraceExporter: any;
27
-
28
- beforeEach(async () => {
29
- vi.clearAllMocks();
30
-
31
- // Clear module cache to get fresh instances
32
- vi.resetModules();
33
-
34
- // Import fresh modules for each test to get clean state
35
- clientNode = await import('../client-node.js');
36
- client = await import('../client.js');
37
-
38
- client.setConfig({ apiKey: undefined, endpoint: undefined });
39
-
40
- const sdkNode = await vi.importMock<any>('@opentelemetry/sdk-node');
41
- NodeSDK = sdkNode.NodeSDK;
42
- const sdkTraceBase = await vi.importMock<any>('@opentelemetry/sdk-trace-base');
43
- BatchSpanProcessor = sdkTraceBase.BatchSpanProcessor;
44
- const otlpExporter = await vi.importMock<any>('@opentelemetry/exporter-trace-otlp-http');
45
- OTLPTraceExporter = otlpExporter.OTLPTraceExporter;
46
- });
47
-
48
- afterEach(() => {
49
- // Clean up global state by clearing the module cache
50
- vi.resetModules();
51
- });
52
-
53
- it('calls setConfig and sets up NodeSDK with correct options', async () => {
54
- await clientNode.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', disableOpenTelemetryAutomaticSetup: false });
55
- expect(NodeSDK).toHaveBeenCalledTimes(1);
56
- const opts = NodeSDK.mock.instances[0].opts;
57
- expect(opts.spanProcessors[0].exporter.headers.Authorization).toBe('Bearer abc');
58
- expect(opts.spanProcessors[0].exporter.url).toContain('/api/otel/v1/traces');
59
- });
60
-
61
- it('calls shutdown on existing sdk if setup is called again', async () => {
62
- // First setup
63
- await clientNode.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', disableOpenTelemetryAutomaticSetup: false });
64
- const sdkInstance = NodeSDK.mock.instances[0];
65
-
66
- // The current implementation prevents multiple setup calls, so we test the shutdown behavior differently
67
- // We'll test that the SDK instance has a shutdown method that can be called
68
- expect(sdkInstance.shutdown).toBeDefined();
69
- expect(typeof sdkInstance.shutdown).toBe('function');
70
- });
71
-
72
- it('does not set up NodeSDK if skipOpenTelemetrySetup is true', async () => {
73
- await clientNode.setupLangWatch({ apiKey: 'abc', endpoint: 'https://foo', skipOpenTelemetrySetup: true });
74
- expect(NodeSDK).not.toHaveBeenCalled();
75
- });
76
- });
@@ -1,71 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterAll, vi } from "vitest";
2
-
3
- describe("client config", () => {
4
- let client: any;
5
-
6
- beforeEach(async () => {
7
- // Mock environment variables before importing the client module
8
- vi.stubEnv('LANGWATCH_API_KEY', undefined);
9
- vi.stubEnv('LANGWATCH_ENDPOINT', undefined);
10
-
11
- // Reset modules to ensure fresh import after env stubbing
12
- vi.resetModules();
13
-
14
- // Dynamically import the client module
15
- client = await import("../client.js");
16
-
17
- // Reset config before each test
18
- client.setConfig({
19
- apiKey: "",
20
- endpoint: void 0,
21
- disableOpenTelemetryAutomaticSetup: false,
22
- disableAutomaticInputCapture: false,
23
- disableAutomaticOutputCapture: false,
24
- });
25
- });
26
-
27
- afterAll(() => {
28
- // Restore original environment
29
- vi.unstubAllEnvs();
30
- });
31
-
32
- it("should use default values if nothing is set", () => {
33
- expect(client.getApiKey()).toBe("");
34
- expect(client.getEndpoint()).toBe("https://app.langwatch.ai");
35
- expect(client.canAutomaticallyCaptureInput()).toBe(true);
36
- expect(client.canAutomaticallyCaptureOutput()).toBe(true);
37
- });
38
-
39
- it("should use env vars if set", () => {
40
- process.env.LANGWATCH_API_KEY = "env-key";
41
- process.env.LANGWATCH_ENDPOINT = "https://env.endpoint";
42
-
43
- client.setConfig({});
44
-
45
- expect(client.getApiKey()).toBe("env-key");
46
- expect(client.getEndpoint()).toBe("https://env.endpoint");
47
- });
48
-
49
- it("should update config with setConfig", () => {
50
- client.setConfig({
51
- apiKey: "test-key",
52
- endpoint: "https://test.endpoint",
53
- disableAutomaticInputCapture: true,
54
- disableAutomaticOutputCapture: true,
55
- });
56
- expect(client.getApiKey()).toBe("test-key");
57
- expect(client.getEndpoint()).toBe("https://test.endpoint");
58
- expect(client.canAutomaticallyCaptureInput()).toBe(false);
59
- expect(client.canAutomaticallyCaptureOutput()).toBe(false);
60
- });
61
-
62
- it("should not override values if undefined is passed", () => {
63
- client.setConfig({
64
- apiKey: "first-key",
65
- endpoint: "https://first.endpoint",
66
- });
67
- client.setConfig({ apiKey: undefined, endpoint: undefined });
68
- expect(client.getApiKey()).toBe("first-key");
69
- expect(client.getEndpoint()).toBe("https://first.endpoint");
70
- });
71
- });
@@ -1,46 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import { setupLangWatch as setupBrowser } from '../../client-browser';
3
-
4
- // Mock window object for Node.js test environment
5
- const mockWindow = {
6
- addEventListener: vi.fn(),
7
- removeEventListener: vi.fn(),
8
- };
9
- global.window = mockWindow as any;
10
-
11
- describe('client-browser integration', () => {
12
- beforeEach(() => {
13
- vi.clearAllMocks();
14
- mockWindow.addEventListener.mockClear();
15
- });
16
-
17
- afterEach(() => {
18
- // Clean up global state by clearing the module cache
19
- vi.resetModules();
20
- });
21
-
22
- it('should start and shut down the WebTracerProvider without error', async () => {
23
- // First setup should complete without error
24
- await expect(setupBrowser({
25
- apiKey: 'integration-key',
26
- endpoint: 'http://localhost:9999',
27
- skipOpenTelemetrySetup: false,
28
- })).resolves.not.toThrow();
29
-
30
- // Second setup should also complete without error (triggers shutdown of previous)
31
- await expect(setupBrowser({
32
- apiKey: 'integration-key2',
33
- endpoint: 'http://localhost:9999',
34
- skipOpenTelemetrySetup: false,
35
- })).resolves.not.toThrow();
36
- });
37
-
38
- it('should not set up WebTracerProvider if skipOpenTelemetrySetup is true', async () => {
39
- // Should complete without error and without setting up WebTracerProvider
40
- await expect(setupBrowser({
41
- apiKey: 'integration-key',
42
- endpoint: 'http://localhost:9999',
43
- skipOpenTelemetrySetup: true,
44
- })).resolves.not.toThrow();
45
- });
46
- });
@@ -1,46 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
-
3
- describe('client-node integration', () => {
4
- let clientNode: any;
5
-
6
- beforeEach(async () => {
7
- vi.clearAllMocks();
8
- vi.resetModules();
9
- // Import fresh modules for each test to get clean state
10
- clientNode = await import('../../client-node.js');
11
- });
12
-
13
- afterEach(() => {
14
- // Clean up global state by clearing the module cache
15
- vi.resetModules();
16
- });
17
-
18
- it('should start and shut down the NodeSDK without error', async () => {
19
- // First setup should complete without error
20
- await expect(clientNode.setupLangWatch({
21
- apiKey: 'integration-key',
22
- endpoint: 'http://localhost:9999',
23
- disableOpenTelemetryAutomaticSetup: false,
24
- })).resolves.not.toThrow();
25
-
26
- // Reset module to clear setupCalled state for second call
27
- vi.resetModules();
28
- clientNode = await import('../../client-node.js');
29
-
30
- // Second setup should also complete without error (triggers shutdown of previous)
31
- await expect(clientNode.setupLangWatch({
32
- apiKey: 'integration-key2',
33
- endpoint: 'http://localhost:9999',
34
- disableOpenTelemetryAutomaticSetup: false,
35
- })).resolves.not.toThrow();
36
- });
37
-
38
- it('should not start NodeSDK if disableOpenTelemetryAutomaticSetup is true', async () => {
39
- // Should complete without error and without setting up NodeSDK
40
- await expect(clientNode.setupLangWatch({
41
- apiKey: 'integration-key',
42
- endpoint: 'http://localhost:9999',
43
- disableOpenTelemetryAutomaticSetup: true,
44
- })).resolves.not.toThrow();
45
- });
46
- });