fortress-optimizer 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/README.md +185 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +129 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Fortress Token Optimizer - npm Package
|
|
2
|
+
|
|
3
|
+
Official npm package for integrating Fortress Token Optimizer into your Node.js applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @fortress-optimizer/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const { FortressClient } = require('@fortress-optimizer/core');
|
|
15
|
+
|
|
16
|
+
const client = new FortressClient(process.env.FORTRESS_API_KEY);
|
|
17
|
+
|
|
18
|
+
// Optimize a prompt
|
|
19
|
+
const result = await client.optimize(
|
|
20
|
+
'Your prompt here that could be optimized',
|
|
21
|
+
'balanced', // 'conservative', 'balanced', or 'aggressive'
|
|
22
|
+
'openai' // LLM provider
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
console.log(`Saved ${result.tokens.savings} tokens!`);
|
|
26
|
+
console.log(`Optimized: ${result.optimization.optimized_prompt}`);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- ✅ Real-time token optimization
|
|
32
|
+
- ✅ Support for all major LLM providers (OpenAI, Anthropic, Azure, Gemini, Groq, Ollama)
|
|
33
|
+
- ✅ Three optimization levels (conservative, balanced, aggressive)
|
|
34
|
+
- ✅ Token usage tracking
|
|
35
|
+
- ✅ Rate limiting and authentication
|
|
36
|
+
- ✅ TypeScript support
|
|
37
|
+
|
|
38
|
+
## API Reference
|
|
39
|
+
|
|
40
|
+
### `FortressClient`
|
|
41
|
+
|
|
42
|
+
#### Constructor
|
|
43
|
+
```javascript
|
|
44
|
+
new FortressClient(apiKey, options?)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Parameters:**
|
|
48
|
+
- `apiKey` (string): Your Fortress API key
|
|
49
|
+
- `options` (object, optional):
|
|
50
|
+
- `baseUrl` (string): API endpoint (default: `https://api.fortress-optimizer.com`)
|
|
51
|
+
- `timeout` (number): Request timeout in ms (default: 10000)
|
|
52
|
+
|
|
53
|
+
#### `optimize(prompt, level, provider)`
|
|
54
|
+
|
|
55
|
+
Optimize a prompt for token efficiency.
|
|
56
|
+
|
|
57
|
+
**Parameters:**
|
|
58
|
+
- `prompt` (string): The prompt to optimize (max 50,000 characters)
|
|
59
|
+
- `level` (string): 'conservative', 'balanced', or 'aggressive'
|
|
60
|
+
- `provider` (string): LLM provider name
|
|
61
|
+
|
|
62
|
+
**Returns:** Promise<OptimizationResult>
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
{
|
|
66
|
+
request_id: "opt_1707892834.123",
|
|
67
|
+
status: "success",
|
|
68
|
+
optimization: {
|
|
69
|
+
optimized_prompt: "Your optimized prompt...",
|
|
70
|
+
technique: "deduplication+compression"
|
|
71
|
+
},
|
|
72
|
+
tokens: {
|
|
73
|
+
original: 150,
|
|
74
|
+
optimized: 120,
|
|
75
|
+
savings: 30,
|
|
76
|
+
savings_percentage: 20.0
|
|
77
|
+
},
|
|
78
|
+
timestamp: "2026-02-13T14:30:45.123Z"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### `getUsage()`
|
|
83
|
+
|
|
84
|
+
Get token usage for your API key.
|
|
85
|
+
|
|
86
|
+
**Returns:** Promise<UsageStats>
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
{
|
|
90
|
+
tokens_used_this_month: 25000,
|
|
91
|
+
tokens_limit: 50000,
|
|
92
|
+
tokens_remaining: 25000,
|
|
93
|
+
percentage_used: 50,
|
|
94
|
+
reset_date: "2026-03-13T00:00:00Z"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `getProviders()`
|
|
99
|
+
|
|
100
|
+
Get list of supported LLM providers.
|
|
101
|
+
|
|
102
|
+
**Returns:** Promise<string[]>
|
|
103
|
+
|
|
104
|
+
#### `healthCheck()`
|
|
105
|
+
|
|
106
|
+
Check API availability.
|
|
107
|
+
|
|
108
|
+
**Returns:** Promise<boolean>
|
|
109
|
+
|
|
110
|
+
## Pricing
|
|
111
|
+
|
|
112
|
+
- **FREE**: 50,000 tokens/month
|
|
113
|
+
- **PRO**: $9.99/month (unlimited)
|
|
114
|
+
- **TEAM**: $99/month (collaboration features)
|
|
115
|
+
- **ENTERPRISE**: Custom pricing
|
|
116
|
+
|
|
117
|
+
See [fortress-optimizer.com/pricing](https://fortress-optimizer.com/pricing) for details.
|
|
118
|
+
|
|
119
|
+
## Examples
|
|
120
|
+
|
|
121
|
+
### Basic Usage
|
|
122
|
+
```javascript
|
|
123
|
+
const client = new FortressClient(process.env.FORTRESS_API_KEY);
|
|
124
|
+
|
|
125
|
+
const result = await client.optimize(
|
|
126
|
+
'Can you explain quantum computing in detail with examples?',
|
|
127
|
+
'balanced',
|
|
128
|
+
'openai'
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
console.log(result);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Batch Optimization
|
|
135
|
+
```javascript
|
|
136
|
+
const prompts = [
|
|
137
|
+
'First prompt...',
|
|
138
|
+
'Second prompt...',
|
|
139
|
+
'Third prompt...'
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const results = await Promise.all(
|
|
143
|
+
prompts.map(p => client.optimize(p, 'balanced', 'openai'))
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
results.forEach((r, i) => {
|
|
147
|
+
console.log(`Prompt ${i}: ${r.tokens.savings_percentage}% saved`);
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Error Handling
|
|
152
|
+
```javascript
|
|
153
|
+
try {
|
|
154
|
+
const result = await client.optimize(prompt, 'balanced', 'openai');
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (error.response?.status === 429) {
|
|
157
|
+
console.log('Rate limited - wait before retrying');
|
|
158
|
+
} else if (error.response?.status === 401) {
|
|
159
|
+
console.log('Invalid API key');
|
|
160
|
+
} else {
|
|
161
|
+
console.log('Optimization failed:', error.message);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Getting an API Key
|
|
167
|
+
|
|
168
|
+
1. Sign up at [fortress-optimizer.com](https://fortress-optimizer.com)
|
|
169
|
+
2. Navigate to API Keys
|
|
170
|
+
3. Create a new key
|
|
171
|
+
4. Use in your application
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
export FORTRESS_API_KEY="your-api-key-here"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Support
|
|
178
|
+
|
|
179
|
+
- 📖 Documentation: [docs.fortress-optimizer.com](https://docs.fortress-optimizer.com)
|
|
180
|
+
- 💬 Community: [Discord](https://discord.gg/fortress)
|
|
181
|
+
- 📧 Email: support@fortress-optimizer.com
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fortress Token Optimizer - npm Package
|
|
3
|
+
* Safe HTTP client wrapper around API
|
|
4
|
+
* Algorithm is backend-only (never exposed in client code)
|
|
5
|
+
*/
|
|
6
|
+
export interface OptimizationResult {
|
|
7
|
+
request_id: string;
|
|
8
|
+
status: 'success' | 'error' | 'rate_limited';
|
|
9
|
+
optimization: {
|
|
10
|
+
optimized_prompt: string;
|
|
11
|
+
technique: string;
|
|
12
|
+
};
|
|
13
|
+
tokens: {
|
|
14
|
+
original: number;
|
|
15
|
+
optimized: number;
|
|
16
|
+
savings: number;
|
|
17
|
+
savings_percentage: number;
|
|
18
|
+
};
|
|
19
|
+
timestamp: string;
|
|
20
|
+
}
|
|
21
|
+
export interface UsageStats {
|
|
22
|
+
tier: string;
|
|
23
|
+
tokens_optimized: number;
|
|
24
|
+
tokens_saved: number;
|
|
25
|
+
requests: number;
|
|
26
|
+
tokens_limit: number | 'unlimited';
|
|
27
|
+
tokens_remaining: number | 'unlimited';
|
|
28
|
+
rate_limit: {
|
|
29
|
+
requests_this_minute: number;
|
|
30
|
+
requests_this_day: number;
|
|
31
|
+
rpm_limit: number;
|
|
32
|
+
rpd_limit: number;
|
|
33
|
+
};
|
|
34
|
+
reset_date: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ClientOptions {
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
maxRetries?: number;
|
|
40
|
+
}
|
|
41
|
+
export declare class FortressClient {
|
|
42
|
+
private api;
|
|
43
|
+
private maxRetries;
|
|
44
|
+
constructor(apiKey: string, options?: ClientOptions);
|
|
45
|
+
optimize(prompt: string, level?: 'conservative' | 'balanced' | 'aggressive', provider?: string): Promise<OptimizationResult>;
|
|
46
|
+
getUsage(): Promise<UsageStats>;
|
|
47
|
+
getProviders(): Promise<string[]>;
|
|
48
|
+
healthCheck(): Promise<boolean>;
|
|
49
|
+
private withRetry;
|
|
50
|
+
private handleError;
|
|
51
|
+
}
|
|
52
|
+
export default FortressClient;
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;IAC7C,YAAY,EAAE;QACZ,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,gBAAgB,EAAE,MAAM,GAAG,WAAW,CAAC;IACvC,UAAU,EAAE;QACV,oBAAoB,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,GAAG,CAAgB;IAC3B,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAmBjD,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,cAAc,GAAG,UAAU,GAAG,YAAyB,EAC9D,QAAQ,GAAE,MAAiB,GAC1B,OAAO,CAAC,kBAAkB,CAAC;IAsCxB,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAO/B,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOjC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YASvB,SAAS;IAyBvB,OAAO,CAAC,WAAW;CAepB;AAED,eAAe,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fortress Token Optimizer - npm Package
|
|
4
|
+
* Safe HTTP client wrapper around API
|
|
5
|
+
* Algorithm is backend-only (never exposed in client code)
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.FortressClient = void 0;
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
class FortressClient {
|
|
14
|
+
constructor(apiKey, options = {}) {
|
|
15
|
+
const baseUrl = options.baseUrl || 'https://api.fortress-optimizer.com';
|
|
16
|
+
if (!baseUrl.startsWith('https://') && !baseUrl.startsWith('http://localhost')) {
|
|
17
|
+
throw new Error('Fortress API requires HTTPS. Use https:// URLs only.');
|
|
18
|
+
}
|
|
19
|
+
const timeout = options.timeout || 10000;
|
|
20
|
+
this.maxRetries = Math.min(options.maxRetries ?? 3, 10);
|
|
21
|
+
this.api = axios_1.default.create({
|
|
22
|
+
baseURL: baseUrl,
|
|
23
|
+
timeout,
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
26
|
+
'X-Client-Version': '1.0.0',
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async optimize(prompt, level = 'balanced', provider = 'openai') {
|
|
32
|
+
return this.withRetry(async () => {
|
|
33
|
+
const response = await this.api.post('/api/optimize', {
|
|
34
|
+
prompt,
|
|
35
|
+
level,
|
|
36
|
+
provider,
|
|
37
|
+
});
|
|
38
|
+
const result = response.data;
|
|
39
|
+
// Validate response integrity — defend against prompt injection
|
|
40
|
+
if (result.optimization?.optimized_prompt) {
|
|
41
|
+
const optimized = result.optimization.optimized_prompt;
|
|
42
|
+
const originalLen = prompt.length;
|
|
43
|
+
// Reject if optimized is significantly LONGER than original (injection likely)
|
|
44
|
+
if (optimized.length > originalLen * 2) {
|
|
45
|
+
throw new Error('Response validation failed: optimized prompt is suspiciously longer than original');
|
|
46
|
+
}
|
|
47
|
+
// Reject if it contains known injection patterns
|
|
48
|
+
const injectionPatterns = [
|
|
49
|
+
'ignore all previous',
|
|
50
|
+
'ignore the above',
|
|
51
|
+
'disregard prior',
|
|
52
|
+
'system prompt',
|
|
53
|
+
'you are now',
|
|
54
|
+
'new instructions:',
|
|
55
|
+
];
|
|
56
|
+
const lower = optimized.toLowerCase();
|
|
57
|
+
for (const pattern of injectionPatterns) {
|
|
58
|
+
if (lower.includes(pattern) && !prompt.toLowerCase().includes(pattern)) {
|
|
59
|
+
throw new Error('Response validation failed: optimized prompt contains suspicious content');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async getUsage() {
|
|
67
|
+
return this.withRetry(async () => {
|
|
68
|
+
const response = await this.api.get('/api/usage');
|
|
69
|
+
return response.data;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async getProviders() {
|
|
73
|
+
return this.withRetry(async () => {
|
|
74
|
+
const response = await this.api.get('/api/providers');
|
|
75
|
+
return response.data.providers;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async healthCheck() {
|
|
79
|
+
try {
|
|
80
|
+
const response = await this.api.get('/health', { timeout: 2000 });
|
|
81
|
+
return response.status === 200;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async withRetry(fn) {
|
|
88
|
+
let lastError;
|
|
89
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
90
|
+
try {
|
|
91
|
+
return await fn();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
const axiosErr = error;
|
|
95
|
+
// Don't retry auth errors or bad requests
|
|
96
|
+
if (axiosErr.response?.status === 401 || axiosErr.response?.status === 400) {
|
|
97
|
+
this.handleError(axiosErr);
|
|
98
|
+
}
|
|
99
|
+
lastError = error;
|
|
100
|
+
// Retry on 429 (rate limit) and 5xx with exponential backoff
|
|
101
|
+
if (attempt < this.maxRetries) {
|
|
102
|
+
const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
|
|
103
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (lastError && 'response' in lastError) {
|
|
108
|
+
this.handleError(lastError);
|
|
109
|
+
}
|
|
110
|
+
throw lastError || new Error('Request failed after retries');
|
|
111
|
+
}
|
|
112
|
+
handleError(error) {
|
|
113
|
+
if (error.response?.status === 401) {
|
|
114
|
+
throw new Error('Invalid API key');
|
|
115
|
+
}
|
|
116
|
+
if (error.response?.status === 429) {
|
|
117
|
+
throw new Error('Rate limited - please wait before retrying');
|
|
118
|
+
}
|
|
119
|
+
if (error.response?.status === 400) {
|
|
120
|
+
throw new Error(`Invalid request: ${error.response.data}`);
|
|
121
|
+
}
|
|
122
|
+
if (error.code === 'ECONNABORTED') {
|
|
123
|
+
throw new Error('Request timeout');
|
|
124
|
+
}
|
|
125
|
+
throw new Error(`API error: ${error.message}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.FortressClient = FortressClient;
|
|
129
|
+
exports.default = FortressClient;
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fortress-optimizer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fortress Token Optimizer - npm package for token optimization",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"lint": "eslint src/",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"tokens",
|
|
15
|
+
"optimization",
|
|
16
|
+
"llm",
|
|
17
|
+
"openai",
|
|
18
|
+
"anthropic",
|
|
19
|
+
"prompt-engineering"
|
|
20
|
+
],
|
|
21
|
+
"author": "Diawest82",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/Diawest82/fortress-optimizer-monorepo"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://fortress-optimizer.com",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"axios": "1.13.5",
|
|
34
|
+
"dotenv": "^16.3.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.10.0",
|
|
38
|
+
"typescript": "^5.3.3",
|
|
39
|
+
"jest": "^29.7.0",
|
|
40
|
+
"@types/jest": "^29.5.8",
|
|
41
|
+
"ts-jest": "^29.1.1",
|
|
42
|
+
"eslint": "^8.55.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|