@revenium/perplexity 1.0.25 → 2.0.1

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/README.md +443 -568
  2. package/dist/cjs/core/config/perplexity-config.js +45 -0
  3. package/dist/cjs/core/config/perplexity-config.js.map +1 -0
  4. package/dist/cjs/core/config/revenium-config.js +80 -0
  5. package/dist/cjs/core/config/revenium-config.js.map +1 -0
  6. package/dist/cjs/core/tracking/metering.js +131 -0
  7. package/dist/cjs/core/tracking/metering.js.map +1 -0
  8. package/dist/cjs/core/wrapper/perplexity-client.js +177 -0
  9. package/dist/cjs/core/wrapper/perplexity-client.js.map +1 -0
  10. package/dist/cjs/index.js +64 -0
  11. package/dist/cjs/index.js.map +1 -0
  12. package/dist/cjs/types/index.js +21 -0
  13. package/dist/cjs/types/index.js.map +1 -0
  14. package/dist/cjs/utils/logger.js +23 -0
  15. package/dist/cjs/utils/logger.js.map +1 -0
  16. package/dist/esm/core/config/perplexity-config.js +40 -0
  17. package/dist/esm/core/config/perplexity-config.js.map +1 -0
  18. package/dist/esm/core/config/revenium-config.js +72 -0
  19. package/dist/esm/core/config/revenium-config.js.map +1 -0
  20. package/dist/esm/core/tracking/metering.js +126 -0
  21. package/dist/esm/core/tracking/metering.js.map +1 -0
  22. package/dist/esm/core/wrapper/perplexity-client.js +170 -0
  23. package/dist/esm/core/wrapper/perplexity-client.js.map +1 -0
  24. package/dist/esm/index.js +44 -0
  25. package/dist/esm/index.js.map +1 -0
  26. package/dist/esm/types/index.js +18 -0
  27. package/dist/esm/types/index.js.map +1 -0
  28. package/dist/esm/utils/logger.js +20 -0
  29. package/dist/esm/utils/logger.js.map +1 -0
  30. package/dist/types/core/config/perplexity-config.d.ts +24 -0
  31. package/dist/types/core/config/perplexity-config.d.ts.map +1 -0
  32. package/dist/types/core/config/revenium-config.d.ts +37 -0
  33. package/dist/types/core/config/revenium-config.d.ts.map +1 -0
  34. package/dist/types/core/tracking/metering.d.ts +31 -0
  35. package/dist/types/core/tracking/metering.d.ts.map +1 -0
  36. package/dist/types/core/wrapper/perplexity-client.d.ts +32 -0
  37. package/dist/types/core/wrapper/perplexity-client.d.ts.map +1 -0
  38. package/dist/types/index.d.ts +34 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/types/index.d.ts +159 -0
  41. package/dist/types/types/index.d.ts.map +1 -0
  42. package/dist/types/utils/logger.d.ts +10 -0
  43. package/dist/types/utils/logger.d.ts.map +1 -0
  44. package/package.json +36 -31
  45. package/.env.example +0 -3
  46. package/dist/interfaces/meteringResponse.d.ts +0 -28
  47. package/dist/interfaces/meteringResponse.js +0 -2
  48. package/dist/models/Metering.js +0 -83
  49. package/dist/v1/perplexityV1.service.js +0 -166
  50. package/dist/v2/perplexityV2.service.js +0 -178
  51. package/examples/v1/basic.ts +0 -50
  52. package/examples/v1/chat.ts +0 -40
  53. package/examples/v1/metadata.ts +0 -49
  54. package/examples/v1/streaming.ts +0 -44
  55. package/examples/v2/basic.ts +0 -49
  56. package/examples/v2/chat.ts +0 -60
  57. package/examples/v2/metadata.ts +0 -71
  58. package/examples/v2/streaming.ts +0 -61
  59. package/playground/v1/basic.js +0 -50
  60. package/playground/v1/chat.js +0 -46
  61. package/playground/v1/metadata.js +0 -50
  62. package/playground/v1/streaming.js +0 -44
  63. package/playground/v2/basic.js +0 -49
  64. package/playground/v2/chat.js +0 -72
  65. package/playground/v2/metadata.js +0 -76
  66. package/playground/v2/streaming.js +0 -67
  67. package/src/index.ts +0 -17
  68. package/src/interfaces/chatCompletionRequest.ts +0 -15
  69. package/src/interfaces/credential.ts +0 -4
  70. package/src/interfaces/meteringRequest.ts +0 -14
  71. package/src/interfaces/meteringResponse.ts +0 -29
  72. package/src/interfaces/operation.ts +0 -4
  73. package/src/interfaces/perplexityResponse.ts +0 -63
  74. package/src/interfaces/perplexityStreaming.ts +0 -56
  75. package/src/interfaces/subscriber.ts +0 -8
  76. package/src/interfaces/tokenCounts.ts +0 -7
  77. package/src/interfaces/usageMetadata.ts +0 -27
  78. package/src/models/Logger.ts +0 -38
  79. package/src/models/Metering.ts +0 -121
  80. package/src/utils/calculateDurationMs.ts +0 -3
  81. package/src/utils/constants/constants.ts +0 -10
  82. package/src/utils/constants/logLevels.ts +0 -1
  83. package/src/utils/constants/messages.ts +0 -11
  84. package/src/utils/constants/models.ts +0 -20
  85. package/src/utils/constants/perplexityModels.ts +0 -71
  86. package/src/utils/extractTokenCount.ts +0 -26
  87. package/src/utils/formatTimestamp.ts +0 -3
  88. package/src/utils/generateTransactionId.ts +0 -5
  89. package/src/utils/index.ts +0 -39
  90. package/src/utils/loadEnv.ts +0 -8
  91. package/src/utils/safeExtract.ts +0 -67
  92. package/src/v1/perplexityV1.controller.ts +0 -164
  93. package/src/v1/perplexityV1.service.ts +0 -230
  94. package/src/v2/perplexityV2.controller.ts +0 -219
  95. package/src/v2/perplexityV2.service.ts +0 -260
  96. package/tsconfig.json +0 -15
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Revenium Middleware for Perplexity
3
+ *
4
+ * A lightweight middleware that adds Revenium metering to Perplexity API calls.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * initializeReveniumFromEnv,
10
+ * initializePerplexityFromEnv,
11
+ * createChatCompletion,
12
+ * } from '@revenium/perplexity';
13
+ *
14
+ * // Initialize configurations
15
+ * initializeReveniumFromEnv();
16
+ * initializePerplexityFromEnv();
17
+ *
18
+ * // Create a chat completion
19
+ * const result = await createChatCompletion({
20
+ * messages: [{ role: 'user', content: 'Hello!' }],
21
+ * model: 'sonar-pro',
22
+ * });
23
+ *
24
+ * console.log(result.content);
25
+ * ```
26
+ */
27
+ export { initializeReveniumFromEnv, initializeRevenium, getReveniumConfig, isReveniumEnabled, disableRevenium, enableRevenium, type ReveniumConfig, } from "./core/config/revenium-config";
28
+ export { initializePerplexityFromEnv, initializePerplexity, getPerplexityConfig, type PerplexityConfig, } from "./core/config/perplexity-config";
29
+ export { createChatCompletion, createStreamingChatCompletion, } from "./core/wrapper/perplexity-client";
30
+ export { generateTransactionId, buildMeteringData, sendMeteringData, } from "./core/tracking/metering";
31
+ export type { PerplexityMessage, PerplexityChatRequest, PerplexityUsage, PerplexityChoice, PerplexityResponse, PerplexityStreamChunk, UsageMetadata, MeteringData, ChatCompletionResult, StreamingResult, PerplexityModel, } from "./types";
32
+ export { PERPLEXITY_MODELS, DEFAULT_MODEL } from "./types";
33
+ export { logger } from "./utils/logger";
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AASH,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,KAAK,cAAc,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,gBAAgB,GACtB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,EACL,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAMlC,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM3D,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * TypeScript Type Definitions for Perplexity Middleware
3
+ */
4
+ export interface PerplexityMessage {
5
+ role: "system" | "user" | "assistant";
6
+ content: string;
7
+ }
8
+ export interface PerplexityChatRequest {
9
+ model: string;
10
+ messages: PerplexityMessage[];
11
+ max_tokens?: number;
12
+ temperature?: number;
13
+ top_p?: number;
14
+ stream?: boolean;
15
+ presence_penalty?: number;
16
+ frequency_penalty?: number;
17
+ }
18
+ export interface PerplexityUsage {
19
+ prompt_tokens: number;
20
+ completion_tokens: number;
21
+ total_tokens: number;
22
+ }
23
+ export interface PerplexityChoice {
24
+ index: number;
25
+ message?: {
26
+ role: string;
27
+ content: string;
28
+ };
29
+ delta?: {
30
+ role?: string;
31
+ content?: string;
32
+ };
33
+ finish_reason: string | null;
34
+ }
35
+ export interface PerplexityResponse {
36
+ id: string;
37
+ object: string;
38
+ created: number;
39
+ model: string;
40
+ choices: PerplexityChoice[];
41
+ usage?: PerplexityUsage;
42
+ }
43
+ export interface PerplexityStreamChunk {
44
+ id: string;
45
+ object: string;
46
+ created: number;
47
+ model: string;
48
+ choices: PerplexityChoice[];
49
+ }
50
+ export interface UsageMetadata {
51
+ subscriber?: {
52
+ id: string;
53
+ email?: string;
54
+ credential?: {
55
+ name: string;
56
+ value: string;
57
+ };
58
+ };
59
+ organizationId?: string;
60
+ productId?: string;
61
+ transactionId?: string;
62
+ traceId?: string;
63
+ inputTokenCount?: number;
64
+ outputTokenCount?: number;
65
+ totalTokenCount?: number;
66
+ reasoningTokenCount?: number;
67
+ cacheCreationTokenCount?: number;
68
+ cacheReadTokenCount?: number;
69
+ requestTime?: string;
70
+ responseTime?: string;
71
+ completionStartTime?: string;
72
+ timeToFirstToken?: number;
73
+ operationType?: string;
74
+ taskType?: string;
75
+ agent?: string;
76
+ stopReason?: string;
77
+ costType?: string;
78
+ subscriberId?: string;
79
+ subscriberEmail?: string;
80
+ subscriberCredentialName?: string;
81
+ subscriberCredential?: string;
82
+ }
83
+ /**
84
+ * Metering data sent to Revenium
85
+ * Field order matches the expected API format
86
+ */
87
+ export interface MeteringData {
88
+ stopReason: string;
89
+ costType: string;
90
+ isStreamed: boolean;
91
+ taskType: string;
92
+ agent: string;
93
+ operationType: string;
94
+ inputTokenCount: number;
95
+ outputTokenCount: number;
96
+ reasoningTokenCount: number;
97
+ cacheCreationTokenCount: number;
98
+ cacheReadTokenCount: number;
99
+ totalTokenCount: number;
100
+ organizationId: string;
101
+ productId: string;
102
+ subscriber: {
103
+ id: string;
104
+ email: string;
105
+ credential: {
106
+ name: string;
107
+ value: string;
108
+ };
109
+ };
110
+ model: string;
111
+ transactionId: string;
112
+ responseTime: string;
113
+ requestDuration: number;
114
+ provider: string;
115
+ requestTime: string;
116
+ completionStartTime: string;
117
+ timeToFirstToken: number;
118
+ middleware_source: string;
119
+ traceId?: string;
120
+ }
121
+ export interface ChatCompletionResult {
122
+ content: string;
123
+ role: string;
124
+ finishReason: string | null;
125
+ usage: {
126
+ promptTokens: number;
127
+ completionTokens: number;
128
+ totalTokens: number;
129
+ };
130
+ model: string;
131
+ transactionId: string;
132
+ rawResponse: PerplexityResponse;
133
+ }
134
+ export interface StreamingResult {
135
+ stream: AsyncGenerator<PerplexityStreamChunk>;
136
+ transactionId: string;
137
+ model: string;
138
+ }
139
+ export interface ReveniumConfig {
140
+ meteringApiKey: string;
141
+ meteringBaseUrl: string;
142
+ teamId?: string;
143
+ enabled: boolean;
144
+ }
145
+ export interface PerplexityConfig {
146
+ apiKey: string;
147
+ baseUrl: string;
148
+ }
149
+ export declare const PERPLEXITY_MODELS: {
150
+ readonly SONAR: "sonar";
151
+ readonly SONAR_PRO: "sonar-pro";
152
+ readonly SONAR_REASONING: "sonar-reasoning";
153
+ readonly LLAMA_3_1_SONAR_SMALL_128K_CHAT: "llama-3.1-sonar-small-128k-chat";
154
+ readonly LLAMA_3_1_SONAR_LARGE_128K_CHAT: "llama-3.1-sonar-large-128k-chat";
155
+ readonly LLAMA_3_1_SONAR_HUGE_128K_CHAT: "llama-3.1-sonar-huge-128k-chat";
156
+ };
157
+ export type PerplexityModel = (typeof PERPLEXITY_MODELS)[keyof typeof PERPLEXITY_MODELS];
158
+ export declare const DEFAULT_MODEL: PerplexityModel;
159
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Simple logger utility
3
+ */
4
+ export declare const logger: {
5
+ info: (...args: any[]) => void;
6
+ warn: (...args: any[]) => void;
7
+ error: (...args: any[]) => void;
8
+ debug: (...args: any[]) => void;
9
+ };
10
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,MAAM;oBACD,GAAG,EAAE;oBAGL,GAAG,EAAE;qBAGJ,GAAG,EAAE;qBAGL,GAAG,EAAE;CAKvB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@revenium/perplexity",
3
- "version": "1.0.25",
4
- "description": "NodeJS middleware for perplexity's AI API",
3
+ "version": "2.0.1",
4
+ "description": "NodeJS middleware for Perplexity AI API with Revenium metering",
5
5
  "homepage": "https://github.com/revenium/revenium-middleware-perplexity-node#readme",
6
6
  "bugs": {
7
7
  "url": "https://github.com/revenium/revenium-middleware-perplexity-node/issues"
@@ -10,35 +10,37 @@
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/revenium/revenium-middleware-perplexity-node.git"
12
12
  },
13
- "main": "dist/index.js",
14
- "types": "dist/index.d.ts",
13
+ "main": "dist/cjs/index.js",
14
+ "module": "dist/esm/index.js",
15
+ "types": "dist/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./dist/esm/index.js",
19
+ "require": "./dist/cjs/index.js",
20
+ "types": "./dist/types/index.d.ts"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist/**/*",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
15
28
  "scripts": {
16
- "build": "tsc -b",
17
- "p-v1-basic": "node playground/v1/basic.js",
18
- "p-v1-streaming": "node playground/v1/streaming.js",
19
- "p-v1-chat": "node playground/v1/chat.js",
20
- "p-v1-metadata": "node playground/v1/metadata.js",
21
- "p-v2-basic": "node playground/v2/basic.js",
22
- "p-v2-streaming": "node playground/v2/streaming.js",
23
- "p-v2-chat": "node playground/v2/chat.js",
24
- "p-v2-metadata": "node playground/v2/metadata.js",
25
- "e-v1-basic": "npx ts-node examples/v1/basic.ts",
26
- "e-v1-streaming": "npx ts-node examples/v1/streaming.ts",
27
- "e-v1-chat": "npx ts-node examples/v1/chat.ts",
28
- "e-v1-metadata": "npx ts-node examples/v1/metadata.ts",
29
- "e-v2-basic": "npx ts-node examples/v2/basic.ts",
30
- "e-v2-streaming": "npx ts-node examples/v2/streaming.ts",
31
- "e-v2-chat": "npx ts-node examples/v2/chat.ts",
32
- "e-v2-metadata": "npx ts-node examples/v2/metadata.ts",
33
- "examples:v1": "npm run e-v1-basic",
34
- "examples:v2": "npm run e-v2-basic",
35
- "examples:all": "npm run examples:v1 && echo '\n=== V2 EXAMPLES ===\n' && npm run examples:v2",
36
- "playground:v1": "npm run p-v1-basic",
37
- "playground:v2": "npm run p-v2-basic",
38
- "playground:all": "npm run playground:v1 && echo '\n=== V2 PLAYGROUND ===\n' && npm run playground:v2",
39
- "test:v1": "npm run e-v1-basic && npm run e-v1-chat && npm run e-v1-streaming && npm run e-v1-metadata",
40
- "test:v2": "npm run e-v2-basic && npm run e-v2-chat && npm run e-v2-streaming && npm run e-v2-metadata",
41
- "test:all": "npm run test:v1 && echo '\n=== TESTING V2 ===\n' && npm run test:v2"
29
+ "clean": "if exist dist rmdir /s /q dist",
30
+ "build:esm": "tsc -p tsconfig.esm.json",
31
+ "build:cjs": "tsc -p tsconfig.cjs.json",
32
+ "build:types": "tsc -p tsconfig.types.json",
33
+ "build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types",
34
+ "prepublishOnly": "npm run build",
35
+ "example:basic": "tsx examples/basic.ts",
36
+ "example:streaming": "tsx examples/streaming.ts",
37
+ "example:chat": "tsx examples/chat.ts",
38
+ "example:metadata": "tsx examples/metadata.ts",
39
+ "playground:basic": "node playground/basic.js",
40
+ "playground:streaming": "node playground/streaming.js",
41
+ "playground:chat": "node playground/chat.js",
42
+ "playground:metadata": "node playground/metadata.js",
43
+ "test": "npm run example:basic && npm run example:streaming && npm run example:chat && npm run example:metadata"
42
44
  },
43
45
  "keywords": [
44
46
  "revenium",
@@ -57,8 +59,11 @@
57
59
  "dependencies": {
58
60
  "dotenv": "^17.2.2",
59
61
  "openai": "^5.23.1",
60
- "ts-node": "^10.9.2",
62
+ "tsx": "^4.19.2",
61
63
  "typescript": "^5.9.2",
62
64
  "uuid": "^13.0.0"
65
+ },
66
+ "devDependencies": {
67
+ "@types/node": "^24.7.1"
63
68
  }
64
69
  }
package/.env.example DELETED
@@ -1,3 +0,0 @@
1
- PERPLEXITY_API_KEY="your_perplexity_api_key_here"
2
- REVENIUM_METERING_API_KEY="your_revenium_api_key_here"
3
- REVENIUM_METERING_BASE_URL="https://api.revenium.io/meter"
@@ -1,28 +0,0 @@
1
- import { ISubscriber } from "./subscriber";
2
- export interface IMeteringResponse {
3
- stopReason: string;
4
- costType: string;
5
- isStreamed: boolean;
6
- taskType: string;
7
- agent: string;
8
- operationType: string;
9
- inputTokenCount: number;
10
- outputTokenCount: number;
11
- reasoningTokenCount: number;
12
- cacheCreationTokenCount: number;
13
- cacheReadTokenCount: number;
14
- totalTokenCount: number;
15
- organizationId: string;
16
- productId: string;
17
- subscriber: ISubscriber;
18
- model: string;
19
- transactionId: string;
20
- responseTime: string;
21
- requestDuration: number;
22
- provider: string;
23
- requestTime: string;
24
- completionStartTime: string;
25
- timeToFirstToken: number;
26
- middleware_source: string;
27
- traceId?: string;
28
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,83 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Metering = void 0;
4
- const utils_1 = require("../utils");
5
- const calculateDurationMs_1 = require("../utils/calculateDurationMs");
6
- const formatTimestamp_1 = require("../utils/formatTimestamp");
7
- const generateTransactionId_1 = require("../utils/generateTransactionId");
8
- const Logger_1 = require("./Logger");
9
- class Metering {
10
- constructor(clientApiKey, clientEndpoint) {
11
- this.endpoint = "";
12
- this.apiKey = "";
13
- this.sendMeteringData = async (metering) => {
14
- try {
15
- // Log the metering data being sent for debugging
16
- Logger_1.logger.info("Sending metering data to Revenium:", JSON.stringify(metering, null, 2));
17
- const response = await fetch(`${this.endpoint}/v2/ai/completions`, {
18
- method: "POST",
19
- headers: {
20
- "Content-Type": "application/json",
21
- "x-api-key": this.apiKey,
22
- accept: "application/json",
23
- },
24
- body: JSON.stringify(metering),
25
- });
26
- if (!response.ok) {
27
- const errorData = await (response === null || response === void 0 ? void 0 : response.text());
28
- Logger_1.logger.error(`Metering API request failed with status ${response.status} - ${errorData}`);
29
- return;
30
- }
31
- Logger_1.logger.info(`Metering data sent successfully to Revenium`);
32
- }
33
- catch (error) {
34
- Logger_1.logger.error(`Error to sent metering data ${error}`);
35
- }
36
- };
37
- this.apiKey = clientApiKey;
38
- this.endpoint = clientEndpoint;
39
- }
40
- createMetering(metering, isStreamed) {
41
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
42
- const usageMetadata = metering.usageMetadata;
43
- const agent = "perplexity";
44
- return {
45
- stopReason: (_a = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.stopReason) !== null && _a !== void 0 ? _a : metering.stopReason,
46
- costType: utils_1.COST_TYPE,
47
- isStreamed,
48
- taskType: (_b = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.taskType) !== null && _b !== void 0 ? _b : utils_1.COST_TYPE,
49
- agent: (_c = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.agent) !== null && _c !== void 0 ? _c : agent,
50
- operationType: (_d = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.operationType) !== null && _d !== void 0 ? _d : metering.operationType.toString(),
51
- inputTokenCount: (_e = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.inputTokenCount) !== null && _e !== void 0 ? _e : metering.tokenCounts.inputTokens,
52
- outputTokenCount: (_f = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.outputTokenCount) !== null && _f !== void 0 ? _f : metering.tokenCounts.outputTokens,
53
- reasoningTokenCount: (_h = (_g = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.reasoningTokenCount) !== null && _g !== void 0 ? _g : metering.tokenCounts.reasoningTokens) !== null && _h !== void 0 ? _h : 0,
54
- cacheCreationTokenCount: (_k = (_j = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.cacheCreationTokenCount) !== null && _j !== void 0 ? _j : metering.tokenCounts.cachedTokens) !== null && _k !== void 0 ? _k : 0,
55
- cacheReadTokenCount: (_l = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.cacheReadTokenCount) !== null && _l !== void 0 ? _l : 0,
56
- totalTokenCount: (_m = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.totalTokenCount) !== null && _m !== void 0 ? _m : metering.tokenCounts.totalTokens,
57
- organizationId: (_o = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.organizationId) !== null && _o !== void 0 ? _o : `my-customer-name-${(0, generateTransactionId_1.generateTransactionId)()}`,
58
- productId: (_p = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.productId) !== null && _p !== void 0 ? _p : utils_1.PRODUCT_ID_FREE,
59
- subscriber: {
60
- id: (_q = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.subscriberId) !== null && _q !== void 0 ? _q : `user-${(0, generateTransactionId_1.generateTransactionId)()}`,
61
- email: (_r = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.subscriberEmail) !== null && _r !== void 0 ? _r : `user-@${agent.toLowerCase()}.ai`,
62
- credential: (usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.subscriberCredentialName) &&
63
- (usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.subscriberCredential)
64
- ? {
65
- name: usageMetadata.subscriberCredentialName,
66
- value: usageMetadata.subscriberCredential,
67
- }
68
- : utils_1.CURRENT_CREDENTIAL,
69
- },
70
- model: metering.modelName,
71
- transactionId: (_s = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.transactionId) !== null && _s !== void 0 ? _s : (0, generateTransactionId_1.generateTransactionId)(),
72
- responseTime: (0, formatTimestamp_1.formatTimestamp)(metering.endTime),
73
- requestDuration: (0, calculateDurationMs_1.calculateDurationMs)(metering.startTime, metering.endTime),
74
- provider: agent,
75
- requestTime: (_u = (_t = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.requestTime) === null || _t === void 0 ? void 0 : _t.toString()) !== null && _u !== void 0 ? _u : (0, formatTimestamp_1.formatTimestamp)(metering.startTime),
76
- completionStartTime: (_w = (_v = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.completionStartTime) === null || _v === void 0 ? void 0 : _v.toString()) !== null && _w !== void 0 ? _w : (0, formatTimestamp_1.formatTimestamp)(metering.endTime),
77
- timeToFirstToken: (_x = usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.timeToFirstToken) !== null && _x !== void 0 ? _x : 0,
78
- middleware_source: utils_1.MIDDLEWARE_SOURCE,
79
- traceId: usageMetadata === null || usageMetadata === void 0 ? void 0 : usageMetadata.traceId,
80
- };
81
- }
82
- }
83
- exports.Metering = Metering;
@@ -1,166 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PerplexityV1Service = void 0;
7
- const openai_1 = __importDefault(require("openai"));
8
- const Logger_1 = require("../models/Logger");
9
- const Metering_1 = require("../models/Metering");
10
- const generateTransactionId_1 = require("../utils/generateTransactionId");
11
- const operation_1 = require("../interfaces/operation");
12
- const utils_1 = require("../utils");
13
- class PerplexityV1Service {
14
- constructor() {
15
- this.working = true;
16
- this.client = new openai_1.default({
17
- apiKey: utils_1.PERPLEXITY_API_KEY,
18
- baseURL: utils_1.PERPLEXITY_API_BASE_URL,
19
- });
20
- Logger_1.logger.info(utils_1.PERPLEXITY_CLIENT_INITIALIZED_MESSAGE);
21
- }
22
- async createChatCompletion(params, model) {
23
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
24
- const transactionId = (0, generateTransactionId_1.generateTransactionId)();
25
- const startTime = new Date();
26
- try {
27
- const { usageMetadata, ...openaiParams } = params;
28
- const requestParams = {
29
- ...openaiParams,
30
- model,
31
- };
32
- const result = (await this.client.chat.completions.create({
33
- ...requestParams,
34
- stream: false,
35
- }));
36
- // Build V1 response format
37
- const perplexityResponse = {
38
- responses: [
39
- {
40
- text: ((_b = (_a = result.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.content) || "",
41
- role: "assistant",
42
- finishReason: (_c = result.choices[0]) === null || _c === void 0 ? void 0 : _c.finish_reason,
43
- },
44
- ],
45
- usageMetadata: {
46
- inputTokenCount: ((_d = result.usage) === null || _d === void 0 ? void 0 : _d.prompt_tokens) || 0,
47
- outputTokenCount: ((_e = result.usage) === null || _e === void 0 ? void 0 : _e.completion_tokens) || 0,
48
- totalTokenCount: ((_f = result.usage) === null || _f === void 0 ? void 0 : _f.total_tokens) || 0,
49
- },
50
- modelVersion: result.model,
51
- transactionId,
52
- };
53
- // Send metering data (using current middleware logic)
54
- if (this.working) {
55
- const tokenCounts = {
56
- inputTokens: ((_g = result.usage) === null || _g === void 0 ? void 0 : _g.prompt_tokens) || 0,
57
- outputTokens: ((_h = result.usage) === null || _h === void 0 ? void 0 : _h.completion_tokens) || 0,
58
- totalTokens: ((_j = result.usage) === null || _j === void 0 ? void 0 : _j.total_tokens) || 0,
59
- };
60
- const endTime = new Date();
61
- Logger_1.logger.info("Metering is working.");
62
- const metering = new Metering_1.Metering(utils_1.REVENIUM_METERING_API_KEY !== null && utils_1.REVENIUM_METERING_API_KEY !== void 0 ? utils_1.REVENIUM_METERING_API_KEY : "", utils_1.REVENIUM_METERING_BASE_URL !== null && utils_1.REVENIUM_METERING_BASE_URL !== void 0 ? utils_1.REVENIUM_METERING_BASE_URL : "");
63
- // Combine user metadata with transaction ID
64
- const combinedMetadata = {
65
- ...usageMetadata,
66
- transactionId,
67
- };
68
- const getMetering = metering.createMetering({
69
- modelName: model,
70
- endTime,
71
- startTime,
72
- operationType: operation_1.IOperationType.CHAT,
73
- stopReason: "END",
74
- tokenCounts,
75
- usageMetadata: combinedMetadata,
76
- }, false);
77
- await metering.sendMeteringData(getMetering);
78
- }
79
- else {
80
- Logger_1.logger.warning("Metering is not working. Check your configuration.");
81
- }
82
- return perplexityResponse;
83
- }
84
- catch (error) {
85
- Logger_1.logger.error("Error in Perplexity V1 chat completion:", error);
86
- throw error;
87
- }
88
- }
89
- async createStreamingCompletion(params, model) {
90
- const transactionId = (0, generateTransactionId_1.generateTransactionId)();
91
- const startTime = new Date();
92
- try {
93
- const { usageMetadata, ...openaiParams } = params;
94
- const requestParams = {
95
- ...openaiParams,
96
- model,
97
- };
98
- const stream = await this.client.chat.completions.create({
99
- ...requestParams,
100
- stream: true,
101
- });
102
- const wrappedStream = this.wrapStream(stream, transactionId, model, startTime, usageMetadata);
103
- return {
104
- stream: wrappedStream,
105
- usageMetadata: {
106
- inputTokenCount: 0, // Will be updated when stream completes
107
- outputTokenCount: 0,
108
- totalTokenCount: 0,
109
- },
110
- modelVersion: model,
111
- transactionId,
112
- };
113
- }
114
- catch (error) {
115
- Logger_1.logger.error("Error in Perplexity V1 streaming:", error);
116
- throw error;
117
- }
118
- }
119
- async *wrapStream(stream, transactionId, model, startTime, usageMetadata) {
120
- let lastChunk = null;
121
- try {
122
- for await (const chunk of stream) {
123
- lastChunk = chunk;
124
- yield chunk;
125
- }
126
- // Send metering data when stream completes (using current middleware logic)
127
- if (this.working) {
128
- // For streaming, we'll use the last chunk's usage data if available
129
- const tokenCounts = {
130
- inputTokens: 0, // Will be updated if lastChunk has usage data
131
- outputTokens: 0,
132
- totalTokens: 0,
133
- };
134
- const endTime = new Date();
135
- Logger_1.logger.info("Metering is working.");
136
- const metering = new Metering_1.Metering(utils_1.REVENIUM_METERING_API_KEY !== null && utils_1.REVENIUM_METERING_API_KEY !== void 0 ? utils_1.REVENIUM_METERING_API_KEY : "", utils_1.REVENIUM_METERING_BASE_URL !== null && utils_1.REVENIUM_METERING_BASE_URL !== void 0 ? utils_1.REVENIUM_METERING_BASE_URL : "");
137
- // Combine user metadata with transaction ID
138
- const combinedMetadata = {
139
- ...usageMetadata,
140
- transactionId,
141
- };
142
- const getMetering = metering.createMetering({
143
- modelName: model,
144
- endTime,
145
- startTime,
146
- operationType: operation_1.IOperationType.CHAT,
147
- stopReason: "END",
148
- tokenCounts,
149
- usageMetadata: combinedMetadata,
150
- }, true);
151
- await metering.sendMeteringData(getMetering);
152
- }
153
- else {
154
- Logger_1.logger.warning("Metering is not working. Check your configuration.");
155
- }
156
- }
157
- catch (error) {
158
- Logger_1.logger.error("Error in Perplexity V1 stream processing:", error);
159
- throw error;
160
- }
161
- }
162
- setWorking(working) {
163
- this.working = working;
164
- }
165
- }
166
- exports.PerplexityV1Service = PerplexityV1Service;