@relayplane/proxy 0.1.9 → 0.2.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 +113 -247
- package/__tests__/server.test.ts +512 -0
- package/__tests__/telemetry.test.ts +126 -0
- package/dist/cli.d.ts +35 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +262 -3024
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +80 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +208 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +25 -1130
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -3005
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +209 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1089 -0
- package/dist/server.js.map +1 -0
- package/dist/streaming.d.ts +80 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +271 -0
- package/dist/streaming.js.map +1 -0
- package/dist/telemetry.d.ts +111 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +315 -0
- package/dist/telemetry.js.map +1 -0
- package/package.json +21 -46
- package/src/cli.ts +341 -0
- package/src/config.ts +206 -0
- package/src/index.ts +82 -0
- package/src/server.ts +1328 -0
- package/src/streaming.ts +331 -0
- package/src/telemetry.ts +343 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +21 -0
- package/LICENSE +0 -21
- package/dist/cli.d.mts +0 -1
- package/dist/cli.mjs +0 -3043
- package/dist/cli.mjs.map +0 -1
- package/dist/index.d.mts +0 -1141
- package/dist/index.mjs +0 -2948
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,319 +1,185 @@
|
|
|
1
1
|
# @relayplane/proxy
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Intelligent AI model routing proxy for cost optimization and observability.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://github.com/RelayPlane/proxy/actions/workflows/ci.yml)
|
|
8
|
-
[](https://www.npmjs.com/package/@relayplane/proxy)
|
|
9
|
-
[](https://opensource.org/licenses/MIT)
|
|
10
|
-
|
|
11
|
-
## Install
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install @relayplane/proxy
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Or run directly:
|
|
5
|
+
## Installation
|
|
18
6
|
|
|
19
7
|
```bash
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## CLI Commands
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Start the proxy server
|
|
27
|
-
npx @relayplane/proxy
|
|
28
|
-
|
|
29
|
-
# Start on custom port
|
|
30
|
-
npx @relayplane/proxy --port 8080
|
|
31
|
-
|
|
32
|
-
# View routing statistics
|
|
33
|
-
npx @relayplane/proxy stats
|
|
34
|
-
|
|
35
|
-
# View stats for last 30 days
|
|
36
|
-
npx @relayplane/proxy stats --days 30
|
|
37
|
-
|
|
38
|
-
# Show help
|
|
39
|
-
npx @relayplane/proxy --help
|
|
8
|
+
npm install -g @relayplane/proxy
|
|
40
9
|
```
|
|
41
10
|
|
|
42
11
|
## Quick Start
|
|
43
12
|
|
|
44
|
-
### 1. Set your API keys
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
48
|
-
export OPENAI_API_KEY="sk-..."
|
|
49
|
-
# Optional: GEMINI_API_KEY, XAI_API_KEY, MOONSHOT_API_KEY
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 2. Start the proxy
|
|
53
|
-
|
|
54
13
|
```bash
|
|
55
|
-
|
|
56
|
-
|
|
14
|
+
# Set your API keys
|
|
15
|
+
export ANTHROPIC_API_KEY=your-key
|
|
16
|
+
export OPENAI_API_KEY=your-key
|
|
57
17
|
|
|
58
|
-
|
|
18
|
+
# Start the proxy
|
|
19
|
+
relayplane-proxy
|
|
59
20
|
|
|
60
|
-
|
|
21
|
+
# Configure your tools to use the proxy
|
|
61
22
|
export ANTHROPIC_BASE_URL=http://localhost:3001
|
|
62
23
|
export OPENAI_BASE_URL=http://localhost:3001
|
|
63
24
|
|
|
64
|
-
#
|
|
65
|
-
openclaw
|
|
25
|
+
# Run your AI tools (Claude Code, Cursor, Aider, etc.)
|
|
66
26
|
```
|
|
67
27
|
|
|
68
|
-
|
|
28
|
+
## Features
|
|
69
29
|
|
|
70
|
-
|
|
30
|
+
- **Intelligent Routing**: Routes requests to the optimal model based on task type
|
|
31
|
+
- **Cost Tracking**: Tracks and reports API costs across all providers
|
|
32
|
+
- **Provider Agnostic**: Works with Anthropic, OpenAI, Gemini, xAI, and more
|
|
33
|
+
- **Local Learning**: Learns from your usage patterns to improve routing
|
|
34
|
+
- **Privacy First**: Never sees your prompts or responses
|
|
71
35
|
|
|
72
|
-
|
|
73
|
-
Your Tool (OpenClaw, Cursor, etc.)
|
|
74
|
-
│
|
|
75
|
-
▼
|
|
76
|
-
RelayPlane Proxy
|
|
77
|
-
├── Infers task type (code_review, analysis, etc.)
|
|
78
|
-
├── Checks routing rules
|
|
79
|
-
├── Selects optimal model (Haiku for simple, Opus for complex)
|
|
80
|
-
├── Tracks outcomes (success/failure/latency)
|
|
81
|
-
└── Learns patterns → improves over time
|
|
82
|
-
│
|
|
83
|
-
▼
|
|
84
|
-
Provider (Anthropic, OpenAI, etc.)
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Learning & Adaptation
|
|
88
|
-
|
|
89
|
-
RelayPlane doesn't just route — it **learns from every request**:
|
|
90
|
-
|
|
91
|
-
- **Outcome Tracking** — Records success/failure for each route decision
|
|
92
|
-
- **Pattern Detection** — Identifies what works for your specific codebase
|
|
93
|
-
- **Continuous Improvement** — Routing gets smarter the more you use it
|
|
94
|
-
- **Local Intelligence** — All learning happens in your local SQLite DB
|
|
36
|
+
## CLI Options
|
|
95
37
|
|
|
96
38
|
```bash
|
|
97
|
-
|
|
98
|
-
npx @relayplane/proxy stats
|
|
39
|
+
relayplane-proxy [command] [options]
|
|
99
40
|
|
|
100
|
-
|
|
101
|
-
|
|
41
|
+
Commands:
|
|
42
|
+
(default) Start the proxy server
|
|
43
|
+
telemetry [on|off|status] Manage telemetry settings
|
|
44
|
+
stats Show usage statistics
|
|
45
|
+
config Show configuration
|
|
102
46
|
|
|
103
|
-
|
|
104
|
-
|
|
47
|
+
Options:
|
|
48
|
+
--port <number> Port to listen on (default: 3001)
|
|
49
|
+
--host <string> Host to bind to (default: 127.0.0.1)
|
|
50
|
+
--offline Disable all network calls except LLM endpoints
|
|
51
|
+
--audit Show telemetry payloads before sending
|
|
52
|
+
-v, --verbose Enable verbose logging
|
|
53
|
+
-h, --help Show this help message
|
|
54
|
+
--version Show version
|
|
105
55
|
```
|
|
106
56
|
|
|
107
|
-
|
|
57
|
+
## Telemetry
|
|
108
58
|
|
|
109
|
-
|
|
59
|
+
RelayPlane collects anonymous telemetry to improve model routing. This data helps us understand usage patterns and optimize routing decisions.
|
|
110
60
|
|
|
111
|
-
|
|
112
|
-
|----------|--------|-----------|-------|
|
|
113
|
-
| **Anthropic** | Claude 4.5 (Opus, Sonnet, Haiku) | ✓ | ✓ |
|
|
114
|
-
| **OpenAI** | GPT-5.2, GPT-5.2-Codex, o1, o3 | ✓ | ✓ |
|
|
115
|
-
| **Google** | Gemini 2.0 Flash, 2.0 Pro | ✓ | ✓ |
|
|
116
|
-
| **xAI** | Grok-3, Grok-3-mini | ✓ | ✓ |
|
|
117
|
-
| **Moonshot** | v1-8k, v1-32k, v1-128k | ✓ | ✓ |
|
|
61
|
+
### What We Collect (Exact Schema)
|
|
118
62
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
| Without RelayPlane | With RelayPlane |
|
|
132
|
-
|-------------------|-----------------|
|
|
133
|
-
| Pay Opus token rates for simple tasks | Route simple tasks to Haiku (1/10 the cost) |
|
|
134
|
-
| Static model selection | Learns from outcomes over time |
|
|
135
|
-
| Manual optimization | Automatic cost-quality balance |
|
|
136
|
-
| No visibility into spend | Built-in savings tracking |
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"device_id": "anon_8f3a...",
|
|
66
|
+
"task_type": "code_review",
|
|
67
|
+
"model": "claude-3-5-haiku",
|
|
68
|
+
"tokens_in": 1847,
|
|
69
|
+
"tokens_out": 423,
|
|
70
|
+
"latency_ms": 2341,
|
|
71
|
+
"success": true,
|
|
72
|
+
"cost_usd": 0.02
|
|
73
|
+
}
|
|
74
|
+
```
|
|
137
75
|
|
|
138
|
-
|
|
76
|
+
### Field Descriptions
|
|
139
77
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
78
|
+
| Field | Type | Description |
|
|
79
|
+
|-------|------|-------------|
|
|
80
|
+
| `device_id` | string | Anonymous random ID (not fingerprintable) |
|
|
81
|
+
| `task_type` | string | Inferred from token patterns, NOT prompt content |
|
|
82
|
+
| `model` | string | The model that handled the request |
|
|
83
|
+
| `tokens_in` | number | Input token count |
|
|
84
|
+
| `tokens_out` | number | Output token count |
|
|
85
|
+
| `latency_ms` | number | Request latency in milliseconds |
|
|
86
|
+
| `success` | boolean | Whether the request succeeded |
|
|
87
|
+
| `cost_usd` | number | Estimated cost in USD |
|
|
145
88
|
|
|
146
|
-
|
|
89
|
+
### Task Types
|
|
147
90
|
|
|
148
|
-
|
|
149
|
-
import { startProxy, RelayPlane, calculateSavings } from '@relayplane/proxy';
|
|
91
|
+
Task types are inferred from request characteristics (token counts, ratios, etc.) - never from prompt content:
|
|
150
92
|
|
|
151
|
-
|
|
152
|
-
|
|
93
|
+
- `quick_task` - Short input/output (< 500 tokens each)
|
|
94
|
+
- `code_review` - Medium-long input, medium output
|
|
95
|
+
- `generation` - High output/input ratio
|
|
96
|
+
- `classification` - Low output/input ratio, short output
|
|
97
|
+
- `long_context` - Input > 10,000 tokens
|
|
98
|
+
- `content_generation` - Output > 1,000 tokens
|
|
99
|
+
- `tool_use` - Request includes tool calls
|
|
100
|
+
- `general` - Default classification
|
|
153
101
|
|
|
154
|
-
|
|
155
|
-
const relay = new RelayPlane({});
|
|
156
|
-
const result = await relay.run({ prompt: 'Review this code...' });
|
|
157
|
-
console.log(result.taskType); // 'code_review'
|
|
158
|
-
console.log(result.model); // 'anthropic:claude-3-5-haiku-latest'
|
|
102
|
+
### What We NEVER Collect
|
|
159
103
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
104
|
+
- ❌ Your prompts
|
|
105
|
+
- ❌ Model responses
|
|
106
|
+
- ❌ File paths or contents
|
|
107
|
+
- ❌ Anything that could identify you or your project
|
|
163
108
|
|
|
164
|
-
|
|
165
|
-
```
|
|
109
|
+
### Verification
|
|
166
110
|
|
|
167
|
-
|
|
111
|
+
You can verify exactly what data is collected:
|
|
168
112
|
|
|
169
113
|
```bash
|
|
170
|
-
|
|
114
|
+
# See telemetry payloads before they're sent
|
|
115
|
+
relayplane-proxy --audit
|
|
171
116
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
--host <string> Host to bind to (default: 127.0.0.1)
|
|
175
|
-
-v, --verbose Enable verbose logging
|
|
176
|
-
-h, --help Show help
|
|
177
|
-
```
|
|
117
|
+
# Disable all telemetry transmission
|
|
118
|
+
relayplane-proxy --offline
|
|
178
119
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
120
|
+
# View the source code
|
|
121
|
+
# https://github.com/RelayPlane/proxy
|
|
122
|
+
```
|
|
182
123
|
|
|
183
|
-
###
|
|
124
|
+
### Opt-Out
|
|
184
125
|
|
|
185
|
-
|
|
126
|
+
To disable telemetry completely:
|
|
186
127
|
|
|
187
128
|
```bash
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"status": "ok",
|
|
194
|
-
"version": "0.1.7",
|
|
195
|
-
"uptime": "2h 15m 30s",
|
|
196
|
-
"providers": { "anthropic": true, "openai": true, "google": false },
|
|
197
|
-
"totalRuns": 142
|
|
198
|
-
}
|
|
129
|
+
relayplane-proxy telemetry off
|
|
199
130
|
```
|
|
200
131
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
Aggregated statistics and cost savings.
|
|
132
|
+
To re-enable:
|
|
204
133
|
|
|
205
134
|
```bash
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
```json
|
|
210
|
-
{
|
|
211
|
-
"totalRuns": 142,
|
|
212
|
-
"savings": {
|
|
213
|
-
"estimatedSavingsPercent": "73.2%",
|
|
214
|
-
"actualCostUsd": "0.0234",
|
|
215
|
-
"baselineCostUsd": "0.0873",
|
|
216
|
-
"savedUsd": "0.0639"
|
|
217
|
-
},
|
|
218
|
-
"modelDistribution": {
|
|
219
|
-
"anthropic/claude-3-5-haiku-latest": { "count": 98, "percentage": "69.0%" },
|
|
220
|
-
"anthropic/claude-sonnet-4-20250514": { "count": 44, "percentage": "31.0%" }
|
|
221
|
-
}
|
|
222
|
-
}
|
|
135
|
+
relayplane-proxy telemetry on
|
|
223
136
|
```
|
|
224
137
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Recent routing decisions.
|
|
138
|
+
Check current status:
|
|
228
139
|
|
|
229
140
|
```bash
|
|
230
|
-
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
```json
|
|
234
|
-
{
|
|
235
|
-
"runs": [
|
|
236
|
-
{
|
|
237
|
-
"runId": "abc123",
|
|
238
|
-
"timestamp": "2026-02-03T13:26:03Z",
|
|
239
|
-
"model": "anthropic/claude-3-5-haiku-latest",
|
|
240
|
-
"taskType": "code_generation",
|
|
241
|
-
"confidence": 0.92,
|
|
242
|
-
"mode": "auto",
|
|
243
|
-
"durationMs": 1203,
|
|
244
|
-
"promptPreview": "Write a function that..."
|
|
245
|
-
}
|
|
246
|
-
],
|
|
247
|
-
"total": 142
|
|
248
|
-
}
|
|
141
|
+
relayplane-proxy telemetry status
|
|
249
142
|
```
|
|
250
143
|
|
|
251
144
|
## Configuration
|
|
252
145
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
```json
|
|
256
|
-
{
|
|
257
|
-
"strategies": {
|
|
258
|
-
"code_review": { "model": "anthropic:claude-sonnet-4-20250514" },
|
|
259
|
-
"code_generation": { "model": "anthropic:claude-3-5-haiku-latest" },
|
|
260
|
-
"analysis": { "model": "anthropic:claude-sonnet-4-20250514" },
|
|
261
|
-
"summarization": { "model": "anthropic:claude-3-5-haiku-latest" },
|
|
262
|
-
"creative_writing": { "model": "anthropic:claude-sonnet-4-20250514" },
|
|
263
|
-
"data_extraction": { "model": "anthropic:claude-3-5-haiku-latest" },
|
|
264
|
-
"translation": { "model": "anthropic:claude-3-5-haiku-latest" },
|
|
265
|
-
"question_answering": { "model": "anthropic:claude-3-5-haiku-latest" },
|
|
266
|
-
"general": { "model": "anthropic:claude-3-5-haiku-latest" }
|
|
267
|
-
},
|
|
268
|
-
"defaults": {
|
|
269
|
-
"qualityModel": "claude-sonnet-4-20250514",
|
|
270
|
-
"costModel": "claude-3-5-haiku-latest"
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Edit and save — changes apply instantly** (hot-reload, no restart needed).
|
|
146
|
+
Configuration is stored in `~/.relayplane/config.json`.
|
|
276
147
|
|
|
277
|
-
###
|
|
148
|
+
### Set API Key (Pro Features)
|
|
278
149
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
| `model` | Provider and model in format `provider:model` |
|
|
282
|
-
| `minConfidence` | Optional. Only use this strategy if confidence >= threshold |
|
|
283
|
-
| `fallback` | Optional. Fallback model if primary fails |
|
|
284
|
-
|
|
285
|
-
### Examples
|
|
286
|
-
|
|
287
|
-
Route all analysis tasks to GPT-4o:
|
|
288
|
-
```json
|
|
289
|
-
"analysis": { "model": "openai:gpt-4o" }
|
|
150
|
+
```bash
|
|
151
|
+
relayplane-proxy config set-key your-api-key
|
|
290
152
|
```
|
|
291
153
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
"fallback": "anthropic:claude-sonnet-4-20250514"
|
|
297
|
-
}
|
|
154
|
+
### View Configuration
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
relayplane-proxy config
|
|
298
158
|
```
|
|
299
159
|
|
|
300
|
-
##
|
|
160
|
+
## Usage Statistics
|
|
301
161
|
|
|
302
|
-
|
|
162
|
+
View your usage statistics:
|
|
303
163
|
|
|
304
164
|
```bash
|
|
305
|
-
|
|
306
|
-
sqlite3 ~/.relayplane/data.db "SELECT * FROM runs ORDER BY created_at DESC LIMIT 10"
|
|
307
|
-
|
|
308
|
-
# Check routing rules
|
|
309
|
-
sqlite3 ~/.relayplane/data.db "SELECT * FROM routing_rules"
|
|
165
|
+
relayplane-proxy stats
|
|
310
166
|
```
|
|
311
167
|
|
|
312
|
-
|
|
168
|
+
This shows:
|
|
169
|
+
- Total requests and cost
|
|
170
|
+
- Success rate
|
|
171
|
+
- Breakdown by model
|
|
172
|
+
- Breakdown by task type
|
|
173
|
+
|
|
174
|
+
## Environment Variables
|
|
313
175
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
176
|
+
| Variable | Description |
|
|
177
|
+
|----------|-------------|
|
|
178
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key |
|
|
179
|
+
| `OPENAI_API_KEY` | OpenAI API key |
|
|
180
|
+
| `GEMINI_API_KEY` | Google Gemini API key |
|
|
181
|
+
| `XAI_API_KEY` | xAI/Grok API key |
|
|
182
|
+
| `MOONSHOT_API_KEY` | Moonshot API key |
|
|
317
183
|
|
|
318
184
|
## License
|
|
319
185
|
|