mirror of
https://github.com/praveentcom/openproxy.git
synced 2026-02-12 14:02:46 +00:00
feat: add UUID generation for request tracking and update PostgreSQL schema
This commit is contained in:
33
README.md
33
README.md
@@ -27,9 +27,7 @@ export const MODEL_COSTS: Record<string, CostConfig> = {
|
||||
|
||||
You can add more models to the `MODEL_COSTS` object to support your specific LLM providers.
|
||||
|
||||
## 📊 Database Table Schema
|
||||
|
||||
Before running the proxy, you need to create the table in the database.
|
||||
## 📊 PostgreSQL Table Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS <DATABASE_TABLE> (
|
||||
@@ -46,10 +44,19 @@ CREATE TABLE IF NOT EXISTS <DATABASE_TABLE> (
|
||||
request_body JSONB,
|
||||
response_body JSONB,
|
||||
response_status INTEGER,
|
||||
provider_url VARCHAR(500)
|
||||
provider_url VARCHAR(500),
|
||||
client_ip INET,
|
||||
user_agent TEXT,
|
||||
request_size INTEGER,
|
||||
response_size INTEGER,
|
||||
stream BOOLEAN,
|
||||
temperature REAL,
|
||||
max_tokens INTEGER,
|
||||
request_id UUID
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_<DATABASE_TABLE>_timestamp ON <DATABASE_TABLE> (timestamp);
|
||||
CREATE INDEX IF NOT EXISTS idx_<DATABASE_TABLE>_request_id ON <DATABASE_TABLE> (request_id);
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
@@ -124,24 +131,6 @@ The corresponding database entry will include:
|
||||
- Response time metrics
|
||||
- Complete request/response bodies for audit purposes
|
||||
|
||||
## 🔧 Advanced Features
|
||||
|
||||
### Custom Cost Models
|
||||
|
||||
Extend the `cost.ts` file to support your specific pricing models:
|
||||
|
||||
```typescript
|
||||
export const MODEL_COSTS: Record<string, CostConfig> = {
|
||||
"gpt-4": { input: 0.03, cached: 0.015, output: 0.06 },
|
||||
"claude-3": { input: 0.025, cached: 0.0125, output: 0.125 },
|
||||
"custom-model": { input: 0.01, cached: 0.005, output: 0.02 },
|
||||
};
|
||||
```
|
||||
|
||||
### Database Integration
|
||||
|
||||
The proxy automatically logs all requests to your PostgreSQL database with comprehensive metadata for analysis and reporting.
|
||||
|
||||
## 🛡️ Security
|
||||
|
||||
- Bearer token authentication required
|
||||
|
||||
24
package-lock.json
generated
24
package-lock.json
generated
@@ -7,9 +7,12 @@
|
||||
"": {
|
||||
"name": "llm-proxy-server",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/uuid": "^10.0.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"pg": "^8.16.3"
|
||||
"pg": "^8.16.3",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.8.1",
|
||||
@@ -124,6 +127,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
@@ -935,6 +944,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/uuid": "^10.0.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"pg": "^8.16.3"
|
||||
"pg": "^8.16.3",
|
||||
"uuid": "^13.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
15
proxy.ts
15
proxy.ts
@@ -6,6 +6,7 @@ import "dotenv/config";
|
||||
import http, { IncomingMessage, ServerResponse } from "http";
|
||||
import { TextDecoder } from "util";
|
||||
import { Pool } from "pg";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { calculateCost } from "./cost";
|
||||
|
||||
@@ -24,6 +25,10 @@ const pool = new Pool({
|
||||
});
|
||||
|
||||
// --- Helper functions ---
|
||||
function generateRequestId(): string {
|
||||
return uuidv4();
|
||||
}
|
||||
|
||||
function setCors(res: ServerResponse) {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, X-Requested-With");
|
||||
@@ -189,7 +194,15 @@ const server = http.createServer(async (req, res) => {
|
||||
request_body: requestJson,
|
||||
response_body: responseBody,
|
||||
response_status: upstreamRes.status,
|
||||
provider_url: UPSTREAM_URL
|
||||
provider_url: UPSTREAM_URL,
|
||||
client_ip: req.socket?.remoteAddress || null,
|
||||
user_agent: req.headers["user-agent"] || null,
|
||||
request_size: bodyBuf.length,
|
||||
response_size: Buffer.from(JSON.stringify(responseBody)).length,
|
||||
stream: contentType.includes("text/event-stream"),
|
||||
temperature: requestJson?.temperature || null,
|
||||
max_tokens: requestJson?.max_tokens || null,
|
||||
request_id: generateRequestId(),
|
||||
};
|
||||
|
||||
logToPG(logData).catch(err => console.error("PG log error:", err));
|
||||
|
||||
Reference in New Issue
Block a user