@revenium/openai 1.0.10 → 1.0.11

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.
@@ -0,0 +1,125 @@
1
+ /**
2
+ * OpenAI Basic Example
3
+ *
4
+ * Shows how to use Revenium middleware with OpenAI chat completions and embeddings.
5
+ * Demonstrates seamless metadata integration - all metadata fields are optional!
6
+ */
7
+
8
+ import 'dotenv/config';
9
+ import { initializeReveniumFromEnv, patchOpenAIInstance } from '@revenium/openai';
10
+ import OpenAI from 'openai';
11
+
12
+ async function openaiBasicExample() {
13
+ console.log(' OpenAI Basic Usage with Seamless Metadata Integration\n');
14
+
15
+ // Initialize Revenium middleware
16
+ const initResult = initializeReveniumFromEnv();
17
+ if (!initResult.success) {
18
+ console.error(' Failed to initialize Revenium:', initResult.message);
19
+ process.exit(1);
20
+ }
21
+
22
+ // Create and patch OpenAI instance
23
+ const openai = patchOpenAIInstance(new OpenAI());
24
+
25
+ // Example 1: Basic chat completion (no metadata)
26
+ console.log('Example 1: Basic chat completion (automatic tracking)');
27
+
28
+ const basicResponse = await openai.chat.completions.create({
29
+ model: 'gpt-4o-mini',
30
+ messages: [{ role: 'user', content: 'What is TypeScript in one sentence?' }],
31
+ // No usageMetadata - still automatically tracked!
32
+ // No max_tokens - let response complete naturally
33
+ });
34
+
35
+ console.log('Response:', basicResponse.choices[0]?.message?.content);
36
+ console.log('Usage:', basicResponse.usage);
37
+ console.log(' Automatically tracked to Revenium without metadata\n');
38
+
39
+ // Example 2: Chat completion with rich metadata (all optional!)
40
+ console.log('Example 2: Chat completion with rich metadata');
41
+
42
+ const metadataResponse = await openai.chat.completions.create({
43
+ model: 'gpt-4o-mini',
44
+ messages: [
45
+ { role: 'user', content: 'Explain the benefits of using middleware in 2 sentences.' },
46
+ ],
47
+
48
+ // All metadata fields are optional - add what you need!
49
+ // Note: Nested subscriber structure matches Python middleware for consistency
50
+ usageMetadata: {
51
+ // User tracking (optional) - nested subscriber object
52
+ subscriber: {
53
+ id: 'user-12345',
54
+ email: 'developer@company.com',
55
+ credential: {
56
+ name: 'api-key',
57
+ value: 'key123',
58
+ },
59
+ },
60
+
61
+ // Business context (optional)
62
+ organizationId: 'my-customer',
63
+ productId: 'ai-assistant',
64
+
65
+ // Task classification (optional)
66
+ taskType: 'explanation-request',
67
+ traceId: `session-${Date.now()}`,
68
+
69
+ // Custom fields (optional)
70
+ agent: 'openai-basic-chat-node',
71
+ },
72
+ });
73
+
74
+ console.log('Response:', metadataResponse.choices[0]?.message?.content);
75
+ console.log('Usage:', metadataResponse.usage);
76
+ console.log(' Tracked with rich metadata for analytics\n');
77
+
78
+ // Example 3: Basic embeddings (no metadata)
79
+ console.log('Example 3: Basic embeddings (automatic tracking)');
80
+
81
+ const basicEmbedding = await openai.embeddings.create({
82
+ model: 'text-embedding-3-small',
83
+ input: 'Revenium middleware automatically tracks OpenAI usage',
84
+ // No usageMetadata - still automatically tracked!
85
+ });
86
+
87
+ console.log('Model:', basicEmbedding.model);
88
+ console.log('Usage:', basicEmbedding.usage);
89
+ console.log('Embedding dimensions:', basicEmbedding.data[0]?.embedding.length);
90
+ console.log('Embeddings automatically tracked without metadata\n');
91
+
92
+ // Example 4: Embeddings with metadata (all optional!)
93
+ console.log(' Example 4: Embeddings with rich metadata');
94
+
95
+ const metadataEmbedding = await openai.embeddings.create({
96
+ model: 'text-embedding-3-small',
97
+ input: 'Advanced text embedding with comprehensive tracking metadata',
98
+
99
+ // All metadata fields are optional - customize for your use case!
100
+ // Note: Nested subscriber structure for consistency across language implementations
101
+ usageMetadata: {
102
+ subscriber: {
103
+ id: 'embedding-user-789',
104
+ email: 'embeddings@company.com',
105
+ credential: {
106
+ name: 'embed-key',
107
+ value: 'embed123',
108
+ },
109
+ },
110
+ organizationId: 'my-company',
111
+ taskType: 'document-embedding',
112
+ productId: 'search-engine',
113
+ traceId: `embed-${Date.now()}`,
114
+ agent: 'openai-basic-embeddings-node',
115
+ },
116
+ });
117
+
118
+ console.log('Model:', metadataEmbedding.model);
119
+ console.log('Usage:', metadataEmbedding.usage);
120
+ console.log('Embedding dimensions:', metadataEmbedding.data[0]?.embedding.length);
121
+ console.log(' Embeddings tracked with metadata for business analytics\n');
122
+ }
123
+
124
+ // Run the example
125
+ openaiBasicExample().catch(console.error);
@@ -0,0 +1,183 @@
1
+ /**
2
+ * OpenAI Responses API Basic Examples
3
+ *
4
+ * This file demonstrates how to use the new OpenAI Responses API with the Revenium middleware.
5
+ * The Responses API is a new stateful API that brings together capabilities from chat completions
6
+ * and assistants API in one unified experience.
7
+ *
8
+ * Reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/responses
9
+ */
10
+
11
+ import 'dotenv/config';
12
+ import { initializeReveniumFromEnv, patchOpenAIInstance } from '@revenium/openai';
13
+ import OpenAI from 'openai';
14
+
15
+ // Import types for the new Responses API
16
+ import type { ResponsesCreateParams, ResponsesResponse } from '../src/types/responses-api.js';
17
+
18
+ async function main() {
19
+ // Initialize Revenium middleware
20
+ await initializeReveniumFromEnv();
21
+
22
+ // Create OpenAI client
23
+ const openai = new OpenAI({
24
+ apiKey: process.env.OPENAI_API_KEY,
25
+ });
26
+
27
+ // Patch the OpenAI instance to add Revenium tracking
28
+ patchOpenAIInstance(openai);
29
+
30
+ console.log(' OpenAI Responses API Basic Examples\n');
31
+
32
+ // Example 1: Basic Responses API call (no metadata)
33
+ console.log(' Example 1: Basic Responses API call (no metadata)');
34
+ try {
35
+ const responsesAPI = openai as any; // Type assertion for new API
36
+
37
+ if (responsesAPI.responses?.create) {
38
+ const response: ResponsesResponse = await responsesAPI.responses.create({
39
+ model: 'gpt-5',
40
+ input: 'What is the capital of France?',
41
+ } as ResponsesCreateParams);
42
+
43
+ console.log('Response ID:', response.id);
44
+ console.log('Model:', response.model);
45
+ console.log('Status:', response.status);
46
+ console.log('Output Text:', response.output_text);
47
+ console.log('Usage:', response.usage);
48
+ } else {
49
+ throw new Error('Responses API not available');
50
+ }
51
+ } catch (error) {
52
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
53
+ console.log(' Error:', (error as Error).message);
54
+ }
55
+
56
+ console.log('\n' + '='.repeat(50) + '\n');
57
+
58
+ // Example 2: Responses API with rich metadata
59
+ console.log(' Example 2: Responses API with rich metadata');
60
+ try {
61
+ const responsesAPI = openai as any;
62
+
63
+ if (responsesAPI.responses?.create) {
64
+ const response: ResponsesResponse = await responsesAPI.responses.create({
65
+ model: 'gpt-5',
66
+ input: [
67
+ {
68
+ role: 'user',
69
+ content: 'Explain quantum computing in simple terms.',
70
+ },
71
+ ],
72
+ max_output_tokens: 150,
73
+ usageMetadata: {
74
+ subscriber: {
75
+ id: 'user-123',
76
+ email: 'user@example.com',
77
+ credential: {
78
+ name: 'api-key',
79
+ value: 'sk-...',
80
+ },
81
+ },
82
+ organizationId: 'org-456',
83
+ productId: 'quantum-explainer',
84
+ taskType: 'educational-content',
85
+ traceId: 'trace-789',
86
+ agent: 'quantum-tutor',
87
+ responseQualityScore: 0.95,
88
+ },
89
+ } as ResponsesCreateParams);
90
+
91
+ console.log('Response ID:', response.id);
92
+ console.log('Model:', response.model);
93
+ console.log('Status:', response.status);
94
+ console.log('Output Text:', response.output_text?.substring(0, 100) + '...');
95
+ console.log('Usage:', response.usage);
96
+ } else {
97
+ throw new Error('Responses API not available');
98
+ }
99
+ } catch (error) {
100
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
101
+ console.log(' Error:', (error as Error).message);
102
+ }
103
+
104
+ console.log('\n' + '='.repeat(50) + '\n');
105
+
106
+ // Example 3: Basic Responses API with string input (no metadata)
107
+ console.log(' Example 3: Basic Responses API with string input (no metadata)');
108
+ try {
109
+ const responsesAPI = openai as any;
110
+
111
+ if (responsesAPI.responses?.create) {
112
+ const response: ResponsesResponse = await responsesAPI.responses.create({
113
+ model: 'gpt-5',
114
+ input: 'Write a haiku about programming.',
115
+ } as ResponsesCreateParams);
116
+
117
+ console.log('Response ID:', response.id);
118
+ console.log('Model:', response.model);
119
+ console.log('Status:', response.status);
120
+ console.log('Output Text:', response.output_text);
121
+ console.log('Usage:', response.usage);
122
+ } else {
123
+ throw new Error('Responses API not available');
124
+ }
125
+ } catch (error) {
126
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
127
+ console.log(' Error:', (error as Error).message);
128
+ }
129
+
130
+ console.log('\n' + '='.repeat(50) + '\n');
131
+
132
+ // Example 4: Advanced Responses API with comprehensive metadata
133
+ console.log(' Example 4: Advanced Responses API with comprehensive metadata');
134
+ try {
135
+ const responsesAPI = openai as any;
136
+
137
+ if (responsesAPI.responses?.create) {
138
+ const response: ResponsesResponse = await responsesAPI.responses.create({
139
+ model: 'gpt-5',
140
+ input: [
141
+ {
142
+ role: 'user',
143
+ content: 'Provide a comprehensive overview of the Responses API capabilities.',
144
+ },
145
+ ],
146
+ max_output_tokens: 200,
147
+ instructions: 'You are a helpful AI assistant specializing in API documentation.',
148
+ usageMetadata: {
149
+ subscriber: {
150
+ id: 'enterprise-user-456',
151
+ email: 'enterprise@company.com',
152
+ credential: {
153
+ name: 'enterprise-key',
154
+ value: 'sk-enterprise-...',
155
+ },
156
+ },
157
+ organizationId: 'enterprise-org-789',
158
+ productId: 'api-documentation-assistant',
159
+ taskType: 'technical-documentation',
160
+ traceId: 'enterprise-trace-012',
161
+ agent: 'documentation-expert',
162
+ responseQualityScore: 0.98,
163
+ },
164
+ } as ResponsesCreateParams);
165
+
166
+ console.log('Response ID:', response.id);
167
+ console.log('Model:', response.model);
168
+ console.log('Status:', response.status);
169
+ console.log('Output Text:', response.output_text?.substring(0, 150) + '...');
170
+ console.log('Usage:', response.usage);
171
+ console.log('Output Array Length:', response.output?.length);
172
+ } else {
173
+ throw new Error('Responses API not available');
174
+ }
175
+ } catch (error) {
176
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
177
+ console.log(' Error:', (error as Error).message);
178
+ }
179
+
180
+ console.log('\n All Responses API examples completed!');
181
+ }
182
+
183
+ main().catch(console.error);
@@ -0,0 +1,203 @@
1
+ /**
2
+ * OpenAI Responses API Streaming Examples
3
+ *
4
+ * This file demonstrates how to use the new OpenAI Responses API with streaming enabled
5
+ * using the Revenium middleware. The Responses API supports streaming for real-time
6
+ * response generation.
7
+ *
8
+ * Reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/responses
9
+ */
10
+
11
+ import 'dotenv/config';
12
+ import { initializeReveniumFromEnv, patchOpenAIInstance } from '@revenium/openai';
13
+ import OpenAI from 'openai';
14
+
15
+ // Import types for the new Responses API
16
+ import type { ResponsesCreateParams } from '../src/types/responses-api.js';
17
+
18
+ async function main() {
19
+ // Initialize Revenium middleware
20
+ await initializeReveniumFromEnv();
21
+
22
+ // Create OpenAI client
23
+ const openai = new OpenAI({
24
+ apiKey: process.env.OPENAI_API_KEY,
25
+ });
26
+
27
+ // Patch the OpenAI instance to add Revenium tracking
28
+ patchOpenAIInstance(openai);
29
+
30
+ console.log(' OpenAI Responses API Streaming Examples\n');
31
+
32
+ // Example 1: Basic Responses API streaming (no metadata)
33
+ console.log(' Example 1: Basic Responses API streaming (no metadata)');
34
+ try {
35
+ const responsesAPI = openai as any; // Type assertion for new API
36
+
37
+ if (responsesAPI.responses?.create) {
38
+ const stream = await responsesAPI.responses.create({
39
+ model: 'gpt-5',
40
+ input: 'Tell me a short story about a robot learning to paint.',
41
+ stream: true,
42
+ } as ResponsesCreateParams);
43
+
44
+ console.log('Streaming response:');
45
+ for await (const event of stream) {
46
+ if (event.type === 'response.output_text.delta') {
47
+ process.stdout.write(event.delta);
48
+ }
49
+ }
50
+ console.log('\n Stream completed');
51
+ } else {
52
+ throw new Error('Responses API not available');
53
+ }
54
+ } catch (error) {
55
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
56
+ console.log(' Error:', (error as Error).message);
57
+ }
58
+
59
+ console.log('\n' + '='.repeat(50) + '\n');
60
+
61
+ // Example 2: Responses API streaming with rich metadata
62
+ console.log(' Example 2: Responses API streaming with rich metadata');
63
+ try {
64
+ const responsesAPI = openai as any;
65
+
66
+ if (responsesAPI.responses?.create) {
67
+ const stream = await responsesAPI.responses.create({
68
+ model: 'gpt-5',
69
+ input: [
70
+ {
71
+ role: 'user',
72
+ content: 'Explain the concept of machine learning in a conversational way.',
73
+ },
74
+ ],
75
+ stream: true,
76
+ max_output_tokens: 200,
77
+ usageMetadata: {
78
+ subscriber: {
79
+ id: 'streaming-user-123',
80
+ email: 'streaming@example.com',
81
+ credential: {
82
+ name: 'streaming-key',
83
+ value: 'sk-streaming-...',
84
+ },
85
+ },
86
+ organizationId: 'streaming-org-456',
87
+ productId: 'ml-educator',
88
+ taskType: 'educational-streaming',
89
+ traceId: 'stream-trace-789',
90
+ agent: 'ml-tutor-stream',
91
+ responseQualityScore: 0.92,
92
+ },
93
+ } as ResponsesCreateParams);
94
+
95
+ console.log('Streaming response with metadata:');
96
+ for await (const event of stream) {
97
+ if (event.type === 'response.output_text.delta') {
98
+ process.stdout.write(event.delta);
99
+ }
100
+ }
101
+ console.log('\n Stream with metadata completed');
102
+ } else {
103
+ throw new Error('Responses API not available');
104
+ }
105
+ } catch (error) {
106
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
107
+ console.log(' Error:', (error as Error).message);
108
+ }
109
+
110
+ console.log('\n' + '='.repeat(50) + '\n');
111
+
112
+ // Example 3: Basic Responses API streaming with array input (no metadata)
113
+ console.log(' Example 3: Basic Responses API streaming with array input (no metadata)');
114
+ try {
115
+ const responsesAPI = openai as any;
116
+
117
+ if (responsesAPI.responses?.create) {
118
+ const stream = await responsesAPI.responses.create({
119
+ model: 'gpt-5',
120
+ input: [
121
+ {
122
+ role: 'user',
123
+ content: 'Write a poem about the beauty of code.',
124
+ },
125
+ ],
126
+ stream: true,
127
+ } as ResponsesCreateParams);
128
+
129
+ console.log('Streaming poetry:');
130
+ for await (const event of stream) {
131
+ if (event.type === 'response.output_text.delta') {
132
+ process.stdout.write(event.delta);
133
+ }
134
+ }
135
+ console.log('\n Poetry stream completed');
136
+ } else {
137
+ throw new Error('Responses API not available');
138
+ }
139
+ } catch (error) {
140
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
141
+ console.log(' Error:', (error as Error).message);
142
+ }
143
+
144
+ console.log('\n' + '='.repeat(50) + '\n');
145
+
146
+ // Example 4: Advanced Responses API streaming with comprehensive metadata
147
+ console.log(' Example 4: Advanced Responses API streaming with comprehensive metadata');
148
+ try {
149
+ const responsesAPI = openai as any;
150
+
151
+ if (responsesAPI.responses?.create) {
152
+ const stream = await responsesAPI.responses.create({
153
+ model: 'gpt-5',
154
+ input: [
155
+ {
156
+ role: 'user',
157
+ content:
158
+ 'Provide a detailed explanation of how streaming APIs work in real-time applications.',
159
+ },
160
+ ],
161
+ stream: true,
162
+ max_output_tokens: 300,
163
+ instructions:
164
+ 'You are a technical expert explaining streaming APIs with practical examples.',
165
+ usageMetadata: {
166
+ subscriber: {
167
+ id: 'advanced-streaming-user-789',
168
+ email: 'advanced@enterprise.com',
169
+ credential: {
170
+ name: 'enterprise-streaming-key',
171
+ value: 'sk-enterprise-streaming-...',
172
+ },
173
+ },
174
+ organizationId: 'enterprise-streaming-org-012',
175
+ productId: 'streaming-api-educator',
176
+ taskType: 'advanced-technical-streaming',
177
+ traceId: 'advanced-stream-trace-345',
178
+ agent: 'streaming-expert',
179
+ responseQualityScore: 0.97,
180
+ },
181
+ } as ResponsesCreateParams);
182
+
183
+ console.log('Advanced streaming response:');
184
+ let deltaCount = 0;
185
+ for await (const event of stream) {
186
+ if (event.type === 'response.output_text.delta') {
187
+ process.stdout.write(event.delta);
188
+ deltaCount++;
189
+ }
190
+ }
191
+ console.log(`\n Advanced stream completed (${deltaCount} delta events)`);
192
+ } else {
193
+ throw new Error('Responses API not available');
194
+ }
195
+ } catch (error) {
196
+ console.log('️ Responses API not yet available in this OpenAI SDK version');
197
+ console.log(' Error:', (error as Error).message);
198
+ }
199
+
200
+ console.log('\n All Responses API streaming examples completed!');
201
+ }
202
+
203
+ main().catch(console.error);
@@ -0,0 +1,161 @@
1
+ /**
2
+ * OpenAI Streaming Example
3
+ *
4
+ * Shows how to use Revenium middleware with streaming OpenAI responses and batch embeddings.
5
+ * Demonstrates seamless metadata integration with streaming - all metadata fields are optional!
6
+ */
7
+
8
+ import 'dotenv/config';
9
+ import { initializeReveniumFromEnv, patchOpenAIInstance } from '@revenium/openai';
10
+ import OpenAI from 'openai';
11
+
12
+ async function openaiStreamingExample() {
13
+ console.log(' OpenAI Streaming with Seamless Metadata Integration\n');
14
+
15
+ // Initialize Revenium middleware
16
+ const initResult = initializeReveniumFromEnv();
17
+ if (!initResult.success) {
18
+ console.error(' Failed to initialize Revenium:', initResult.message);
19
+ process.exit(1);
20
+ }
21
+
22
+ // Create and patch OpenAI instance
23
+ const openai = patchOpenAIInstance(new OpenAI());
24
+
25
+ // Example 1: Basic streaming (no metadata)
26
+ console.log(' Example 1: Basic streaming chat (automatic tracking)');
27
+ console.log(' Assistant: ');
28
+
29
+ const basicStream = await openai.chat.completions.create({
30
+ model: 'gpt-4o-mini',
31
+ messages: [{ role: 'user', content: 'Count from 1 to 5 slowly' }],
32
+ stream: true,
33
+ // No usageMetadata - still automatically tracked when stream completes!
34
+ // No max_tokens - let response complete naturally
35
+ });
36
+
37
+ for await (const chunk of basicStream) {
38
+ const content = chunk.choices[0]?.delta?.content || '';
39
+ if (content) {
40
+ process.stdout.write(content);
41
+ }
42
+ }
43
+
44
+ console.log('\n Streaming automatically tracked to Revenium without metadata\n');
45
+
46
+ // Example 2: Streaming with rich metadata (all optional!)
47
+ console.log(' Example 2: Streaming chat with rich metadata');
48
+ console.log(' Assistant: ');
49
+
50
+ const metadataStream = await openai.chat.completions.create({
51
+ model: 'gpt-4o-mini',
52
+ messages: [{ role: 'user', content: 'Write a haiku about middleware' }],
53
+ stream: true,
54
+
55
+ // All metadata fields are optional - add what you need for analytics!
56
+ // Note: Nested subscriber structure matches Python middleware implementation
57
+ usageMetadata: {
58
+ // User tracking (optional) - nested subscriber object
59
+ subscriber: {
60
+ id: 'streaming-user-456',
61
+ email: 'poet@company.com',
62
+ credential: {
63
+ name: 'stream-key',
64
+ value: 'stream456',
65
+ },
66
+ },
67
+
68
+ // Business context (optional)
69
+ organizationId: 'creative-company',
70
+ productId: 'ai-poet',
71
+
72
+ // Task classification (optional)
73
+ taskType: 'creative-writing',
74
+ traceId: `stream-${Date.now()}`,
75
+
76
+ // Custom fields (optional)
77
+ agent: 'openai-streaming-chat-metadata-node',
78
+ responseQualityScore: 0.9,
79
+ },
80
+ });
81
+
82
+ for await (const chunk of metadataStream) {
83
+ const content = chunk.choices[0]?.delta?.content || '';
84
+ if (content) {
85
+ process.stdout.write(content);
86
+ }
87
+ }
88
+
89
+ console.log('\n Streaming tracked with rich metadata for analytics\n');
90
+
91
+ // Example 3: Batch embeddings (no metadata)
92
+ console.log(' Example 3: Batch embeddings (automatic tracking)');
93
+
94
+ const batchEmbeddings = await openai.embeddings.create({
95
+ model: 'text-embedding-3-small',
96
+ input: [
97
+ 'First document for batch processing',
98
+ 'Second document for batch processing',
99
+ 'Third document for batch processing',
100
+ ],
101
+ // No usageMetadata - still automatically tracked!
102
+ });
103
+
104
+ console.log(' Model:', batchEmbeddings.model);
105
+ console.log(' Usage:', batchEmbeddings.usage);
106
+ console.log(' Embeddings count:', batchEmbeddings.data.length);
107
+ console.log(' Batch embeddings automatically tracked without metadata\n');
108
+
109
+ // Example 4: Embeddings with metadata for batch processing
110
+ console.log(' Example 4: Batch embeddings with metadata');
111
+
112
+ const metadataBatchEmbeddings = await openai.embeddings.create({
113
+ model: 'text-embedding-3-small',
114
+ input: [
115
+ 'Document 1: Streaming responses provide real-time feedback',
116
+ 'Document 2: Metadata enables rich business analytics',
117
+ 'Document 3: Batch processing improves efficiency',
118
+ ],
119
+
120
+ // All metadata fields are optional - perfect for batch operations!
121
+ usageMetadata: {
122
+ // User tracking (optional) - nested subscriber object
123
+ subscriber: {
124
+ id: 'batch-processor-123',
125
+ email: 'batch@data-company.com',
126
+ credential: {
127
+ name: 'batch-key',
128
+ value: 'batch-value-456',
129
+ },
130
+ },
131
+
132
+ // Business context (optional)
133
+ organizationId: 'data-company',
134
+ productId: 'document-search',
135
+
136
+ // Task classification (optional)
137
+ taskType: 'batch-document-embedding',
138
+ traceId: `batch-${Date.now()}`,
139
+
140
+ // Custom fields (optional)
141
+ agent: 'openai-batch-embeddings-metadata-node',
142
+ },
143
+ });
144
+
145
+ console.log(' Model:', metadataBatchEmbeddings.model);
146
+ console.log(' Usage:', metadataBatchEmbeddings.usage);
147
+ console.log(' Embeddings count:', metadataBatchEmbeddings.data.length);
148
+ console.log(' Batch embeddings tracked with metadata for business insights\n');
149
+
150
+ // Summary
151
+ console.log(' Summary:');
152
+ console.log(' Streaming responses work seamlessly with metadata');
153
+ console.log(' Usage tracked automatically when streams complete');
154
+ console.log(' Batch embeddings supported with optional metadata');
155
+ console.log(' All metadata fields are optional');
156
+ console.log(' No type casting required - native TypeScript support');
157
+ console.log(' Real-time streaming + comprehensive analytics');
158
+ }
159
+
160
+ // Run the example
161
+ openaiStreamingExample().catch(console.error);