@revenium/perplexity 1.0.23 → 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.
- package/README.md +468 -364
- package/dist/cjs/core/config/perplexity-config.js +45 -0
- package/dist/cjs/core/config/perplexity-config.js.map +1 -0
- package/dist/cjs/core/config/revenium-config.js +80 -0
- package/dist/cjs/core/config/revenium-config.js.map +1 -0
- package/dist/cjs/core/tracking/metering.js +131 -0
- package/dist/cjs/core/tracking/metering.js.map +1 -0
- package/dist/cjs/core/wrapper/perplexity-client.js +177 -0
- package/dist/cjs/core/wrapper/perplexity-client.js.map +1 -0
- package/dist/cjs/index.js +64 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types/index.js +21 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/utils/logger.js +23 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/esm/core/config/perplexity-config.js +40 -0
- package/dist/esm/core/config/perplexity-config.js.map +1 -0
- package/dist/esm/core/config/revenium-config.js +72 -0
- package/dist/esm/core/config/revenium-config.js.map +1 -0
- package/dist/esm/core/tracking/metering.js +126 -0
- package/dist/esm/core/tracking/metering.js.map +1 -0
- package/dist/esm/core/wrapper/perplexity-client.js +170 -0
- package/dist/esm/core/wrapper/perplexity-client.js.map +1 -0
- package/dist/esm/index.js +44 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types/index.js +18 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/utils/logger.js +20 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/types/core/config/perplexity-config.d.ts +24 -0
- package/dist/types/core/config/perplexity-config.d.ts.map +1 -0
- package/dist/types/core/config/revenium-config.d.ts +37 -0
- package/dist/types/core/config/revenium-config.d.ts.map +1 -0
- package/dist/types/core/tracking/metering.d.ts +31 -0
- package/dist/types/core/tracking/metering.d.ts.map +1 -0
- package/dist/types/core/wrapper/perplexity-client.d.ts +32 -0
- package/dist/types/core/wrapper/perplexity-client.d.ts.map +1 -0
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +159 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/utils/logger.d.ts +10 -0
- package/dist/types/utils/logger.d.ts.map +1 -0
- package/package.json +36 -16
- package/.env.example +0 -3
- package/dist/index.js +0 -19
- package/dist/interfaces/chatCompletionRequest.d.ts +0 -9
- package/dist/interfaces/chatCompletionRequest.js +0 -2
- package/dist/interfaces/credential.d.ts +0 -4
- package/dist/interfaces/credential.js +0 -2
- package/dist/interfaces/meteringRequest.d.ts +0 -13
- package/dist/interfaces/meteringRequest.js +0 -2
- package/dist/interfaces/meteringResponse.d.ts +0 -27
- package/dist/interfaces/meteringResponse.js +0 -2
- package/dist/interfaces/operation.d.ts +0 -4
- package/dist/interfaces/operation.js +0 -8
- package/dist/interfaces/subscriber.d.ts +0 -8
- package/dist/interfaces/subscriber.js +0 -2
- package/dist/interfaces/tokenCounts.d.ts +0 -7
- package/dist/interfaces/tokenCounts.js +0 -2
- package/dist/interfaces/usageMetadata.d.ts +0 -27
- package/dist/interfaces/usageMetadata.js +0 -2
- package/dist/middleware.d.ts +0 -22
- package/dist/middleware.js +0 -129
- package/dist/models/Logger.js +0 -35
- package/dist/models/Metering.d.ts +0 -9
- package/dist/models/Metering.js +0 -80
- package/dist/utils/calculateDurationMs.d.ts +0 -1
- package/dist/utils/calculateDurationMs.js +0 -6
- package/dist/utils/constants/constants.d.ts +0 -6
- package/dist/utils/constants/constants.js +0 -11
- package/dist/utils/constants/logLevels.d.ts +0 -1
- package/dist/utils/constants/logLevels.js +0 -4
- package/dist/utils/constants/messages.d.ts +0 -5
- package/dist/utils/constants/messages.js +0 -8
- package/dist/utils/constants/models.d.ts +0 -1
- package/dist/utils/constants/models.js +0 -21
- package/dist/utils/extractTokenCount.d.ts +0 -2
- package/dist/utils/extractTokenCount.js +0 -28
- package/dist/utils/formatTimeStamp.d.ts +0 -1
- package/dist/utils/formatTimeStamp.js +0 -6
- package/dist/utils/generateTransactionId.d.ts +0 -1
- package/dist/utils/generateTransactionId.js +0 -7
- package/dist/utils/index.d.ts +0 -6
- package/dist/utils/index.js +0 -23
- package/dist/utils/loadEnv.d.ts +0 -1
- package/dist/utils/loadEnv.js +0 -7
- package/dist/utils/safeExtract.d.ts +0 -29
- package/dist/utils/safeExtract.js +0 -67
- package/examples/basic.ts +0 -17
- package/examples/chat-completions.ts +0 -22
- package/examples/enhanced.ts +0 -20
- package/examples/metadata.ts +0 -43
- package/examples/streaming.ts +0 -24
- package/playground/basic.js +0 -17
- package/playground/chat-completions.js +0 -22
- package/playground/enhanced.js +0 -20
- package/playground/metadata.js +0 -43
- package/playground/streaming.js +0 -24
- package/src/index.ts +0 -4
- package/src/interfaces/chatCompletionRequest.ts +0 -10
- package/src/interfaces/credential.ts +0 -4
- package/src/interfaces/meteringRequest.ts +0 -14
- package/src/interfaces/meteringResponse.ts +0 -28
- package/src/interfaces/operation.ts +0 -4
- package/src/interfaces/subscriber.ts +0 -8
- package/src/interfaces/tokenCounts.ts +0 -7
- package/src/interfaces/usageMetadata.ts +0 -27
- package/src/middleware.ts +0 -157
- package/src/models/Logger.ts +0 -38
- package/src/models/Metering.ts +0 -114
- package/src/utils/calculateDurationMs.ts +0 -3
- package/src/utils/constants/constants.ts +0 -10
- package/src/utils/constants/logLevels.ts +0 -1
- package/src/utils/constants/messages.ts +0 -11
- package/src/utils/constants/models.ts +0 -20
- package/src/utils/extractTokenCount.ts +0 -26
- package/src/utils/formatTimestamp.ts +0 -3
- package/src/utils/generateTransactionId.ts +0 -5
- package/src/utils/index.ts +0 -39
- package/src/utils/loadEnv.ts +0 -8
- package/src/utils/safeExtract.ts +0 -67
- package/tsconfig.json +0 -15
package/src/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ChatCompletionMessageParam } from "openai/resources/index";
|
|
2
|
-
import { IUsageMetadata } from "./usageMetadata";
|
|
3
|
-
|
|
4
|
-
export interface IChatCompletionRequest {
|
|
5
|
-
model?: string;
|
|
6
|
-
messages: ChatCompletionMessageParam[];
|
|
7
|
-
stream?: boolean;
|
|
8
|
-
usageMetadata?: IUsageMetadata;
|
|
9
|
-
[key: string]: any;
|
|
10
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { IOperationType } from "./operation";
|
|
2
|
-
import { ITokenCounts } from "./tokenCounts";
|
|
3
|
-
import { IUsageMetadata } from "./usageMetadata";
|
|
4
|
-
|
|
5
|
-
export interface IMeteringRequest {
|
|
6
|
-
transactionId?: string;
|
|
7
|
-
startTime: Date;
|
|
8
|
-
endTime: Date;
|
|
9
|
-
modelName: string;
|
|
10
|
-
tokenCounts: ITokenCounts;
|
|
11
|
-
stopReason: string;
|
|
12
|
-
operationType: IOperationType;
|
|
13
|
-
usageMetadata?: IUsageMetadata;
|
|
14
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ISubscriber } from "./subscriber";
|
|
2
|
-
|
|
3
|
-
export interface IMeteringResponse {
|
|
4
|
-
stopReason: string;
|
|
5
|
-
costType: string;
|
|
6
|
-
isStreamed: boolean;
|
|
7
|
-
taskType: string;
|
|
8
|
-
agent: string;
|
|
9
|
-
operationType: string;
|
|
10
|
-
inputTokenCount: number;
|
|
11
|
-
outputTokenCount: number;
|
|
12
|
-
reasoningTokenCount: number;
|
|
13
|
-
cacheCreationTokenCount: number;
|
|
14
|
-
cacheReadTokenCount: number;
|
|
15
|
-
totalTokenCount: number;
|
|
16
|
-
organizationId: string;
|
|
17
|
-
productId: string;
|
|
18
|
-
subscriber: ISubscriber;
|
|
19
|
-
model: string;
|
|
20
|
-
transactionId: string;
|
|
21
|
-
responseTime: string;
|
|
22
|
-
requestDuration: number;
|
|
23
|
-
provider: string;
|
|
24
|
-
requestTime: string;
|
|
25
|
-
completionStartTime: string;
|
|
26
|
-
timeToFirstToken: number;
|
|
27
|
-
middleware_source: string;
|
|
28
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export interface IUsageMetadata {
|
|
2
|
-
traceId?: string;
|
|
3
|
-
taskType?: string;
|
|
4
|
-
subscriberEmail?: string;
|
|
5
|
-
subscriberId?: string;
|
|
6
|
-
subscriberCredentialName?: string;
|
|
7
|
-
subscriberCredential?: string;
|
|
8
|
-
organizationId?: string;
|
|
9
|
-
subscriptionId?: string;
|
|
10
|
-
productId?: string;
|
|
11
|
-
agent?: string;
|
|
12
|
-
responseQualityScore?: number;
|
|
13
|
-
transactionId?: string;
|
|
14
|
-
timeToFirstToken?: number;
|
|
15
|
-
requestTime?: Date;
|
|
16
|
-
completionStartTime?: Date;
|
|
17
|
-
operationType?: string;
|
|
18
|
-
inputTokenCount?: number;
|
|
19
|
-
outputTokenCount?: number;
|
|
20
|
-
reasoningTokenCount?: number;
|
|
21
|
-
cacheCreationTokenCount?: number;
|
|
22
|
-
cacheReadTokenCount?: number;
|
|
23
|
-
totalTokenCount?: number;
|
|
24
|
-
responseTime?: Date;
|
|
25
|
-
requestDuration?: number;
|
|
26
|
-
stopReason?: string;
|
|
27
|
-
}
|
package/src/middleware.ts
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import OpenAI from "openai";
|
|
2
|
-
import {
|
|
3
|
-
models,
|
|
4
|
-
PERPLEXITY_API_BASE_URL,
|
|
5
|
-
PERPLEXITY_API_KEY,
|
|
6
|
-
PERPLEXITY_API_KEY_INVALID_MESSAGE,
|
|
7
|
-
PERPLEXITY_CLIENT_INITIALIZED_MESSAGE,
|
|
8
|
-
PERPLEXITY_METERING_API_KEY_IS_NOT_SET_MESSAGE,
|
|
9
|
-
PERPLEXITY_METERING_BASE_URL_IS_NOT_SET_MESSAGE,
|
|
10
|
-
PERPLEXITY_REQUIRED_API_KEY_MESSAGE,
|
|
11
|
-
REVENIUM_METERING_API_KEY,
|
|
12
|
-
REVENIUM_METERING_BASE_URL,
|
|
13
|
-
} from "./utils";
|
|
14
|
-
import { logger } from "./models/Logger";
|
|
15
|
-
import { IChatCompletionRequest } from "./interfaces/chatCompletionRequest";
|
|
16
|
-
import { Metering } from "./models/Metering";
|
|
17
|
-
import { IOperationType } from "./interfaces/operation";
|
|
18
|
-
import { extractGoogleAITokenCounts } from "./utils/extractTokenCount";
|
|
19
|
-
import { RequestOptions } from "openai/internal/request-options";
|
|
20
|
-
|
|
21
|
-
export class PerplexityReveniumMiddleware {
|
|
22
|
-
private client: OpenAI;
|
|
23
|
-
private working: boolean = true;
|
|
24
|
-
private modelName: string = "";
|
|
25
|
-
constructor() {
|
|
26
|
-
this.verifyEnv();
|
|
27
|
-
this.client = new OpenAI({
|
|
28
|
-
apiKey: PERPLEXITY_API_KEY,
|
|
29
|
-
baseURL: PERPLEXITY_API_BASE_URL,
|
|
30
|
-
});
|
|
31
|
-
logger.info(PERPLEXITY_CLIENT_INITIALIZED_MESSAGE);
|
|
32
|
-
}
|
|
33
|
-
public getGenerativeModel(model: string) {
|
|
34
|
-
this.modelName = model;
|
|
35
|
-
if (!models.includes(model)) {
|
|
36
|
-
throw new Error(`Model ${model} is not supported`);
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
createChatCompletion: this.chatCompletion,
|
|
40
|
-
createChatCompletionStream: this.streamingChatCompletion,
|
|
41
|
-
createEmbeddings: this.embeddings,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private embeddings = async (
|
|
46
|
-
_body: Omit<OpenAI.Embeddings.EmbeddingCreateParams, "model">,
|
|
47
|
-
_options?: RequestOptions
|
|
48
|
-
) => {};
|
|
49
|
-
|
|
50
|
-
private streamingChatCompletion = async (params: IChatCompletionRequest) => {
|
|
51
|
-
const startTime: Date = new Date();
|
|
52
|
-
try {
|
|
53
|
-
const { usageMetadata, ...openaiParams } = params;
|
|
54
|
-
const requestParams = {
|
|
55
|
-
...openaiParams,
|
|
56
|
-
model: this.modelName,
|
|
57
|
-
};
|
|
58
|
-
const result = await this.client?.chat.completions.create({
|
|
59
|
-
...requestParams,
|
|
60
|
-
stream: true,
|
|
61
|
-
});
|
|
62
|
-
if (!this.working) {
|
|
63
|
-
logger.warning("Metering is not working. Check your configuration.");
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
const tokenCounts = extractGoogleAITokenCounts(result);
|
|
67
|
-
const endTime: Date = new Date();
|
|
68
|
-
logger.info("Metering is working.");
|
|
69
|
-
const metering = new Metering(
|
|
70
|
-
REVENIUM_METERING_API_KEY ?? "",
|
|
71
|
-
REVENIUM_METERING_BASE_URL ?? ""
|
|
72
|
-
);
|
|
73
|
-
const getMetering = metering.createMetering(
|
|
74
|
-
{
|
|
75
|
-
modelName: this.modelName,
|
|
76
|
-
endTime,
|
|
77
|
-
startTime,
|
|
78
|
-
operationType: IOperationType.CHAT,
|
|
79
|
-
stopReason: "END",
|
|
80
|
-
tokenCounts,
|
|
81
|
-
usageMetadata,
|
|
82
|
-
},
|
|
83
|
-
true
|
|
84
|
-
);
|
|
85
|
-
await metering.sendMeteringData(getMetering);
|
|
86
|
-
return result;
|
|
87
|
-
} catch (error) {
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
private chatCompletion = async (params: IChatCompletionRequest) => {
|
|
93
|
-
const startTime: Date = new Date();
|
|
94
|
-
try {
|
|
95
|
-
const { usageMetadata, ...openaiParams } = params;
|
|
96
|
-
const requestParams = {
|
|
97
|
-
...openaiParams,
|
|
98
|
-
model: this.modelName,
|
|
99
|
-
};
|
|
100
|
-
const result: OpenAI.Chat.Completions.ChatCompletion & {
|
|
101
|
-
_request_id?: string | null | undefined;
|
|
102
|
-
} = await this.client?.chat.completions.create({
|
|
103
|
-
...requestParams,
|
|
104
|
-
stream: false,
|
|
105
|
-
});
|
|
106
|
-
if (!this.working) {
|
|
107
|
-
logger.warning("Metering is not working. Check your configuration.");
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
const tokenCounts = extractGoogleAITokenCounts(result);
|
|
111
|
-
const endTime: Date = new Date();
|
|
112
|
-
logger.info(" Metering is working.");
|
|
113
|
-
const metering = new Metering(
|
|
114
|
-
REVENIUM_METERING_API_KEY ?? "",
|
|
115
|
-
REVENIUM_METERING_BASE_URL ?? ""
|
|
116
|
-
);
|
|
117
|
-
const getMetering = metering.createMetering(
|
|
118
|
-
{
|
|
119
|
-
modelName: this.modelName,
|
|
120
|
-
endTime,
|
|
121
|
-
startTime,
|
|
122
|
-
operationType: IOperationType.CHAT,
|
|
123
|
-
stopReason: "END",
|
|
124
|
-
tokenCounts,
|
|
125
|
-
usageMetadata,
|
|
126
|
-
},
|
|
127
|
-
false
|
|
128
|
-
);
|
|
129
|
-
await metering.sendMeteringData(getMetering);
|
|
130
|
-
return result;
|
|
131
|
-
} catch (error) {
|
|
132
|
-
throw error;
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
private verifyEnv(): void {
|
|
137
|
-
if (!PERPLEXITY_API_KEY) {
|
|
138
|
-
logger.error(PERPLEXITY_REQUIRED_API_KEY_MESSAGE);
|
|
139
|
-
throw new Error(PERPLEXITY_REQUIRED_API_KEY_MESSAGE);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!PERPLEXITY_API_KEY.includes("pplx-")) {
|
|
143
|
-
logger.error(PERPLEXITY_API_KEY_INVALID_MESSAGE);
|
|
144
|
-
throw new Error(PERPLEXITY_API_KEY_INVALID_MESSAGE);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!REVENIUM_METERING_API_KEY) {
|
|
148
|
-
logger.warning(PERPLEXITY_METERING_API_KEY_IS_NOT_SET_MESSAGE);
|
|
149
|
-
this.working = false;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (!REVENIUM_METERING_BASE_URL) {
|
|
153
|
-
logger.warning(PERPLEXITY_METERING_BASE_URL_IS_NOT_SET_MESSAGE);
|
|
154
|
-
this.working = false;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
package/src/models/Logger.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { LOG_LEVELS } from "../utils";
|
|
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;
|
package/src/models/Metering.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { IMeteringRequest } from "../interfaces/meteringRequest";
|
|
2
|
-
import { IMeteringResponse } from "../interfaces/meteringResponse";
|
|
3
|
-
import {
|
|
4
|
-
COST_TYPE,
|
|
5
|
-
CURRENT_CREDENTIAL,
|
|
6
|
-
MIDDLEWARE_SOURCE,
|
|
7
|
-
PRODUCT_ID_FREE,
|
|
8
|
-
REVENIUM_METERING_API_KEY,
|
|
9
|
-
REVENIUM_METERING_BASE_URL,
|
|
10
|
-
} from "../utils";
|
|
11
|
-
import { calculateDurationMs } from "../utils/calculateDurationMs";
|
|
12
|
-
import { formatTimestamp } from "../utils/formatTimestamp";
|
|
13
|
-
import { generateTransactionId } from "../utils/generateTransactionId";
|
|
14
|
-
import { logger } from "./Logger";
|
|
15
|
-
|
|
16
|
-
export class Metering {
|
|
17
|
-
private endpoint: string = "";
|
|
18
|
-
private apiKey: string = "";
|
|
19
|
-
constructor(clientApiKey: string, clientEndpoint: string) {
|
|
20
|
-
this.apiKey = clientApiKey;
|
|
21
|
-
this.endpoint = clientEndpoint;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public createMetering(
|
|
25
|
-
metering: IMeteringRequest,
|
|
26
|
-
isStreamed: boolean
|
|
27
|
-
): IMeteringResponse {
|
|
28
|
-
const usageMetadata = metering.usageMetadata;
|
|
29
|
-
const agent: string = "perplexity";
|
|
30
|
-
return {
|
|
31
|
-
stopReason: usageMetadata?.stopReason ?? metering.stopReason,
|
|
32
|
-
costType: COST_TYPE,
|
|
33
|
-
isStreamed,
|
|
34
|
-
taskType: COST_TYPE,
|
|
35
|
-
agent: usageMetadata?.agent ?? agent,
|
|
36
|
-
operationType:
|
|
37
|
-
usageMetadata?.operationType ?? metering.operationType.toString(),
|
|
38
|
-
inputTokenCount:
|
|
39
|
-
usageMetadata?.inputTokenCount ?? metering.tokenCounts.inputTokens,
|
|
40
|
-
outputTokenCount:
|
|
41
|
-
usageMetadata?.outputTokenCount ?? metering.tokenCounts.outputTokens,
|
|
42
|
-
reasoningTokenCount:
|
|
43
|
-
usageMetadata?.reasoningTokenCount ??
|
|
44
|
-
metering.tokenCounts.reasoningTokens ??
|
|
45
|
-
0,
|
|
46
|
-
cacheCreationTokenCount:
|
|
47
|
-
usageMetadata?.cacheCreationTokenCount ??
|
|
48
|
-
metering.tokenCounts.cachedTokens ??
|
|
49
|
-
0,
|
|
50
|
-
cacheReadTokenCount: usageMetadata?.cacheReadTokenCount ?? 0,
|
|
51
|
-
totalTokenCount:
|
|
52
|
-
usageMetadata?.totalTokenCount ?? metering.tokenCounts.totalTokens,
|
|
53
|
-
organizationId:
|
|
54
|
-
usageMetadata?.organizationId ??
|
|
55
|
-
`my-customer-name-${generateTransactionId()}`,
|
|
56
|
-
productId: usageMetadata?.productId ?? PRODUCT_ID_FREE,
|
|
57
|
-
subscriber: {
|
|
58
|
-
id: usageMetadata?.subscriberId ?? `user-${generateTransactionId()}`,
|
|
59
|
-
email:
|
|
60
|
-
usageMetadata?.subscriberEmail ?? `user-@${agent.toLowerCase()}.ai`,
|
|
61
|
-
credential:
|
|
62
|
-
usageMetadata?.subscriberCredentialName &&
|
|
63
|
-
usageMetadata?.subscriberCredential
|
|
64
|
-
? {
|
|
65
|
-
name: usageMetadata.subscriberCredentialName,
|
|
66
|
-
value: usageMetadata.subscriberCredential,
|
|
67
|
-
}
|
|
68
|
-
: CURRENT_CREDENTIAL,
|
|
69
|
-
},
|
|
70
|
-
model: metering.modelName,
|
|
71
|
-
transactionId: usageMetadata?.transactionId ?? generateTransactionId(),
|
|
72
|
-
responseTime: formatTimestamp(metering.endTime),
|
|
73
|
-
requestDuration: calculateDurationMs(
|
|
74
|
-
metering.startTime,
|
|
75
|
-
metering.endTime
|
|
76
|
-
),
|
|
77
|
-
provider: agent,
|
|
78
|
-
requestTime:
|
|
79
|
-
usageMetadata?.requestTime?.toString() ??
|
|
80
|
-
formatTimestamp(metering.startTime),
|
|
81
|
-
completionStartTime:
|
|
82
|
-
usageMetadata?.completionStartTime?.toString() ??
|
|
83
|
-
formatTimestamp(metering.endTime),
|
|
84
|
-
timeToFirstToken: usageMetadata?.timeToFirstToken ?? 0,
|
|
85
|
-
middleware_source: MIDDLEWARE_SOURCE,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
public sendMeteringData = async (
|
|
90
|
-
metering: IMeteringResponse
|
|
91
|
-
): Promise<void> => {
|
|
92
|
-
try {
|
|
93
|
-
const response = await fetch(`${this.endpoint}/v2/ai/completions`, {
|
|
94
|
-
method: "POST",
|
|
95
|
-
headers: {
|
|
96
|
-
"Content-Type": "application/json",
|
|
97
|
-
"x-api-key": this.apiKey,
|
|
98
|
-
accept: "application/json",
|
|
99
|
-
},
|
|
100
|
-
body: JSON.stringify(metering),
|
|
101
|
-
});
|
|
102
|
-
if (!response.ok) {
|
|
103
|
-
const errorData = await response?.text();
|
|
104
|
-
logger.error(
|
|
105
|
-
`Metering API request failed with status ${response.status} - ${errorData}`
|
|
106
|
-
);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
logger.info(`Metering data sent successfully to Revenium`);
|
|
110
|
-
} catch (error: any) {
|
|
111
|
-
logger.error(`Error to sent metering data ${error}`);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ICredential } from "../../interfaces/credential";
|
|
2
|
-
|
|
3
|
-
export const PERPLEXITY_API_BASE_URL: string = "https://api.perplexity.ai";
|
|
4
|
-
export const COST_TYPE: string = "AI";
|
|
5
|
-
export const MIDDLEWARE_SOURCE: string = "node";
|
|
6
|
-
export const PRODUCT_ID_FREE: string = "free-trial";
|
|
7
|
-
export const CURRENT_CREDENTIAL: ICredential = {
|
|
8
|
-
name: "apiKey",
|
|
9
|
-
value: "keyValue",
|
|
10
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const LOG_LEVELS: string[] = ["DEBUG", "INFO", "WARNING", "ERROR"];
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const PERPLEXITY_REQUIRED_API_KEY_MESSAGE: string =
|
|
2
|
-
"PERPLEXITY_API_KEY is required. Set it in environment variables or pass it to the constructor.";
|
|
3
|
-
|
|
4
|
-
export const PERPLEXITY_API_KEY_INVALID_MESSAGE: string =
|
|
5
|
-
"PERPLEXITY_API_KEY is invalid. Please check your API key.";
|
|
6
|
-
export const PERPLEXITY_METERING_API_KEY_IS_NOT_SET_MESSAGE: string =
|
|
7
|
-
"REVENIUM_METERING_API_KEY is not set. Metering will not work.";
|
|
8
|
-
export const PERPLEXITY_METERING_BASE_URL_IS_NOT_SET_MESSAGE: string =
|
|
9
|
-
"REVENIUM_METERING_BASE_URL is not set. Metering will not work.";
|
|
10
|
-
export const PERPLEXITY_CLIENT_INITIALIZED_MESSAGE =
|
|
11
|
-
"Perplexity AI client initialized with middleware";
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const models: string[] = [
|
|
2
|
-
// Perplexity Sonar Models (2025) - Chat Completions
|
|
3
|
-
"sonar", // Lightweight, cost-effective search model
|
|
4
|
-
"sonar-pro", // Advanced search with deeper content understanding
|
|
5
|
-
"sonar-reasoning", // Quick problem-solving with step-by-step logic and search
|
|
6
|
-
"sonar-reasoning-pro", // Enhanced multi-step reasoning with web search
|
|
7
|
-
"sonar-deep-research", // Exhaustive research and detailed report generation
|
|
8
|
-
|
|
9
|
-
// Legacy models (deprecated - will be removed)
|
|
10
|
-
"sonar-small",
|
|
11
|
-
"sonar-small-online",
|
|
12
|
-
"sonar-medium-online",
|
|
13
|
-
"sonar-small-chat",
|
|
14
|
-
"sonar-medium-chat",
|
|
15
|
-
|
|
16
|
-
// OpenAI Embedding Models (use with OpenAI client directly)
|
|
17
|
-
"text-embedding-3-small", // Most capable small embedding model
|
|
18
|
-
"text-embedding-3-large", // Most capable large embedding model
|
|
19
|
-
"text-embedding-ada-002", // Legacy embedding model
|
|
20
|
-
];
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ITokenCounts } from "../interfaces/tokenCounts";
|
|
2
|
-
import { logger } from "../models/Logger";
|
|
3
|
-
import { safeExtract } from "./safeExtract";
|
|
4
|
-
|
|
5
|
-
export function extractGoogleAITokenCounts(response: any): ITokenCounts {
|
|
6
|
-
console.log;
|
|
7
|
-
try {
|
|
8
|
-
const usageMetadata = response.usage || (response as any).response?.usage;
|
|
9
|
-
if (!usageMetadata)
|
|
10
|
-
return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
11
|
-
|
|
12
|
-
const inputTokens = safeExtract.number(usageMetadata, "prompt_tokens");
|
|
13
|
-
const outputTokens = safeExtract.number(usageMetadata, "completion_tokens");
|
|
14
|
-
const totalTokens = safeExtract.number(usageMetadata, "total_tokens");
|
|
15
|
-
return {
|
|
16
|
-
inputTokens,
|
|
17
|
-
outputTokens,
|
|
18
|
-
totalTokens,
|
|
19
|
-
cachedTokens: 0,
|
|
20
|
-
reasoningTokens: 0,
|
|
21
|
-
};
|
|
22
|
-
} catch (error) {
|
|
23
|
-
logger.warning("Failed to extract Google AI token counts:", error);
|
|
24
|
-
return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/utils/index.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PERPLEXITY_API_KEY,
|
|
3
|
-
REVENIUM_METERING_API_KEY,
|
|
4
|
-
REVENIUM_METERING_BASE_URL,
|
|
5
|
-
} from "./loadEnv";
|
|
6
|
-
import {
|
|
7
|
-
PERPLEXITY_REQUIRED_API_KEY_MESSAGE,
|
|
8
|
-
PERPLEXITY_API_KEY_INVALID_MESSAGE,
|
|
9
|
-
PERPLEXITY_METERING_API_KEY_IS_NOT_SET_MESSAGE,
|
|
10
|
-
PERPLEXITY_METERING_BASE_URL_IS_NOT_SET_MESSAGE,
|
|
11
|
-
PERPLEXITY_CLIENT_INITIALIZED_MESSAGE,
|
|
12
|
-
} from "./constants/messages";
|
|
13
|
-
import { LOG_LEVELS } from "./constants/logLevels";
|
|
14
|
-
import { models } from "./constants/models";
|
|
15
|
-
import {
|
|
16
|
-
PERPLEXITY_API_BASE_URL,
|
|
17
|
-
COST_TYPE,
|
|
18
|
-
MIDDLEWARE_SOURCE,
|
|
19
|
-
PRODUCT_ID_FREE,
|
|
20
|
-
CURRENT_CREDENTIAL,
|
|
21
|
-
} from "./constants/constants";
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
PERPLEXITY_API_KEY,
|
|
25
|
-
REVENIUM_METERING_API_KEY,
|
|
26
|
-
REVENIUM_METERING_BASE_URL,
|
|
27
|
-
PERPLEXITY_REQUIRED_API_KEY_MESSAGE,
|
|
28
|
-
PERPLEXITY_API_KEY_INVALID_MESSAGE,
|
|
29
|
-
LOG_LEVELS,
|
|
30
|
-
PERPLEXITY_METERING_API_KEY_IS_NOT_SET_MESSAGE,
|
|
31
|
-
PERPLEXITY_METERING_BASE_URL_IS_NOT_SET_MESSAGE,
|
|
32
|
-
PERPLEXITY_CLIENT_INITIALIZED_MESSAGE,
|
|
33
|
-
models,
|
|
34
|
-
PERPLEXITY_API_BASE_URL,
|
|
35
|
-
COST_TYPE,
|
|
36
|
-
MIDDLEWARE_SOURCE,
|
|
37
|
-
PRODUCT_ID_FREE,
|
|
38
|
-
CURRENT_CREDENTIAL,
|
|
39
|
-
};
|
package/src/utils/loadEnv.ts
DELETED
package/src/utils/safeExtract.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Safe extraction utility functions.
|
|
3
|
-
*/
|
|
4
|
-
export namespace safeExtract {
|
|
5
|
-
/**
|
|
6
|
-
* Safely extract a value from an object, returning undefined if the path doesn't exist.
|
|
7
|
-
*/
|
|
8
|
-
export function get<T>(
|
|
9
|
-
obj: any,
|
|
10
|
-
path: string,
|
|
11
|
-
defaultValue?: T
|
|
12
|
-
): T | undefined {
|
|
13
|
-
try {
|
|
14
|
-
const keys: string[] = path.split(".");
|
|
15
|
-
let result = obj;
|
|
16
|
-
|
|
17
|
-
for (const key of keys) {
|
|
18
|
-
if (result == null || typeof result !== "object") {
|
|
19
|
-
return defaultValue;
|
|
20
|
-
}
|
|
21
|
-
result = result[key];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return result ?? defaultValue;
|
|
25
|
-
} catch {
|
|
26
|
-
return defaultValue;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Safely extract a string value, returning empty string if not found.
|
|
32
|
-
*/
|
|
33
|
-
export function string(obj: any, path: string): string {
|
|
34
|
-
return get(obj, path, "") || "";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Safely extract a number value, returning 0 if not found.
|
|
39
|
-
*/
|
|
40
|
-
export function number(obj: any, path: string): number {
|
|
41
|
-
const value = get(obj, path, 0);
|
|
42
|
-
return typeof value === "number" ? value : 0;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Safely extract a boolean value, returning false if not found.
|
|
47
|
-
*/
|
|
48
|
-
export function boolean(obj: any, path: string): boolean {
|
|
49
|
-
return get(obj, path, false) || false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Safely extract an object value, returning empty object if not found.
|
|
54
|
-
*/
|
|
55
|
-
export function object(obj: any, path: string): Record<string, any> {
|
|
56
|
-
const value = get(obj, path, {});
|
|
57
|
-
return typeof value === "object" && value !== null ? value : {};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Safely extract an array value, returning empty array if not found.
|
|
62
|
-
*/
|
|
63
|
-
export function array(obj: any, path: string): any[] {
|
|
64
|
-
const value = get(obj, path, []);
|
|
65
|
-
return Array.isArray(value) ? value : [];
|
|
66
|
-
}
|
|
67
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"declaration": true,
|
|
5
|
-
"outDir": "dist",
|
|
6
|
-
"rootDir": "src",
|
|
7
|
-
"module": "CommonJS",
|
|
8
|
-
"target": "ES2019",
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"strict": true,
|
|
11
|
-
"skipLibCheck": true
|
|
12
|
-
},
|
|
13
|
-
"include": ["src"],
|
|
14
|
-
"exclude": ["node_modules", "dist"]
|
|
15
|
-
}
|