@revenium/openai 1.0.11 → 1.0.13

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 (96) hide show
  1. package/.env.example +20 -0
  2. package/CHANGELOG.md +47 -47
  3. package/README.md +121 -964
  4. package/dist/cjs/core/config/loader.js +1 -1
  5. package/dist/cjs/core/config/loader.js.map +1 -1
  6. package/dist/cjs/core/config/manager.js +2 -1
  7. package/dist/cjs/core/config/manager.js.map +1 -1
  8. package/dist/cjs/core/providers/detector.js +3 -3
  9. package/dist/cjs/core/providers/detector.js.map +1 -1
  10. package/dist/cjs/core/tracking/api-client.js +1 -1
  11. package/dist/cjs/core/tracking/api-client.js.map +1 -1
  12. package/dist/cjs/core/tracking/payload-builder.js +17 -12
  13. package/dist/cjs/core/tracking/payload-builder.js.map +1 -1
  14. package/dist/cjs/index.js +23 -2
  15. package/dist/cjs/index.js.map +1 -1
  16. package/dist/cjs/types/index.js.map +1 -1
  17. package/dist/cjs/utils/metadata-builder.js +12 -5
  18. package/dist/cjs/utils/metadata-builder.js.map +1 -1
  19. package/dist/cjs/utils/stop-reason-mapper.js +4 -0
  20. package/dist/cjs/utils/stop-reason-mapper.js.map +1 -1
  21. package/dist/cjs/utils/url-builder.js +32 -7
  22. package/dist/cjs/utils/url-builder.js.map +1 -1
  23. package/dist/esm/core/config/loader.js +1 -1
  24. package/dist/esm/core/config/loader.js.map +1 -1
  25. package/dist/esm/core/config/manager.js +2 -1
  26. package/dist/esm/core/config/manager.js.map +1 -1
  27. package/dist/esm/core/providers/detector.js +3 -3
  28. package/dist/esm/core/providers/detector.js.map +1 -1
  29. package/dist/esm/core/tracking/api-client.js +1 -1
  30. package/dist/esm/core/tracking/api-client.js.map +1 -1
  31. package/dist/esm/core/tracking/payload-builder.js +17 -12
  32. package/dist/esm/core/tracking/payload-builder.js.map +1 -1
  33. package/dist/esm/index.js +22 -2
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/types/index.js.map +1 -1
  36. package/dist/esm/utils/metadata-builder.js +12 -5
  37. package/dist/esm/utils/metadata-builder.js.map +1 -1
  38. package/dist/esm/utils/stop-reason-mapper.js +4 -0
  39. package/dist/esm/utils/stop-reason-mapper.js.map +1 -1
  40. package/dist/esm/utils/url-builder.js +32 -7
  41. package/dist/esm/utils/url-builder.js.map +1 -1
  42. package/dist/types/core/config/manager.d.ts.map +1 -1
  43. package/dist/types/core/tracking/payload-builder.d.ts.map +1 -1
  44. package/dist/types/index.d.ts +23 -2
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/types/types/index.d.ts +9 -13
  47. package/dist/types/types/index.d.ts.map +1 -1
  48. package/dist/types/types/openai-augmentation.d.ts +1 -2
  49. package/dist/types/types/openai-augmentation.d.ts.map +1 -1
  50. package/dist/types/utils/metadata-builder.d.ts +2 -1
  51. package/dist/types/utils/metadata-builder.d.ts.map +1 -1
  52. package/dist/types/utils/stop-reason-mapper.d.ts.map +1 -1
  53. package/dist/types/utils/url-builder.d.ts +11 -3
  54. package/dist/types/utils/url-builder.d.ts.map +1 -1
  55. package/examples/README.md +213 -255
  56. package/examples/azure-basic.ts +26 -14
  57. package/examples/azure-responses-basic.ts +39 -10
  58. package/examples/azure-responses-streaming.ts +39 -10
  59. package/examples/azure-streaming.ts +41 -20
  60. package/examples/getting_started.ts +54 -0
  61. package/examples/openai-basic.ts +39 -17
  62. package/examples/openai-function-calling.ts +259 -0
  63. package/examples/openai-responses-basic.ts +38 -9
  64. package/examples/openai-responses-streaming.ts +38 -9
  65. package/examples/openai-streaming.ts +24 -13
  66. package/examples/openai-vision.ts +289 -0
  67. package/package.json +3 -9
  68. package/src/core/config/azure-config.ts +72 -0
  69. package/src/core/config/index.ts +23 -0
  70. package/src/core/config/loader.ts +66 -0
  71. package/src/core/config/manager.ts +95 -0
  72. package/src/core/config/validator.ts +89 -0
  73. package/src/core/providers/detector.ts +159 -0
  74. package/src/core/providers/index.ts +16 -0
  75. package/src/core/tracking/api-client.ts +78 -0
  76. package/src/core/tracking/index.ts +21 -0
  77. package/src/core/tracking/payload-builder.ts +137 -0
  78. package/src/core/tracking/usage-tracker.ts +189 -0
  79. package/src/core/wrapper/index.ts +9 -0
  80. package/src/core/wrapper/instance-patcher.ts +288 -0
  81. package/src/core/wrapper/request-handler.ts +423 -0
  82. package/src/core/wrapper/stream-wrapper.ts +100 -0
  83. package/src/index.ts +360 -0
  84. package/src/types/function-parameters.ts +251 -0
  85. package/src/types/index.ts +310 -0
  86. package/src/types/openai-augmentation.ts +232 -0
  87. package/src/types/responses-api.ts +308 -0
  88. package/src/utils/azure-model-resolver.ts +220 -0
  89. package/src/utils/constants.ts +21 -0
  90. package/src/utils/error-handler.ts +251 -0
  91. package/src/utils/metadata-builder.ts +228 -0
  92. package/src/utils/provider-detection.ts +257 -0
  93. package/src/utils/request-handler-factory.ts +285 -0
  94. package/src/utils/stop-reason-mapper.ts +78 -0
  95. package/src/utils/type-guards.ts +202 -0
  96. package/src/utils/url-builder.ts +68 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * OpenAI Function Calling Example
3
+ *
4
+ * Demonstrates how Revenium middleware seamlessly tracks function/tool calling usage
5
+ * with OpenAI chat completions. Shows automatic tracking of:
6
+ * - Function definitions and calls
7
+ * - Token usage including function call overhead
8
+ * - Multi-turn conversations with function execution
9
+ * - Cost calculation for function calling features
10
+ *
11
+ * All metadata fields are optional and work seamlessly with function calling!
12
+ *
13
+ * For complete metadata field reference, see:
14
+ * https://revenium.readme.io/reference/meter_ai_completion
15
+ *
16
+ * OpenAI Function Calling Reference:
17
+ * https://platform.openai.com/docs/guides/function-calling
18
+ */
19
+
20
+ import 'dotenv/config';
21
+ import { initializeReveniumFromEnv, patchOpenAIInstance } from '@revenium/openai';
22
+ import OpenAI from 'openai';
23
+
24
+ // Simulated weather API function
25
+ function getCurrentWeather(location: string, unit: 'celsius' | 'fahrenheit' = 'celsius'): string {
26
+ // Simulate weather data
27
+ const temperature = unit === 'celsius' ? 22 : 72;
28
+ const conditions = 'sunny';
29
+
30
+ return JSON.stringify({
31
+ location,
32
+ temperature,
33
+ unit,
34
+ conditions,
35
+ forecast: 'Clear skies throughout the day',
36
+ });
37
+ }
38
+
39
+ async function openAIFunctionCallingExample() {
40
+ console.log('🔧 OpenAI Function Calling with Revenium Tracking\n');
41
+
42
+ // Initialize Revenium middleware
43
+ const initResult = initializeReveniumFromEnv();
44
+ if (!initResult.success) {
45
+ console.error('❌ Failed to initialize Revenium:', initResult.message);
46
+ process.exit(1);
47
+ }
48
+
49
+ // Create and patch OpenAI instance
50
+ const openai = patchOpenAIInstance(new OpenAI());
51
+
52
+ // Define function schema for OpenAI
53
+ const tools: OpenAI.Chat.Completions.ChatCompletionTool[] = [
54
+ {
55
+ type: 'function',
56
+ function: {
57
+ name: 'get_current_weather',
58
+ description: 'Get the current weather in a given location',
59
+ parameters: {
60
+ type: 'object',
61
+ properties: {
62
+ location: {
63
+ type: 'string',
64
+ description: 'The city and state, e.g. San Francisco, CA',
65
+ },
66
+ unit: {
67
+ type: 'string',
68
+ enum: ['celsius', 'fahrenheit'],
69
+ description: 'The temperature unit to use',
70
+ },
71
+ },
72
+ required: ['location'],
73
+ },
74
+ },
75
+ },
76
+ ];
77
+
78
+ // Example 1: Function calling without metadata (automatic tracking)
79
+ console.log('📍 Example 1: Basic function calling (automatic tracking)\n');
80
+
81
+ const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
82
+ {
83
+ role: 'user',
84
+ content: "What's the weather like in San Francisco?",
85
+ },
86
+ ];
87
+
88
+ // First call - AI decides to use the function
89
+ const firstResponse = await openai.chat.completions.create({
90
+ model: 'gpt-4o-mini',
91
+ messages: messages,
92
+ tools: tools,
93
+ tool_choice: 'auto',
94
+ // No usageMetadata - still automatically tracked!
95
+ });
96
+
97
+ console.log('AI Response (First call):');
98
+ console.log('Usage:', firstResponse.usage);
99
+
100
+ const firstMessage = firstResponse.choices[0]?.message;
101
+ console.log('Finish reason:', firstResponse.choices[0]?.finish_reason);
102
+
103
+ // Check if AI wants to call a function
104
+ if (firstMessage?.tool_calls) {
105
+ console.log('\n🔧 AI decided to call function:', firstMessage.tool_calls[0]?.function.name);
106
+ console.log('Function arguments:', firstMessage.tool_calls[0]?.function.arguments);
107
+
108
+ // Execute the function
109
+ const functionCall = firstMessage.tool_calls[0];
110
+ const functionArgs = JSON.parse(functionCall?.function.arguments || '{}');
111
+ const functionResponse = getCurrentWeather(
112
+ functionArgs.location,
113
+ functionArgs.unit
114
+ );
115
+
116
+ console.log('Function result:', functionResponse);
117
+
118
+ // Add function call and result to conversation
119
+ messages.push(firstMessage);
120
+ messages.push({
121
+ role: 'tool',
122
+ tool_call_id: functionCall.id,
123
+ content: functionResponse,
124
+ });
125
+
126
+ // Second call - AI uses function result to answer
127
+ const secondResponse = await openai.chat.completions.create({
128
+ model: 'gpt-4o-mini',
129
+ messages: messages,
130
+ tools: tools,
131
+ // No usageMetadata - still automatically tracked!
132
+ });
133
+
134
+ console.log('\n💬 AI Final Response:');
135
+ console.log('Content:', secondResponse.choices[0]?.message?.content);
136
+ console.log('Usage:', secondResponse.usage);
137
+ console.log('✅ Function calling automatically tracked without metadata\n');
138
+ }
139
+
140
+ // Example 2: Function calling with rich metadata
141
+ console.log('📊 Example 2: Function calling with comprehensive metadata\n');
142
+
143
+ const metadataMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
144
+ {
145
+ role: 'user',
146
+ content: "I'm planning a trip. What's the weather in Boston and should I bring a jacket?",
147
+ },
148
+ ];
149
+
150
+ // First call with metadata
151
+ const metadataFirstResponse = await openai.chat.completions.create({
152
+ model: 'gpt-4o',
153
+ messages: metadataMessages,
154
+ tools: tools,
155
+ tool_choice: 'auto',
156
+
157
+ // ✨ All metadata fields are optional - perfect for tracking AI agents!
158
+ usageMetadata: {
159
+ subscriber: {
160
+ id: 'travel-user-456',
161
+ email: 'traveler@company.com',
162
+ credential: {
163
+ name: 'api-key',
164
+ value: 'travel-key-789',
165
+ },
166
+ },
167
+ organizationId: 'travel-agency-corp',
168
+ productId: 'ai-travel-assistant',
169
+ subscriptionId: 'sub-pro-travel-123',
170
+ taskType: 'function-calling-weather',
171
+ traceId: `func-call-${Date.now()}`,
172
+ agent: 'weather-assistant-node',
173
+ responseQualityScore: 0.95, // 0.0-1.0 scale
174
+ },
175
+ });
176
+
177
+ console.log('AI Response with Metadata (First call):');
178
+ console.log('Usage:', metadataFirstResponse.usage);
179
+
180
+ const metadataFirstMessage = metadataFirstResponse.choices[0]?.message;
181
+ console.log('Finish reason:', metadataFirstResponse.choices[0]?.finish_reason);
182
+
183
+ // Process function calls if any
184
+ if (metadataFirstMessage?.tool_calls) {
185
+ console.log('\n🔧 Function calls requested:', metadataFirstMessage.tool_calls.length);
186
+
187
+ // Execute each function call
188
+ for (const toolCall of metadataFirstMessage.tool_calls) {
189
+ console.log(' - Function:', toolCall.function.name);
190
+ console.log(' Arguments:', toolCall.function.arguments);
191
+
192
+ const functionArgs = JSON.parse(toolCall.function.arguments);
193
+ const functionResponse = getCurrentWeather(
194
+ functionArgs.location,
195
+ functionArgs.unit
196
+ );
197
+
198
+ console.log(' Result:', functionResponse);
199
+
200
+ // Add function result to conversation
201
+ metadataMessages.push(metadataFirstMessage);
202
+ metadataMessages.push({
203
+ role: 'tool',
204
+ tool_call_id: toolCall.id,
205
+ content: functionResponse,
206
+ });
207
+ }
208
+
209
+ // Second call with metadata - AI generates final response
210
+ const metadataSecondResponse = await openai.chat.completions.create({
211
+ model: 'gpt-4o',
212
+ messages: metadataMessages,
213
+ tools: tools,
214
+
215
+ // ✨ Same metadata carried through the conversation
216
+ usageMetadata: {
217
+ subscriber: {
218
+ id: 'travel-user-456',
219
+ email: 'traveler@company.com',
220
+ credential: {
221
+ name: 'api-key',
222
+ value: 'travel-key-789',
223
+ },
224
+ },
225
+ organizationId: 'travel-agency-corp',
226
+ productId: 'ai-travel-assistant',
227
+ subscriptionId: 'sub-pro-travel-123',
228
+ taskType: 'function-calling-weather',
229
+ traceId: `func-call-${Date.now()}`,
230
+ agent: 'weather-assistant-node',
231
+ responseQualityScore: 0.98, // 0.0-1.0 scale
232
+ },
233
+ });
234
+
235
+ console.log('\n💬 AI Final Response with Metadata:');
236
+ console.log('Content:', metadataSecondResponse.choices[0]?.message?.content);
237
+ console.log('Usage:', metadataSecondResponse.usage);
238
+ console.log('✅ Function calling tracked with rich metadata for AI agent analytics\n');
239
+ }
240
+
241
+ // Summary
242
+ console.log('📈 Function Calling Summary:');
243
+ console.log('✅ Function definitions work seamlessly with middleware');
244
+ console.log('✅ Token usage tracked including function call overhead');
245
+ console.log('✅ Multi-turn conversations fully supported');
246
+ console.log('✅ All metadata fields optional and work perfectly');
247
+ console.log('✅ Cost calculation includes function calling tokens');
248
+ console.log('✅ No type casting required - native TypeScript support');
249
+ console.log('✅ Perfect for tracking AI agents and tool usage\n');
250
+
251
+ console.log('💡 Use Cases:');
252
+ console.log(' - AI agents with tool access');
253
+ console.log(' - Customer support bots with API integrations');
254
+ console.log(' - Data analysis assistants with function execution');
255
+ console.log(' - Multi-step workflows with external tools');
256
+ }
257
+
258
+ // Run the example
259
+ openAIFunctionCallingExample().catch(console.error);
@@ -5,7 +5,16 @@
5
5
  * The Responses API is a new stateful API that brings together capabilities from chat completions
6
6
  * and assistants API in one unified experience.
7
7
  *
8
- * Reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/responses
8
+ * Metadata Options:
9
+ * - Start with basic usage (no metadata) - tracking works automatically
10
+ * - Add subscriber info for user tracking
11
+ * - Include organization/product IDs for business analytics
12
+ * - Use task type and trace ID for detailed analysis
13
+ *
14
+ * For complete metadata field reference, see:
15
+ * https://revenium.readme.io/reference/meter_ai_completion
16
+ *
17
+ * Responses API Reference: https://platform.openai.com/docs/api-reference/responses
9
18
  */
10
19
 
11
20
  import 'dotenv/config';
@@ -71,20 +80,30 @@ async function main() {
71
80
  ],
72
81
  max_output_tokens: 150,
73
82
  usageMetadata: {
83
+ // User identification
74
84
  subscriber: {
75
85
  id: 'user-123',
76
86
  email: 'user@example.com',
77
87
  credential: {
78
- name: 'api-key',
79
- value: 'sk-...',
88
+ name: 'api-key-prod',
89
+ value: 'key-efg-123',
80
90
  },
81
91
  },
92
+
93
+ // Organization & billing
82
94
  organizationId: 'org-456',
95
+ subscriptionId: 'plan-responses-2024',
96
+
97
+ // Product & task tracking
83
98
  productId: 'quantum-explainer',
84
99
  taskType: 'educational-content',
85
- traceId: 'trace-789',
86
100
  agent: 'quantum-tutor',
87
- responseQualityScore: 0.95,
101
+
102
+ // Session tracking
103
+ traceId: 'trace-789',
104
+
105
+ // Quality metrics
106
+ responseQualityScore: 0.95, // 0.0-1.0 scale
88
107
  },
89
108
  } as ResponsesCreateParams);
90
109
 
@@ -146,20 +165,30 @@ async function main() {
146
165
  max_output_tokens: 200,
147
166
  instructions: 'You are a helpful AI assistant specializing in API documentation.',
148
167
  usageMetadata: {
168
+ // User identification
149
169
  subscriber: {
150
170
  id: 'enterprise-user-456',
151
171
  email: 'enterprise@company.com',
152
172
  credential: {
153
- name: 'enterprise-key',
154
- value: 'sk-enterprise-...',
173
+ name: 'api-key-prod',
174
+ value: 'key-hij-456',
155
175
  },
156
176
  },
177
+
178
+ // Organization & billing
157
179
  organizationId: 'enterprise-org-789',
180
+ subscriptionId: 'plan-enterprise-docs-2024',
181
+
182
+ // Product & task tracking
158
183
  productId: 'api-documentation-assistant',
159
184
  taskType: 'technical-documentation',
160
- traceId: 'enterprise-trace-012',
161
185
  agent: 'documentation-expert',
162
- responseQualityScore: 0.98,
186
+
187
+ // Session tracking
188
+ traceId: 'enterprise-trace-012',
189
+
190
+ // Quality metrics
191
+ responseQualityScore: 0.98, // 0.0-1.0 scale
163
192
  },
164
193
  } as ResponsesCreateParams);
165
194
 
@@ -5,7 +5,16 @@
5
5
  * using the Revenium middleware. The Responses API supports streaming for real-time
6
6
  * response generation.
7
7
  *
8
- * Reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/responses
8
+ * Metadata Options:
9
+ * - Start with basic usage (no metadata) - tracking works automatically
10
+ * - Add subscriber info for user tracking
11
+ * - Include organization/product IDs for business analytics
12
+ * - Use task type and trace ID for detailed analysis
13
+ *
14
+ * For complete metadata field reference, see:
15
+ * https://revenium.readme.io/reference/meter_ai_completion
16
+ *
17
+ * Responses API Reference: https://platform.openai.com/docs/api-reference/responses
9
18
  */
10
19
 
11
20
  import 'dotenv/config';
@@ -75,20 +84,30 @@ async function main() {
75
84
  stream: true,
76
85
  max_output_tokens: 200,
77
86
  usageMetadata: {
87
+ // User identification
78
88
  subscriber: {
79
89
  id: 'streaming-user-123',
80
90
  email: 'streaming@example.com',
81
91
  credential: {
82
- name: 'streaming-key',
83
- value: 'sk-streaming-...',
92
+ name: 'api-key-prod',
93
+ value: 'key-klm-789',
84
94
  },
85
95
  },
96
+
97
+ // Organization & billing
86
98
  organizationId: 'streaming-org-456',
99
+ subscriptionId: 'plan-streaming-edu-2024',
100
+
101
+ // Product & task tracking
87
102
  productId: 'ml-educator',
88
103
  taskType: 'educational-streaming',
89
- traceId: 'stream-trace-789',
90
104
  agent: 'ml-tutor-stream',
91
- responseQualityScore: 0.92,
105
+
106
+ // Session tracking
107
+ traceId: 'stream-trace-789',
108
+
109
+ // Quality metrics
110
+ responseQualityScore: 0.92, // 0.0-1.0 scale
92
111
  },
93
112
  } as ResponsesCreateParams);
94
113
 
@@ -163,20 +182,30 @@ async function main() {
163
182
  instructions:
164
183
  'You are a technical expert explaining streaming APIs with practical examples.',
165
184
  usageMetadata: {
185
+ // User identification
166
186
  subscriber: {
167
187
  id: 'advanced-streaming-user-789',
168
188
  email: 'advanced@enterprise.com',
169
189
  credential: {
170
- name: 'enterprise-streaming-key',
171
- value: 'sk-enterprise-streaming-...',
190
+ name: 'api-key-prod',
191
+ value: 'key-nop-012',
172
192
  },
173
193
  },
194
+
195
+ // Organization & billing
174
196
  organizationId: 'enterprise-streaming-org-012',
197
+ subscriptionId: 'plan-enterprise-stream-2024',
198
+
199
+ // Product & task tracking
175
200
  productId: 'streaming-api-educator',
176
201
  taskType: 'advanced-technical-streaming',
177
- traceId: 'advanced-stream-trace-345',
178
202
  agent: 'streaming-expert',
179
- responseQualityScore: 0.97,
203
+
204
+ // Session tracking
205
+ traceId: 'advanced-stream-trace-345',
206
+
207
+ // Quality metrics
208
+ responseQualityScore: 0.97, // 0.0-1.0 scale
180
209
  },
181
210
  } as ResponsesCreateParams);
182
211
 
@@ -1,8 +1,17 @@
1
1
  /**
2
- * OpenAI Streaming Example
2
+ * OpenAI Streaming Example
3
3
  *
4
4
  * Shows how to use Revenium middleware with streaming OpenAI responses and batch embeddings.
5
5
  * Demonstrates seamless metadata integration with streaming - all metadata fields are optional!
6
+ *
7
+ * Metadata Options:
8
+ * - Start with basic usage (no metadata) - tracking works automatically
9
+ * - Add subscriber info for user tracking
10
+ * - Include organization/product IDs for business analytics
11
+ * - Use task type and trace ID for detailed analysis
12
+ *
13
+ * For complete metadata field reference, see:
14
+ * https://revenium.readme.io/reference/meter_ai_completion
6
15
  */
7
16
 
8
17
  import 'dotenv/config';
@@ -52,30 +61,32 @@ async function openaiStreamingExample() {
52
61
  messages: [{ role: 'user', content: 'Write a haiku about middleware' }],
53
62
  stream: true,
54
63
 
55
- // All metadata fields are optional - add what you need for analytics!
56
- // Note: Nested subscriber structure matches Python middleware implementation
64
+ // Optional metadata for advanced reporting, lineage tracking, and cost allocation
57
65
  usageMetadata: {
58
- // User tracking (optional) - nested subscriber object
66
+ // User identification
59
67
  subscriber: {
60
68
  id: 'streaming-user-456',
61
69
  email: 'poet@company.com',
62
70
  credential: {
63
- name: 'stream-key',
64
- value: 'stream456',
71
+ name: 'api-key-prod',
72
+ value: 'key-ghi-789',
65
73
  },
66
74
  },
67
75
 
68
- // Business context (optional)
76
+ // Organization & billing
69
77
  organizationId: 'creative-company',
70
- productId: 'ai-poet',
78
+ subscriptionId: 'plan-creative-2024',
71
79
 
72
- // Task classification (optional)
80
+ // Product & task tracking
81
+ productId: 'ai-poet',
73
82
  taskType: 'creative-writing',
74
- traceId: `stream-${Date.now()}`,
83
+ agent: 'openai-streaming-chat-node',
75
84
 
76
- // Custom fields (optional)
77
- agent: 'openai-streaming-chat-metadata-node',
78
- responseQualityScore: 0.9,
85
+ // Session tracking
86
+ traceId: 'stream-' + Date.now(),
87
+
88
+ // Quality metrics
89
+ responseQualityScore: 0.92, // 0.0-1.0 scale
79
90
  },
80
91
  });
81
92