@revenium/perplexity 1.0.0
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/LICENSE +21 -0
- package/README.md +367 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/models/Exception/ApiResponseError.d.ts +6 -0
- package/dist/models/Exception/ApiResponseError.d.ts.map +1 -0
- package/dist/models/Exception/ApiResponseError.js +13 -0
- package/dist/models/Exception/ApiResponseError.js.map +1 -0
- package/dist/models/Exception/ConfigurationError.d.ts +4 -0
- package/dist/models/Exception/ConfigurationError.d.ts.map +1 -0
- package/dist/models/Exception/ConfigurationError.js +11 -0
- package/dist/models/Exception/ConfigurationError.js.map +1 -0
- package/dist/models/Exception/MeteringError.d.ts +5 -0
- package/dist/models/Exception/MeteringError.d.ts.map +1 -0
- package/dist/models/Exception/MeteringError.js +12 -0
- package/dist/models/Exception/MeteringError.js.map +1 -0
- package/dist/models/Exception/MiddlewareActivationError.d.ts +4 -0
- package/dist/models/Exception/MiddlewareActivationError.d.ts.map +1 -0
- package/dist/models/Exception/MiddlewareActivationError.js +11 -0
- package/dist/models/Exception/MiddlewareActivationError.js.map +1 -0
- package/dist/models/Exception/StreamTrackingError.d.ts +4 -0
- package/dist/models/Exception/StreamTrackingError.d.ts.map +1 -0
- package/dist/models/Exception/StreamTrackingError.js +11 -0
- package/dist/models/Exception/StreamTrackingError.js.map +1 -0
- package/dist/models/Exception/TokenCountingError.d.ts +4 -0
- package/dist/models/Exception/TokenCountingError.d.ts.map +1 -0
- package/dist/models/Exception/TokenCountingError.js +11 -0
- package/dist/models/Exception/TokenCountingError.js.map +1 -0
- package/dist/models/Exception/index.d.ts +7 -0
- package/dist/models/Exception/index.d.ts.map +1 -0
- package/dist/models/Exception/index.js +23 -0
- package/dist/models/Exception/index.js.map +1 -0
- package/dist/models/Logger.d.ts +10 -0
- package/dist/models/Logger.d.ts.map +1 -0
- package/dist/models/Logger.js +36 -0
- package/dist/models/Logger.js.map +1 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +19 -0
- package/dist/models/index.js.map +1 -0
- package/dist/perplexity-ai/client.d.ts +31 -0
- package/dist/perplexity-ai/client.d.ts.map +1 -0
- package/dist/perplexity-ai/client.js +75 -0
- package/dist/perplexity-ai/client.js.map +1 -0
- package/dist/perplexity-ai/index.d.ts +3 -0
- package/dist/perplexity-ai/index.d.ts.map +1 -0
- package/dist/perplexity-ai/index.js +19 -0
- package/dist/perplexity-ai/index.js.map +1 -0
- package/dist/perplexity-ai/middleware.d.ts +2 -0
- package/dist/perplexity-ai/middleware.d.ts.map +1 -0
- package/dist/perplexity-ai/middleware.js +163 -0
- package/dist/perplexity-ai/middleware.js.map +1 -0
- package/dist/types/context.d.ts +9 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +3 -0
- package/dist/types/context.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +28 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/metering.d.ts +28 -0
- package/dist/types/metering.d.ts.map +1 -0
- package/dist/types/metering.js +3 -0
- package/dist/types/metering.js.map +1 -0
- package/dist/types/modelInfo.d.ts +6 -0
- package/dist/types/modelInfo.d.ts.map +1 -0
- package/dist/types/modelInfo.js +3 -0
- package/dist/types/modelInfo.js.map +1 -0
- package/dist/types/operation.d.ts +5 -0
- package/dist/types/operation.d.ts.map +1 -0
- package/dist/types/operation.js +9 -0
- package/dist/types/operation.js.map +1 -0
- package/dist/types/perplexityConfig.d.ts +5 -0
- package/dist/types/perplexityConfig.d.ts.map +1 -0
- package/dist/types/perplexityConfig.js +3 -0
- package/dist/types/perplexityConfig.js.map +1 -0
- package/dist/types/provider.d.ts +4 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +8 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/reveniumConfig.d.ts +6 -0
- package/dist/types/reveniumConfig.d.ts.map +1 -0
- package/dist/types/reveniumConfig.js +3 -0
- package/dist/types/reveniumConfig.js.map +1 -0
- package/dist/types/streamTracker.d.ts +9 -0
- package/dist/types/streamTracker.d.ts.map +1 -0
- package/dist/types/streamTracker.js +3 -0
- package/dist/types/streamTracker.js.map +1 -0
- package/dist/types/subscriber.d.ts +9 -0
- package/dist/types/subscriber.d.ts.map +1 -0
- package/dist/types/subscriber.js +3 -0
- package/dist/types/subscriber.js.map +1 -0
- package/dist/types/tokenCounts.d.ts +6 -0
- package/dist/types/tokenCounts.d.ts.map +1 -0
- package/dist/types/tokenCounts.js +3 -0
- package/dist/types/tokenCounts.js.map +1 -0
- package/dist/types/usageData.d.ts +16 -0
- package/dist/types/usageData.d.ts.map +1 -0
- package/dist/types/usageData.js +3 -0
- package/dist/types/usageData.js.map +1 -0
- package/dist/types/usageMetadata.d.ts +14 -0
- package/dist/types/usageMetadata.d.ts.map +1 -0
- package/dist/types/usageMetadata.js +3 -0
- package/dist/types/usageMetadata.js.map +1 -0
- package/dist/utils/activeMiddleware.d.ts +2 -0
- package/dist/utils/activeMiddleware.d.ts.map +1 -0
- package/dist/utils/activeMiddleware.js +24 -0
- package/dist/utils/activeMiddleware.js.map +1 -0
- package/dist/utils/askConsole.d.ts +2 -0
- package/dist/utils/askConsole.d.ts.map +1 -0
- package/dist/utils/askConsole.js +20 -0
- package/dist/utils/askConsole.js.map +1 -0
- package/dist/utils/calculateDurationMs.d.ts +2 -0
- package/dist/utils/calculateDurationMs.d.ts.map +1 -0
- package/dist/utils/calculateDurationMs.js +7 -0
- package/dist/utils/calculateDurationMs.js.map +1 -0
- package/dist/utils/constants/constants.d.ts +9 -0
- package/dist/utils/constants/constants.d.ts.map +1 -0
- package/dist/utils/constants/constants.js +19 -0
- package/dist/utils/constants/constants.js.map +1 -0
- package/dist/utils/constants/messages.d.ts +19 -0
- package/dist/utils/constants/messages.d.ts.map +1 -0
- package/dist/utils/constants/messages.js +22 -0
- package/dist/utils/constants/messages.js.map +1 -0
- package/dist/utils/createMeteringRequest.d.ts +3 -0
- package/dist/utils/createMeteringRequest.d.ts.map +1 -0
- package/dist/utils/createMeteringRequest.js +10 -0
- package/dist/utils/createMeteringRequest.js.map +1 -0
- package/dist/utils/createPerplexityMetadata.d.ts +3 -0
- package/dist/utils/createPerplexityMetadata.d.ts.map +1 -0
- package/dist/utils/createPerplexityMetadata.js +12 -0
- package/dist/utils/createPerplexityMetadata.js.map +1 -0
- package/dist/utils/extractModelName.d.ts +2 -0
- package/dist/utils/extractModelName.d.ts.map +1 -0
- package/dist/utils/extractModelName.js +15 -0
- package/dist/utils/extractModelName.js.map +1 -0
- package/dist/utils/extractPerplexityTokenCounts.d.ts +3 -0
- package/dist/utils/extractPerplexityTokenCounts.d.ts.map +1 -0
- package/dist/utils/extractPerplexityTokenCounts.js +17 -0
- package/dist/utils/extractPerplexityTokenCounts.js.map +1 -0
- package/dist/utils/extractStopReason.d.ts +2 -0
- package/dist/utils/extractStopReason.d.ts.map +1 -0
- package/dist/utils/extractStopReason.js +14 -0
- package/dist/utils/extractStopReason.js.map +1 -0
- package/dist/utils/extractUsageMetadata.d.ts +3 -0
- package/dist/utils/extractUsageMetadata.d.ts.map +1 -0
- package/dist/utils/extractUsageMetadata.js +15 -0
- package/dist/utils/extractUsageMetadata.js.map +1 -0
- package/dist/utils/formatTimestamp.d.ts +2 -0
- package/dist/utils/formatTimestamp.d.ts.map +1 -0
- package/dist/utils/formatTimestamp.js +7 -0
- package/dist/utils/formatTimestamp.js.map +1 -0
- package/dist/utils/generateTransactionId.d.ts +2 -0
- package/dist/utils/generateTransactionId.d.ts.map +1 -0
- package/dist/utils/generateTransactionId.js +8 -0
- package/dist/utils/generateTransactionId.js.map +1 -0
- package/dist/utils/getEnv.d.ts +4 -0
- package/dist/utils/getEnv.d.ts.map +1 -0
- package/dist/utils/getEnv.js +16 -0
- package/dist/utils/getEnv.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +29 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/safeExtract.d.ts +2 -0
- package/dist/utils/safeExtract.d.ts.map +1 -0
- package/dist/utils/safeExtract.js +22 -0
- package/dist/utils/safeExtract.js.map +1 -0
- package/dist/utils/sendMeteringData.d.ts +3 -0
- package/dist/utils/sendMeteringData.d.ts.map +1 -0
- package/dist/utils/sendMeteringData.js +35 -0
- package/dist/utils/sendMeteringData.js.map +1 -0
- package/dist/utils/verifyLogVerbose.d.ts +2 -0
- package/dist/utils/verifyLogVerbose.d.ts.map +1 -0
- package/dist/utils/verifyLogVerbose.js +10 -0
- package/dist/utils/verifyLogVerbose.js.map +1 -0
- package/examples/README.md +316 -0
- package/examples/basic-client-example.ts +36 -0
- package/examples/metadata-example.ts +92 -0
- package/examples/multiple-models-example.ts +65 -0
- package/examples/openai-client-example.ts +76 -0
- package/examples/perplexity_basic_example.ts +24 -0
- package/examples/perplexity_middleware_example.ts +222 -0
- package/examples/run-all-examples.ts +118 -0
- package/examples/simple-test.ts +278 -0
- package/examples/streaming-example.ts +46 -0
- package/package.json +54 -0
- package/src/index.ts +38 -0
- package/src/models/Exception/ApiResponseError.ts +6 -0
- package/src/models/Exception/ConfigurationError.ts +6 -0
- package/src/models/Exception/MeteringError.ts +6 -0
- package/src/models/Exception/MiddlewareActivationError.ts +6 -0
- package/src/models/Exception/StreamTrackingError.ts +6 -0
- package/src/models/Exception/TokenCountingError.ts +6 -0
- package/src/models/Exception/index.ts +6 -0
- package/src/models/Logger.ts +38 -0
- package/src/models/index.ts +2 -0
- package/src/perplexity-ai/client.ts +97 -0
- package/src/perplexity-ai/index.ts +2 -0
- package/src/perplexity-ai/middleware.ts +259 -0
- package/src/types/context.ts +9 -0
- package/src/types/index.ts +11 -0
- package/src/types/metering.ts +28 -0
- package/src/types/modelInfo.ts +5 -0
- package/src/types/operation.ts +4 -0
- package/src/types/perplexityConfig.ts +4 -0
- package/src/types/provider.ts +3 -0
- package/src/types/reveniumConfig.ts +5 -0
- package/src/types/streamTracker.ts +9 -0
- package/src/types/subscriber.ts +8 -0
- package/src/types/tokenCounts.ts +5 -0
- package/src/types/usageData.ts +16 -0
- package/src/types/usageMetadata.ts +13 -0
- package/src/utils/activeMiddleware.ts +34 -0
- package/src/utils/askConsole.ts +15 -0
- package/src/utils/calculateDurationMs.ts +3 -0
- package/src/utils/constants/constants.ts +17 -0
- package/src/utils/constants/messages.ts +35 -0
- package/src/utils/createMeteringRequest.ts +16 -0
- package/src/utils/createPerplexityMetadata.ts +11 -0
- package/src/utils/extractModelName.ts +14 -0
- package/src/utils/extractPerplexityTokenCounts.ts +16 -0
- package/src/utils/extractStopReason.ts +13 -0
- package/src/utils/extractUsageMetadata.ts +15 -0
- package/src/utils/formatTimestamp.ts +3 -0
- package/src/utils/generateTransactionId.ts +5 -0
- package/src/utils/getEnv.ts +16 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/safeExtract.ts +18 -0
- package/src/utils/sendMeteringData.ts +46 -0
- package/src/utils/verifyLogVerbose.ts +7 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { config } from "dotenv";
|
|
2
|
+
import "../src/index"; // Import middleware to activate automatic tracking
|
|
3
|
+
|
|
4
|
+
config();
|
|
5
|
+
|
|
6
|
+
async function perplexityBasicExample(): Promise<boolean> {
|
|
7
|
+
console.log("\n🤖 Perplexity AI - Basic Example");
|
|
8
|
+
console.log("=".repeat(50));
|
|
9
|
+
|
|
10
|
+
const perplexityApiKey = process.env.PERPLEXITY_API_KEY;
|
|
11
|
+
const reveniumKey = process.env.REVENIUM_METERING_API_KEY;
|
|
12
|
+
|
|
13
|
+
if (!perplexityApiKey) {
|
|
14
|
+
console.log("❌ PERPLEXITY_API_KEY not found");
|
|
15
|
+
console.log(" Set: export PERPLEXITY_API_KEY=your-perplexity-api-key");
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!reveniumKey) {
|
|
20
|
+
console.log("⚠️ REVENIUM_METERING_API_KEY not found - metering will fail");
|
|
21
|
+
console.log(" Set: export REVENIUM_METERING_API_KEY=your-revenium-key");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(`✅ Perplexity API Key: ${perplexityApiKey.substring(0, 10)}...`);
|
|
25
|
+
if (reveniumKey) {
|
|
26
|
+
console.log(`✅ Revenium Key: ${reveniumKey.substring(0, 10)}...`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch("https://api.perplexity.ai/chat/completions", {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${perplexityApiKey}`,
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
model: "perplexity-online",
|
|
38
|
+
messages: [
|
|
39
|
+
{
|
|
40
|
+
role: "user",
|
|
41
|
+
content:
|
|
42
|
+
"What is the meaning of life, the universe and everything?",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const result = await response.json();
|
|
53
|
+
console.log(
|
|
54
|
+
`✅ Response: ${result.choices[0].message.content.substring(0, 100)}...`
|
|
55
|
+
);
|
|
56
|
+
console.log("✅ Response received successfully");
|
|
57
|
+
console.log("📊 Token usage will be tracked by the middleware");
|
|
58
|
+
console.log("🎉 Zero-config integration successful!");
|
|
59
|
+
console.log(" Your usage is automatically tracked in Revenium");
|
|
60
|
+
return true;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.log(`❌ Perplexity test failed: ${error}`);
|
|
63
|
+
console.error(error);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function perplexityEnhancedExample(): Promise<boolean> {
|
|
69
|
+
console.log("\n📊 Perplexity AI - Enhanced Tracking Example");
|
|
70
|
+
console.log("=".repeat(50));
|
|
71
|
+
|
|
72
|
+
const perplexityApiKey = process.env.PERPLEXITY_API_KEY;
|
|
73
|
+
if (!perplexityApiKey) {
|
|
74
|
+
console.log("❌ PERPLEXITY_API_KEY not found");
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const response = await fetch("https://api.perplexity.ai/chat/completions", {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${perplexityApiKey}`,
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify({
|
|
86
|
+
model: "perplexity-online",
|
|
87
|
+
messages: [
|
|
88
|
+
{
|
|
89
|
+
role: "user",
|
|
90
|
+
content: "Analyze this quarterly report for key insights",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
usageMetadata: {
|
|
94
|
+
traceId: "conv-28a7e9d4",
|
|
95
|
+
taskType: "document-analysis",
|
|
96
|
+
subscriberEmail: "user@example.com",
|
|
97
|
+
subscriberId: "user-12345",
|
|
98
|
+
organizationId: "acme-corp",
|
|
99
|
+
subscriptionId: "premium-plan",
|
|
100
|
+
productId: "business-intelligence",
|
|
101
|
+
agent: "report-analyzer-v2",
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const result = await response.json();
|
|
111
|
+
console.log(
|
|
112
|
+
`✅ Enhanced response: ${result.choices[0].message.content.substring(
|
|
113
|
+
0,
|
|
114
|
+
100
|
|
115
|
+
)}...`
|
|
116
|
+
);
|
|
117
|
+
console.log("🎯 Enhanced tracking with metadata successful!");
|
|
118
|
+
return true;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.log(`❌ Perplexity enhanced test failed: ${error}`);
|
|
121
|
+
console.error(error);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function perplexityStreamingExample(): Promise<boolean> {
|
|
127
|
+
console.log("\n🌊 Perplexity AI - Streaming Example");
|
|
128
|
+
console.log("=".repeat(50));
|
|
129
|
+
|
|
130
|
+
const perplexityApiKey = process.env.PERPLEXITY_API_KEY;
|
|
131
|
+
if (!perplexityApiKey) {
|
|
132
|
+
console.log("❌ PERPLEXITY_API_KEY not found");
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const response = await fetch("https://api.perplexity.ai/chat/completions", {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: {
|
|
140
|
+
Authorization: `Bearer ${perplexityApiKey}`,
|
|
141
|
+
"Content-Type": "application/json",
|
|
142
|
+
},
|
|
143
|
+
body: JSON.stringify({
|
|
144
|
+
model: "perplexity-online",
|
|
145
|
+
messages: [
|
|
146
|
+
{
|
|
147
|
+
role: "user",
|
|
148
|
+
content: "Write a creative story about AI",
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
stream: true,
|
|
152
|
+
usageMetadata: {
|
|
153
|
+
organizationId: "creative-studio",
|
|
154
|
+
taskType: "creative-writing",
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!response.body) {
|
|
164
|
+
throw new Error("No response body for streaming");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const reader = response.body.getReader();
|
|
168
|
+
const decoder = new TextDecoder();
|
|
169
|
+
let streamedContent = "";
|
|
170
|
+
|
|
171
|
+
while (true) {
|
|
172
|
+
const { done, value } = await reader.read();
|
|
173
|
+
if (done) break;
|
|
174
|
+
|
|
175
|
+
const chunk = decoder.decode(value);
|
|
176
|
+
const lines = chunk.split("\n");
|
|
177
|
+
|
|
178
|
+
for (const line of lines) {
|
|
179
|
+
if (line.startsWith("data: ")) {
|
|
180
|
+
const data = line.slice(6);
|
|
181
|
+
if (data === "[DONE]") break;
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const parsed = JSON.parse(data);
|
|
185
|
+
if (parsed.choices[0]?.delta?.content) {
|
|
186
|
+
const content = parsed.choices[0].delta.content;
|
|
187
|
+
streamedContent += content;
|
|
188
|
+
process.stdout.write(content);
|
|
189
|
+
}
|
|
190
|
+
} catch (e) {
|
|
191
|
+
// Ignore parsing errors for incomplete chunks
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
console.log("\n✅ Streaming completed successfully");
|
|
198
|
+
console.log("📊 Streaming usage will be tracked by the middleware");
|
|
199
|
+
return true;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.log(`❌ Perplexity streaming test failed: ${error}`);
|
|
202
|
+
console.error(error);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function perplexityDifferentModelExample(): Promise<boolean> {
|
|
208
|
+
console.log("\n🔧 Perplexity AI - Different Model Example");
|
|
209
|
+
console.log("=".repeat(50));
|
|
210
|
+
|
|
211
|
+
const perplexityApiKey = process.env.PERPLEXITY_API_KEY;
|
|
212
|
+
if (!perplexityApiKey) {
|
|
213
|
+
console.log("❌ PERPLEXITY_API_KEY not found");
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
const response = await fetch("https://api.perplexity.ai/chat/completions", {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: {
|
|
221
|
+
Authorization: `Bearer ${perplexityApiKey}`,
|
|
222
|
+
"Content-Type": "application/json",
|
|
223
|
+
},
|
|
224
|
+
body: JSON.stringify({
|
|
225
|
+
model: "llama-3.1-8b-online",
|
|
226
|
+
messages: [
|
|
227
|
+
{
|
|
228
|
+
role: "user",
|
|
229
|
+
content: "Explain quantum computing in simple terms",
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const result = await response.json();
|
|
240
|
+
console.log(
|
|
241
|
+
`✅ Llama response: ${result.choices[0].message.content.substring(
|
|
242
|
+
0,
|
|
243
|
+
100
|
|
244
|
+
)}...`
|
|
245
|
+
);
|
|
246
|
+
console.log("✅ Different model test successful!");
|
|
247
|
+
return true;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.log(`❌ Perplexity different model test failed: ${error}`);
|
|
250
|
+
console.error(error);
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function main(): Promise<void> {
|
|
256
|
+
console.log("🚀 Starting Revenium Perplexity AI Middleware Tests");
|
|
257
|
+
console.log("=".repeat(60));
|
|
258
|
+
|
|
259
|
+
let successCount = 0;
|
|
260
|
+
const totalTests: number = 4;
|
|
261
|
+
|
|
262
|
+
// Run Perplexity AI tests
|
|
263
|
+
if (await perplexityBasicExample()) successCount++;
|
|
264
|
+
if (await perplexityEnhancedExample()) successCount++;
|
|
265
|
+
if (await perplexityStreamingExample()) successCount++;
|
|
266
|
+
if (await perplexityDifferentModelExample()) successCount++;
|
|
267
|
+
|
|
268
|
+
console.log("\n" + "=".repeat(60));
|
|
269
|
+
console.log(`📊 Test Results: ${successCount}/${totalTests} tests passed`);
|
|
270
|
+
|
|
271
|
+
if (successCount === totalTests) {
|
|
272
|
+
console.log("🎉 All tests passed! Middleware is working correctly.");
|
|
273
|
+
} else {
|
|
274
|
+
console.log("⚠️ Some tests failed. Check the logs above for details.");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { config } from "dotenv";
|
|
2
|
+
import { createPerplexityClient } from "../src/perplexity-ai";
|
|
3
|
+
|
|
4
|
+
config();
|
|
5
|
+
|
|
6
|
+
async function streamingExample() {
|
|
7
|
+
console.log("\n🌊 Perplexity AI - Streaming Example");
|
|
8
|
+
console.log("=".repeat(50));
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
// Create client instance
|
|
12
|
+
const client = createPerplexityClient();
|
|
13
|
+
|
|
14
|
+
// Create streaming chat completion
|
|
15
|
+
const stream = await client.createStreamingChatCompletion({
|
|
16
|
+
model: "sonar-pro",
|
|
17
|
+
messages: [
|
|
18
|
+
{
|
|
19
|
+
role: "user",
|
|
20
|
+
content: "Write a creative story about AI and the future of technology",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log("📝 Streaming response:");
|
|
26
|
+
console.log("-".repeat(30));
|
|
27
|
+
|
|
28
|
+
let fullContent = "";
|
|
29
|
+
for await (const chunk of stream) {
|
|
30
|
+
const content = chunk.choices[0]?.delta?.content;
|
|
31
|
+
if (content) {
|
|
32
|
+
fullContent += content;
|
|
33
|
+
process.stdout.write(content);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log("\n\n✅ Streaming completed successfully");
|
|
38
|
+
console.log("📊 Streaming usage automatically tracked by middleware");
|
|
39
|
+
console.log("🎉 Streaming example successful!");
|
|
40
|
+
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error("❌ Error:", error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
streamingExample().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@revenium/perplexity",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "NodeJS middleware for perplexity's AI API",
|
|
5
|
+
"homepage": "https://github.com/revenium/revenium-middleware-perplexity-node#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/revenium/revenium-middleware-perplexity-node/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/revenium/revenium-middleware-perplexity-node.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"author": "",
|
|
15
|
+
"type": "commonjs",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"clean": "rimraf dist",
|
|
21
|
+
"prebuild": "npm run clean",
|
|
22
|
+
"simple-test": "npx ts-node examples/simple-test.ts",
|
|
23
|
+
"perplexity-basic-example": "npx ts-node examples/perplexity_basic_example.ts",
|
|
24
|
+
"perplexity-middleware-example": "npx ts-node examples/perplexity_middleware_example.ts",
|
|
25
|
+
"basic-client-example": "npx ts-node examples/basic-client-example.ts",
|
|
26
|
+
"streaming-example": "npx ts-node examples/streaming-example.ts",
|
|
27
|
+
"multiple-models-example": "npx ts-node examples/multiple-models-example.ts",
|
|
28
|
+
"openai-client-example": "npx ts-node examples/openai-client-example.ts",
|
|
29
|
+
"metadata-example": "npx ts-node examples/metadata-example.ts",
|
|
30
|
+
"run-all-examples": "npx ts-node examples/run-all-examples.ts"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"revenium",
|
|
34
|
+
"middleware",
|
|
35
|
+
"perplexity",
|
|
36
|
+
"ai",
|
|
37
|
+
"chat",
|
|
38
|
+
"completion",
|
|
39
|
+
"metering",
|
|
40
|
+
"monitoring",
|
|
41
|
+
"typescript"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"axios": "^1.11.0",
|
|
45
|
+
"dotenv": "^17.2.1",
|
|
46
|
+
"openai": "^5.15.0",
|
|
47
|
+
"uuid": "^11.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^24.3.0",
|
|
51
|
+
"rimraf": "^6.0.1",
|
|
52
|
+
"typescript": "^5.9.2"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { config } from "dotenv";
|
|
2
|
+
import { Logger } from "./models";
|
|
3
|
+
import { activeMiddleware } from "./utils/activeMiddleware";
|
|
4
|
+
import { verifyLogVerbose } from "./utils/verifyLogVerbose";
|
|
5
|
+
|
|
6
|
+
// Import the Perplexity middleware to activate it
|
|
7
|
+
import "./perplexity-ai/middleware";
|
|
8
|
+
|
|
9
|
+
config();
|
|
10
|
+
|
|
11
|
+
const verboseStartup:boolean =
|
|
12
|
+
process.env.REVENIUM_VERBOSE_STARTUP?.toLowerCase() === "true";
|
|
13
|
+
|
|
14
|
+
verifyLogVerbose(
|
|
15
|
+
verboseStartup,
|
|
16
|
+
"Revenium Perplexity middleware initialization starting"
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
// Activate middleware for Perplexity AI
|
|
20
|
+
let activeSDKs: string[] = [];
|
|
21
|
+
activeMiddleware(verboseStartup, activeSDKs, "perplexity-ai");
|
|
22
|
+
|
|
23
|
+
// Export all utilities, types, and models
|
|
24
|
+
export * from "./utils";
|
|
25
|
+
export * from "./types";
|
|
26
|
+
export * from "./models";
|
|
27
|
+
|
|
28
|
+
// Export Perplexity client and middleware
|
|
29
|
+
export * from "./perplexity-ai";
|
|
30
|
+
|
|
31
|
+
// Log the active SDKs
|
|
32
|
+
Logger.info(
|
|
33
|
+
"Revenium Perplexity middleware activated for: %s",
|
|
34
|
+
activeSDKs.length > 0 ? activeSDKs.join(", ") : "none"
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const version:string = "0.1.0";
|
|
38
|
+
export const activeSDKList:string[] = activeSDKs;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LOG_LEVELS } from "../utils/constants/constants";
|
|
2
|
+
|
|
3
|
+
export class Logger {
|
|
4
|
+
private static logLevel: string = process.env.REVENIUM_LOG_LEVEL || "INFO";
|
|
5
|
+
|
|
6
|
+
static debug(message: string, data?: any): void {
|
|
7
|
+
if (this.shouldLog(LOG_LEVELS[0])) {
|
|
8
|
+
console.log(`${LOG_LEVELS[0]} ${message}`, data || "");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static info(message: string, data?: any): void {
|
|
13
|
+
if (this.shouldLog(LOG_LEVELS[1])) {
|
|
14
|
+
console.log(`${LOG_LEVELS[1]} ${message}`, data || "");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static warning(message: string, data?: any): void {
|
|
19
|
+
if (this.shouldLog(LOG_LEVELS[2])) {
|
|
20
|
+
console.warn(`${LOG_LEVELS[2]} ${message}`, data || "");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static error(message: string, data?: any): void {
|
|
25
|
+
if (this.shouldLog(LOG_LEVELS[3])) {
|
|
26
|
+
console.error(`${LOG_LEVELS[3]} ${message}`, data || "");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private static shouldLog(level: string): boolean {
|
|
31
|
+
const levels = LOG_LEVELS;
|
|
32
|
+
const currentLevel = levels.indexOf(this.logLevel.toUpperCase());
|
|
33
|
+
const messageLevel = levels.indexOf(level);
|
|
34
|
+
return messageLevel >= currentLevel;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const logger = Logger;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { OpenAI } from "openai";
|
|
2
|
+
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
|
|
3
|
+
import { Logger } from "../models";
|
|
4
|
+
import {
|
|
5
|
+
PERPLEXITY_CHAT_COMPLETION_FAILED_MESSAGE,
|
|
6
|
+
PERPLEXITY_CLIENT_INITIALIZED_MESSAGE,
|
|
7
|
+
PERPLEXITY_GET_MODELS_FAILED_MESSAGE,
|
|
8
|
+
PERPLEXITY_REQUIRED_API_KEY_MESSAGE,
|
|
9
|
+
PERPLEXITY_STREAMING_CHAT_COMPLETION_FAILED_MESSAGE,
|
|
10
|
+
} from "../utils/constants/messages";
|
|
11
|
+
|
|
12
|
+
// Import middleware to activate automatic tracking
|
|
13
|
+
import "./middleware";
|
|
14
|
+
import { CURRENT_PERPLEXITY_BASE_URL } from "../utils/constants/constants";
|
|
15
|
+
|
|
16
|
+
//Perplexity AI Client with middleware integration
|
|
17
|
+
export class PerplexityClient {
|
|
18
|
+
private client: OpenAI;
|
|
19
|
+
|
|
20
|
+
constructor(apiKey?: string) {
|
|
21
|
+
const perplexityApiKey = apiKey || process.env.PERPLEXITY_API_KEY;
|
|
22
|
+
|
|
23
|
+
if (!perplexityApiKey) {
|
|
24
|
+
throw new Error(PERPLEXITY_REQUIRED_API_KEY_MESSAGE);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.client = new OpenAI({
|
|
28
|
+
apiKey: perplexityApiKey,
|
|
29
|
+
baseURL: CURRENT_PERPLEXITY_BASE_URL,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
Logger.info(PERPLEXITY_CLIENT_INITIALIZED_MESSAGE);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//Create a chat completion
|
|
36
|
+
async createChatCompletion(params: {
|
|
37
|
+
model: string;
|
|
38
|
+
messages: ChatCompletionMessageParam[];
|
|
39
|
+
stream?: false;
|
|
40
|
+
usageMetadata?: any;
|
|
41
|
+
[key: string]: any;
|
|
42
|
+
}) {
|
|
43
|
+
try {
|
|
44
|
+
// Remove usageMetadata from params as it's not part of OpenAI API
|
|
45
|
+
const { usageMetadata, ...openaiParams } = params;
|
|
46
|
+
const response = await this.client.chat.completions.create(openaiParams);
|
|
47
|
+
return response;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
Logger.error(PERPLEXITY_CHAT_COMPLETION_FAILED_MESSAGE, { error });
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//Create a streaming chat completion
|
|
55
|
+
async createStreamingChatCompletion(params: {
|
|
56
|
+
model: string;
|
|
57
|
+
messages: ChatCompletionMessageParam[];
|
|
58
|
+
usageMetadata?: any;
|
|
59
|
+
[key: string]: any;
|
|
60
|
+
}) {
|
|
61
|
+
try {
|
|
62
|
+
// Remove usageMetadata from params as it's not part of OpenAI API
|
|
63
|
+
const { usageMetadata, ...openaiParams } = params;
|
|
64
|
+
const stream = await this.client.chat.completions.create({
|
|
65
|
+
...openaiParams,
|
|
66
|
+
stream: true,
|
|
67
|
+
});
|
|
68
|
+
return stream;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
Logger.error(PERPLEXITY_STREAMING_CHAT_COMPLETION_FAILED_MESSAGE, {
|
|
71
|
+
error,
|
|
72
|
+
});
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//Get available models
|
|
78
|
+
async getModels() {
|
|
79
|
+
try {
|
|
80
|
+
const models = await this.client.models.list();
|
|
81
|
+
return models;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
Logger.error(PERPLEXITY_GET_MODELS_FAILED_MESSAGE, { error });
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Create a Perplexity client instance
|
|
91
|
+
*/
|
|
92
|
+
export function createPerplexityClient(apiKey?: string): PerplexityClient {
|
|
93
|
+
return new PerplexityClient(apiKey);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Export the OpenAI client for advanced usage
|
|
97
|
+
export { OpenAI };
|