@revenium/perplexity 1.0.5 → 1.0.7

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.
package/README.md CHANGED
@@ -31,9 +31,15 @@ import { createPerplexityClient } from "@revenium/perplexity";
31
31
  config();
32
32
 
33
33
  async function example() {
34
- // Create client instance
34
+ // Create client instance (uses environment variables by default)
35
35
  const client = createPerplexityClient();
36
36
 
37
+ // Or create with custom API key and base URL
38
+ const customClient = createPerplexityClient(
39
+ "your-api-key",
40
+ "https://api.perplexity.ai"
41
+ );
42
+
37
43
  // Make a chat completion
38
44
  const response = await client.createChatCompletion({
39
45
  model: "sonar-pro",
@@ -97,8 +103,11 @@ REVENIUM_METERING_BASE_URL=https://api.revenium.io/meter/v2
97
103
  # Optional: Perplexity base URL (defaults to https://api.perplexity.ai)
98
104
  PERPLEXITY_BASE_URL=https://api.perplexity.ai
99
105
 
100
- # Optional: Enable verbose logging
106
+ # Optional: Enable verbose logging for debugging
101
107
  REVENIUM_VERBOSE_STARTUP=true
108
+
109
+ # Optional: Set log level (DEBUG, INFO, WARNING, ERROR)
110
+ REVENIUM_LOG_LEVEL=INFO
102
111
  ```
103
112
 
104
113
  ## šŸ“š Examples
@@ -152,14 +161,22 @@ const stream = await client.createStreamingChatCompletion({
152
161
  content: "Write a creative story about AI",
153
162
  },
154
163
  ],
164
+ // Optional: Include usage metadata for tracking
165
+ usageMetadata: {
166
+ traceId: "story-generation-001",
167
+ taskType: "creative-writing",
168
+ subscriberEmail: "user@example.com",
169
+ },
155
170
  });
156
171
 
172
+ console.log("šŸ“ Streaming response:");
157
173
  for await (const chunk of stream) {
158
174
  const content = chunk.choices[0]?.delta?.content;
159
175
  if (content) {
160
176
  process.stdout.write(content);
161
177
  }
162
178
  }
179
+ console.log("\nāœ… Streaming completed!");
163
180
  ```
164
181
 
165
182
  ## šŸ“Š Usage Metadata
@@ -247,14 +264,33 @@ npm run run-all-examples
247
264
 
248
265
  ### PerplexityClient
249
266
 
250
- #### `createPerplexityClient(apiKey?: string)`
267
+ #### `createPerplexityClient(apiKey?: string, baseUrl?: string)`
251
268
 
252
269
  Creates a new Perplexity client instance.
253
270
 
271
+ **Parameters:**
272
+
273
+ - `apiKey` (optional): Your Perplexity API key. If not provided, uses `PERPLEXITY_API_KEY` environment variable.
274
+ - `baseUrl` (optional): Custom base URL for Perplexity API. If not provided, uses `PERPLEXITY_BASE_URL` environment variable or defaults to `https://api.perplexity.ai`.
275
+
254
276
  ```typescript
277
+ // Using environment variables
255
278
  const client = createPerplexityClient();
256
- // or
279
+
280
+ // With custom API key
257
281
  const client = createPerplexityClient("your-api-key");
282
+
283
+ // With custom API key and base URL
284
+ const client = createPerplexityClient(
285
+ "your-api-key",
286
+ "https://api.perplexity.ai"
287
+ );
288
+
289
+ // With custom base URL only (uses env var for API key)
290
+ const client = createPerplexityClient(
291
+ undefined,
292
+ "https://custom-perplexity-endpoint.com"
293
+ );
258
294
  ```
259
295
 
260
296
  #### `client.createChatCompletion(params)`
@@ -310,16 +346,74 @@ interface UsageMetadata {
310
346
  }
311
347
  ```
312
348
 
349
+ ## šŸ”§ Configuration Options
350
+
351
+ ### Client Configuration
352
+
353
+ The `createPerplexityClient` function accepts two optional parameters:
354
+
355
+ ```typescript
356
+ // All default configuration (uses environment variables)
357
+ const client = createPerplexityClient();
358
+
359
+ // Custom API key only
360
+ const client = createPerplexityClient("your-custom-api-key");
361
+
362
+ // Custom API key and base URL
363
+ const client = createPerplexityClient(
364
+ "your-custom-api-key",
365
+ "https://custom-perplexity-endpoint.com"
366
+ );
367
+
368
+ // Custom base URL only (API key from environment)
369
+ const client = createPerplexityClient(
370
+ undefined,
371
+ "https://custom-perplexity-endpoint.com"
372
+ );
373
+ ```
374
+
375
+ ### Environment Variable Priority
376
+
377
+ The client follows this priority order for configuration:
378
+
379
+ 1. **API Key**: Function parameter → `PERPLEXITY_API_KEY` environment variable
380
+ 2. **Base URL**: Function parameter → `PERPLEXITY_BASE_URL` environment variable → Default (`https://api.perplexity.ai`)
381
+
313
382
  ## šŸ”§ Integration Tips
314
383
 
315
384
  ### Express.js
316
385
 
317
386
  Load environment variables first, create a separate Perplexity module, and use the patched instance everywhere.
318
387
 
388
+ ```typescript
389
+ // perplexity.js
390
+ import { config } from "dotenv";
391
+ import { createPerplexityClient } from "@revenium/perplexity";
392
+
393
+ config();
394
+ export const perplexityClient = createPerplexityClient();
395
+ ```
396
+
319
397
  ### Next.js
320
398
 
321
399
  Use global variables to prevent re-initialization, works with both Pages and App Router.
322
400
 
401
+ ```typescript
402
+ // lib/perplexity.ts
403
+ import { createPerplexityClient } from "@revenium/perplexity";
404
+
405
+ declare global {
406
+ var perplexityClient: ReturnType<typeof createPerplexityClient> | undefined;
407
+ }
408
+
409
+ export const perplexityClient =
410
+ globalThis.perplexityClient ?? createPerplexityClient();
411
+
412
+ if (process.env.NODE_ENV !== "production") {
413
+ globalThis.perplexityClient = perplexityClient;
414
+ }
415
+ ```
416
+
323
417
  ### Serverless
324
418
 
325
419
  Implement singleton pattern for cold starts, handle CORS for browser clients.
@@ -335,6 +429,8 @@ Validate environment variables at startup, add health checks for orchestration.
335
429
  1. **Middleware not activating**: Ensure you're importing the package before creating client instances
336
430
  2. **Environment variables**: Verify all required environment variables are set
337
431
  3. **API keys**: Check that both Perplexity and Revenium API keys are valid
432
+ 4. **Custom base URL**: If using a custom base URL, ensure it's accessible and compatible with Perplexity API
433
+ 5. **Module imports**: Make sure you're using the correct import: `import { createPerplexityClient } from "@revenium/perplexity"`
338
434
 
339
435
  ### Debug Mode
340
436
 
@@ -97,11 +97,43 @@ async function processPerplexityResponse(response, transactionId, model, startTi
97
97
  try {
98
98
  const endTime = new Date();
99
99
  const duration = (0, utils_1.calculateDurationMs)(startTime, endTime);
100
- // Parse response body
101
- const responseData = await response.json();
102
- // Extract token counts and other data
103
- const tokenCounts = (0, utils_1.extractPerplexityTokenCounts)(responseData);
104
- const stopReason = (0, utils_1.extractStopReason)(responseData);
100
+ // Check if this is a streaming response
101
+ const contentType = response.headers.get("content-type") || "";
102
+ const isStreamingResponse = contentType.includes("text/plain") ||
103
+ contentType.includes("text/event-stream");
104
+ let responseData;
105
+ let tokenCounts = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
106
+ let stopReason = "END";
107
+ if (isStreamingResponse) {
108
+ // For streaming responses, we can't easily parse the full response
109
+ // We'll extract what we can from the stream or use defaults
110
+ const responseText = await response.text();
111
+ // Try to extract token information from the last complete JSON chunk
112
+ const jsonChunks = responseText
113
+ .split("\n")
114
+ .filter((line) => line.startsWith("data: ") && line !== "data: [DONE]")
115
+ .map((line) => line.substring(6)); // Remove 'data: ' prefix
116
+ if (jsonChunks.length > 0) {
117
+ try {
118
+ // Parse the last chunk to get usage information
119
+ const lastChunk = JSON.parse(jsonChunks[jsonChunks.length - 1]);
120
+ if (lastChunk.usage) {
121
+ tokenCounts = (0, utils_1.extractPerplexityTokenCounts)(lastChunk);
122
+ }
123
+ }
124
+ catch (e) {
125
+ // If we can't parse, use defaults
126
+ models_1.Logger.warning("Could not parse streaming response for token counts, using defaults");
127
+ }
128
+ }
129
+ responseData = { usage: tokenCounts };
130
+ }
131
+ else {
132
+ // Parse response body for non-streaming responses
133
+ responseData = await response.json();
134
+ tokenCounts = (0, utils_1.extractPerplexityTokenCounts)(responseData);
135
+ stopReason = (0, utils_1.extractStopReason)(responseData);
136
+ }
105
137
  const modelName = (0, utils_1.extractModelName)(responseData, model);
106
138
  // Send metering data (only if API key is available)
107
139
  if ((0, getEnv_1.getReveniumApiKey)()) {
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/perplexity-ai/middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/perplexity-ai/middleware.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,10 @@ async function metadataExample() {
30
30
  },
31
31
  });
32
32
 
33
- console.log("āœ… Response:", basicResponse.choices[0]?.message?.content?.substring(0, 100) + "...");
33
+ console.log(
34
+ "āœ… Response:",
35
+ basicResponse.choices[0]?.message?.content?.substring(0, 100) + "..."
36
+ );
34
37
 
35
38
  // Example 2: Advanced metadata
36
39
  console.log("\n2ļøāƒ£ Advanced metadata tracking:");
@@ -53,7 +56,10 @@ async function metadataExample() {
53
56
  },
54
57
  });
55
58
 
56
- console.log("āœ… Response:", advancedResponse.choices[0]?.message?.content?.substring(0, 100) + "...");
59
+ console.log(
60
+ "āœ… Response:",
61
+ advancedResponse.choices[0]?.message?.content?.substring(0, 100) + "..."
62
+ );
57
63
 
58
64
  // Example 3: Streaming with metadata
59
65
  console.log("\n3ļøāƒ£ Streaming with metadata:");
@@ -83,7 +89,6 @@ async function metadataExample() {
83
89
 
84
90
  console.log("\n\nšŸŽ‰ All metadata examples completed successfully!");
85
91
  console.log("šŸ“Š All usage tracked with custom metadata");
86
-
87
92
  } catch (error) {
88
93
  console.error("āŒ Error:", error);
89
94
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenium/perplexity",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "NodeJS middleware for perplexity's AI API",
5
5
  "homepage": "https://github.com/revenium/revenium-middleware-perplexity-node#readme",
6
6
  "bugs": {
@@ -0,0 +1,31 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ const basicExample = async () => {
4
+ console.log("\nšŸ¤– Perplexity AI - Basic Client Example");
5
+ console.log("=".repeat(50));
6
+
7
+ try {
8
+ // Create client instance
9
+ const client = createPerplexityClient();
10
+
11
+ // Make a simple chat completion
12
+ const response = await client.createChatCompletion({
13
+ model: "sonar-pro",
14
+ messages: [
15
+ {
16
+ role: "user",
17
+ content: "What is the meaning of life, the universe and everything?",
18
+ },
19
+ ],
20
+ });
21
+
22
+ console.log("āœ… Response received:");
23
+ console.log(response.choices[0].message.content);
24
+ console.log("\nšŸ“Š Token usage automatically tracked by middleware");
25
+ console.log("šŸŽ‰ Basic client example successful!");
26
+ } catch (error) {
27
+ console.error("āŒ Error:", error);
28
+ }
29
+ };
30
+
31
+ basicExample();
@@ -0,0 +1,82 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ async function customConfigExample() {
4
+ console.log("\nāš™ļø Perplexity AI - Custom Configuration Example");
5
+ console.log("=".repeat(50));
6
+
7
+ try {
8
+ // Example 1: Using environment variables (default)
9
+ console.log("\n1ļøāƒ£ Using environment variables:");
10
+ const defaultClient = createPerplexityClient();
11
+
12
+ const response1 = await defaultClient.createChatCompletion({
13
+ model: "sonar-pro",
14
+ messages: [
15
+ {
16
+ role: "user",
17
+ content: "Hello from default configuration!",
18
+ },
19
+ ],
20
+ });
21
+ console.log("āœ… Default config response:", response1.choices[0]?.message?.content?.substring(0, 50) + "...");
22
+
23
+ // Example 2: Custom API key only
24
+ console.log("\n2ļøāƒ£ Using custom API key:");
25
+ const customKeyClient = createPerplexityClient(process.env.PERPLEXITY_API_KEY);
26
+
27
+ const response2 = await customKeyClient.createChatCompletion({
28
+ model: "sonar-pro",
29
+ messages: [
30
+ {
31
+ role: "user",
32
+ content: "Hello from custom API key configuration!",
33
+ },
34
+ ],
35
+ });
36
+ console.log("āœ… Custom key response:", response2.choices[0]?.message?.content?.substring(0, 50) + "...");
37
+
38
+ // Example 3: Custom API key and base URL
39
+ console.log("\n3ļøāƒ£ Using custom API key and base URL:");
40
+ const fullCustomClient = createPerplexityClient(
41
+ process.env.PERPLEXITY_API_KEY,
42
+ "https://api.perplexity.ai"
43
+ );
44
+
45
+ const response3 = await fullCustomClient.createChatCompletion({
46
+ model: "sonar-pro",
47
+ messages: [
48
+ {
49
+ role: "user",
50
+ content: "Hello from fully custom configuration!",
51
+ },
52
+ ],
53
+ });
54
+ console.log("āœ… Full custom response:", response3.choices[0]?.message?.content?.substring(0, 50) + "...");
55
+
56
+ // Example 4: Custom base URL only (API key from env)
57
+ console.log("\n4ļøāƒ£ Using custom base URL only:");
58
+ const customUrlClient = createPerplexityClient(
59
+ undefined,
60
+ "https://api.perplexity.ai"
61
+ );
62
+
63
+ const response4 = await customUrlClient.createChatCompletion({
64
+ model: "sonar-pro",
65
+ messages: [
66
+ {
67
+ role: "user",
68
+ content: "Hello from custom URL configuration!",
69
+ },
70
+ ],
71
+ });
72
+ console.log("āœ… Custom URL response:", response4.choices[0]?.message?.content?.substring(0, 50) + "...");
73
+
74
+ console.log("\nšŸŽ‰ All configuration examples completed successfully!");
75
+ console.log("šŸ“Š All requests tracked by middleware regardless of configuration");
76
+
77
+ } catch (error) {
78
+ console.error("āŒ Error:", error);
79
+ }
80
+ }
81
+
82
+ customConfigExample();
@@ -0,0 +1,36 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ const enhancedExample = async () => {
4
+ console.log("\n1ļøāƒ£ Enhanced Example:");
5
+
6
+ try {
7
+ const client = createPerplexityClient();
8
+ const advancedResponse = await client.createChatCompletion({
9
+ model: "sonar-pro",
10
+ messages: [
11
+ {
12
+ role: "user",
13
+ content: "What are the latest developments in AI?",
14
+ },
15
+ ],
16
+ usageMetadata: {
17
+ traceId: "conv-advanced-123",
18
+ taskType: "research",
19
+ subscriberId: "user-12345",
20
+ subscriberCredentialName: "api-key-1",
21
+ productId: "business-intelligence",
22
+ agent: "research-assistant-v2",
23
+ responseQualityScore: 0.95,
24
+ },
25
+ });
26
+
27
+ console.log(
28
+ "āœ… Response:",
29
+ advancedResponse.choices[0]?.message?.content?.substring(0, 100) + "..."
30
+ );
31
+ } catch (error) {
32
+ console.error("āŒ Error:", error);
33
+ }
34
+ };
35
+
36
+ enhancedExample();
@@ -0,0 +1,94 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ async function metadataExample() {
4
+ console.log("\nšŸ“Š Perplexity AI - Metadata Tracking Example");
5
+ console.log("=".repeat(50));
6
+
7
+ try {
8
+ // Create client instance
9
+ const client = createPerplexityClient();
10
+
11
+ // Example 1: Basic metadata
12
+ console.log("\n1ļøāƒ£ Basic metadata tracking:");
13
+ const basicResponse = await client.createChatCompletion({
14
+ model: "sonar-pro",
15
+ messages: [
16
+ {
17
+ role: "user",
18
+ content: "Analyze this quarterly report for key insights",
19
+ },
20
+ ],
21
+ usageMetadata: {
22
+ traceId: "conv-28a7e9d4",
23
+ taskType: "document-analysis",
24
+ subscriberEmail: "user@example.com",
25
+ organizationId: "acme-corp",
26
+ subscriptionId: "premium-plan",
27
+ },
28
+ });
29
+
30
+ console.log(
31
+ "āœ… Response:",
32
+ basicResponse.choices[0]?.message?.content?.substring(0, 100) + "..."
33
+ );
34
+
35
+ // Example 2: Advanced metadata
36
+ console.log("\n2ļøāƒ£ Advanced metadata tracking:");
37
+ const advancedResponse = await client.createChatCompletion({
38
+ model: "sonar-pro",
39
+ messages: [
40
+ {
41
+ role: "user",
42
+ content: "What are the latest developments in AI?",
43
+ },
44
+ ],
45
+ usageMetadata: {
46
+ traceId: "conv-advanced-123",
47
+ taskType: "research",
48
+ subscriberId: "user-12345",
49
+ subscriberCredentialName: "api-key-1",
50
+ productId: "business-intelligence",
51
+ agent: "research-assistant-v2",
52
+ responseQualityScore: 0.95,
53
+ },
54
+ });
55
+
56
+ console.log(
57
+ "āœ… Response:",
58
+ advancedResponse.choices[0]?.message?.content?.substring(0, 100) + "..."
59
+ );
60
+
61
+ // Example 3: Streaming with metadata
62
+ console.log("\n3ļøāƒ£ Streaming with metadata:");
63
+ const stream = await client.createStreamingChatCompletion({
64
+ model: "sonar-pro",
65
+ messages: [
66
+ {
67
+ role: "user",
68
+ content: "Write a creative story about AI",
69
+ },
70
+ ],
71
+ usageMetadata: {
72
+ traceId: "conv-streaming-456",
73
+ taskType: "creative-writing",
74
+ organizationId: "creative-studio",
75
+ agent: "story-generator",
76
+ },
77
+ });
78
+
79
+ console.log("šŸ“ Streaming response with metadata:");
80
+ for await (const chunk of stream) {
81
+ const content = chunk.choices[0]?.delta?.content;
82
+ if (content) {
83
+ process.stdout.write(content);
84
+ }
85
+ }
86
+
87
+ console.log("\n\nšŸŽ‰ All metadata examples completed successfully!");
88
+ console.log("šŸ“Š All usage tracked with custom metadata");
89
+ } catch (error) {
90
+ console.error("āŒ Error:", error);
91
+ }
92
+ }
93
+
94
+ metadataExample();
@@ -0,0 +1,62 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ async function multipleModelsExample() {
4
+ console.log("\nšŸ”§ Perplexity AI - Multiple Models Example");
5
+ console.log("=".repeat(50));
6
+
7
+ try {
8
+ // Create client instance
9
+ const client = createPerplexityClient();
10
+
11
+ // Test different prompts with the same model
12
+ const testCases = [
13
+ {
14
+ name: "sonar-pro (Quantum Computing)",
15
+ description: "Latest and most capable model",
16
+ prompt: "Explain quantum computing in simple terms",
17
+ },
18
+ {
19
+ name: "sonar-pro (AI Developments)",
20
+ description: "Latest and most capable model",
21
+ prompt: "What are the latest developments in AI?",
22
+ },
23
+ {
24
+ name: "sonar-pro (Weather)",
25
+ description: "Latest and most capable model",
26
+ prompt: "What is the weather like today?",
27
+ },
28
+ ];
29
+
30
+ for (const testCase of testCases) {
31
+ console.log(`\nšŸ¤– Testing: ${testCase.name}`);
32
+ console.log(`šŸ“ Description: ${testCase.description}`);
33
+ console.log("-".repeat(40));
34
+
35
+ try {
36
+ const response = await client.createChatCompletion({
37
+ model: "sonar-pro",
38
+ messages: [
39
+ {
40
+ role: "user",
41
+ content: testCase.prompt,
42
+ },
43
+ ],
44
+ });
45
+
46
+ console.log("āœ… Response:");
47
+ console.log(response.choices[0]?.message?.content?.substring(0, 200) + "...");
48
+ console.log("šŸ“Š Usage tracked by middleware");
49
+
50
+ } catch (error) {
51
+ console.log(`āŒ Error with ${testCase.name}:`, error);
52
+ }
53
+ }
54
+
55
+ console.log("\nšŸŽ‰ Multiple models example completed!");
56
+
57
+ } catch (error) {
58
+ console.error("āŒ Error:", error);
59
+ }
60
+ }
61
+
62
+ multipleModelsExample();
@@ -0,0 +1,73 @@
1
+ import { OpenAI } from "openai";
2
+
3
+ // Import middleware to activate automatic tracking
4
+ import "@revenium/perplexity";
5
+
6
+ async function openaiClientExample() {
7
+ console.log("\nšŸ¤– Perplexity AI - OpenAI Client Example");
8
+ console.log("=".repeat(50));
9
+
10
+ try {
11
+ // Create OpenAI client configured for Perplexity (like in basic example)
12
+ const client = new OpenAI({
13
+ apiKey: process.env.PERPLEXITY_API_KEY,
14
+ baseURL: "https://api.perplexity.ai",
15
+ });
16
+
17
+ console.log("āœ… OpenAI client configured for Perplexity AI");
18
+ console.log("šŸ“Š Middleware automatically tracking all requests");
19
+
20
+ // Test different types of requests
21
+ console.log("\n1ļøāƒ£ Basic chat completion:");
22
+ const basicResponse = await client.chat.completions.create({
23
+ model: "sonar-pro",
24
+ messages: [
25
+ {
26
+ role: "user",
27
+ content: "What is the meaning of life, the universe and everything?",
28
+ },
29
+ ],
30
+ });
31
+ console.log("āœ… Response:", basicResponse.choices[0]?.message?.content?.substring(0, 100) + "...");
32
+
33
+ console.log("\n2ļøāƒ£ Streaming chat completion:");
34
+ const stream = await client.chat.completions.create({
35
+ model: "sonar-pro",
36
+ messages: [
37
+ {
38
+ role: "user",
39
+ content: "Write a short poem about AI",
40
+ },
41
+ ],
42
+ stream: true,
43
+ });
44
+
45
+ console.log("šŸ“ Streaming response:");
46
+ for await (const chunk of stream) {
47
+ const content = chunk.choices[0]?.delta?.content;
48
+ if (content) {
49
+ process.stdout.write(content);
50
+ }
51
+ }
52
+
53
+ console.log("\n\n3ļøāƒ£ Different prompt:");
54
+ const differentResponse = await client.chat.completions.create({
55
+ model: "sonar-pro",
56
+ messages: [
57
+ {
58
+ role: "user",
59
+ content: "Explain machine learning in one sentence",
60
+ },
61
+ ],
62
+ });
63
+ console.log("āœ… Response:", differentResponse.choices[0]?.message?.content);
64
+
65
+ console.log("\nšŸŽ‰ All examples completed successfully!");
66
+ console.log("šŸ“Š All usage automatically tracked by middleware");
67
+
68
+ } catch (error) {
69
+ console.error("āŒ Error:", error);
70
+ }
71
+ }
72
+
73
+ openaiClientExample();
@@ -0,0 +1,40 @@
1
+ import { createPerplexityClient } from "@revenium/perplexity";
2
+
3
+ async function streamingExample() {
4
+ console.log("\nšŸ“Š Perplexity AI - Streaming Example");
5
+ console.log("=".repeat(50));
6
+
7
+ try {
8
+ const client = createPerplexityClient();
9
+ console.log("\n3ļøāƒ£ Streaming with metadata:");
10
+ const stream = await client.createStreamingChatCompletion({
11
+ model: "sonar-pro",
12
+ messages: [
13
+ {
14
+ role: "user",
15
+ content: "Write a creative story about AI",
16
+ },
17
+ ],
18
+ usageMetadata: {
19
+ traceId: "conv-streaming-456",
20
+ taskType: "creative-writing",
21
+ organizationId: "creative-studio",
22
+ agent: "story-generator",
23
+ },
24
+ });
25
+
26
+ console.log("šŸ“ Streaming response with metadata:");
27
+ for await (const chunk of stream) {
28
+ const content = chunk.choices[0]?.delta?.content;
29
+ if (content) {
30
+ process.stdout.write(content);
31
+ }
32
+ }
33
+
34
+ console.log("\n\nšŸŽ‰ Streaming completed!");
35
+ } catch (error) {
36
+ console.error("āŒ Error:", error);
37
+ }
38
+ }
39
+
40
+ streamingExample();
@@ -186,12 +186,50 @@ async function processPerplexityResponse(
186
186
  const endTime = new Date();
187
187
  const duration = calculateDurationMs(startTime, endTime);
188
188
 
189
- // Parse response body
190
- const responseData = await response.json();
189
+ // Check if this is a streaming response
190
+ const contentType = response.headers.get("content-type") || "";
191
+ const isStreamingResponse =
192
+ contentType.includes("text/plain") ||
193
+ contentType.includes("text/event-stream");
194
+
195
+ let responseData: any;
196
+ let tokenCounts = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
197
+ let stopReason = "END";
198
+
199
+ if (isStreamingResponse) {
200
+ // For streaming responses, we can't easily parse the full response
201
+ // We'll extract what we can from the stream or use defaults
202
+ const responseText = await response.text();
203
+
204
+ // Try to extract token information from the last complete JSON chunk
205
+ const jsonChunks = responseText
206
+ .split("\n")
207
+ .filter((line) => line.startsWith("data: ") && line !== "data: [DONE]")
208
+ .map((line) => line.substring(6)); // Remove 'data: ' prefix
209
+
210
+ if (jsonChunks.length > 0) {
211
+ try {
212
+ // Parse the last chunk to get usage information
213
+ const lastChunk = JSON.parse(jsonChunks[jsonChunks.length - 1]);
214
+ if (lastChunk.usage) {
215
+ tokenCounts = extractPerplexityTokenCounts(lastChunk);
216
+ }
217
+ } catch (e) {
218
+ // If we can't parse, use defaults
219
+ Logger.warning(
220
+ "Could not parse streaming response for token counts, using defaults"
221
+ );
222
+ }
223
+ }
224
+
225
+ responseData = { usage: tokenCounts };
226
+ } else {
227
+ // Parse response body for non-streaming responses
228
+ responseData = await response.json();
229
+ tokenCounts = extractPerplexityTokenCounts(responseData);
230
+ stopReason = extractStopReason(responseData);
231
+ }
191
232
 
192
- // Extract token counts and other data
193
- const tokenCounts = extractPerplexityTokenCounts(responseData);
194
- const stopReason = extractStopReason(responseData);
195
233
  const modelName = extractModelName(responseData, model);
196
234
 
197
235
  // Send metering data (only if API key is available)
@@ -1,22 +0,0 @@
1
- import { createPerplexityClient } from "@revenium/perplexity";
2
-
3
- async function basicExample() {
4
- const client = createPerplexityClient();
5
-
6
- const response = await client.createChatCompletion({
7
- model: "sonar-pro",
8
- messages: [
9
- {
10
- role: "user",
11
- content: "What is the meaning of life, the universe and everything?",
12
- },
13
- ],
14
- });
15
-
16
- console.log("āœ… Response received:");
17
- console.log(response.choices[0].message.content);
18
- console.log("\nšŸ“Š Token usage automatically tracked by middleware");
19
- console.log("šŸŽ‰ Basic client example successful!");
20
- }
21
-
22
- basicExample();