@opencompress/opencompress 1.1.0 → 1.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/dist/index.js +60 -30
- package/openclaw.security.json +72 -0
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -34,12 +34,18 @@ var OPENCOMPRESS_MODELS = [
|
|
|
34
34
|
// Mistral
|
|
35
35
|
{ id: "mistralai/mistral-large-2411", name: "Mistral Large (Compressed)", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192 }
|
|
36
36
|
];
|
|
37
|
-
function buildProviderModels(baseUrl) {
|
|
38
|
-
|
|
37
|
+
function buildProviderModels(baseUrl, upstreamKey, upstreamBaseUrl) {
|
|
38
|
+
const config = {
|
|
39
39
|
baseUrl: `${baseUrl}/v1`,
|
|
40
40
|
api: "openai-completions",
|
|
41
41
|
models: OPENCOMPRESS_MODELS
|
|
42
42
|
};
|
|
43
|
+
if (upstreamKey || upstreamBaseUrl) {
|
|
44
|
+
config.headers = {};
|
|
45
|
+
if (upstreamKey) config.headers["X-Upstream-Key"] = upstreamKey;
|
|
46
|
+
if (upstreamBaseUrl) config.headers["X-Upstream-Base-Url"] = upstreamBaseUrl;
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
43
49
|
}
|
|
44
50
|
var opencompressProvider = {
|
|
45
51
|
id: "opencompress",
|
|
@@ -103,9 +109,11 @@ var plugin = {
|
|
|
103
109
|
version: VERSION,
|
|
104
110
|
async register(api) {
|
|
105
111
|
const baseUrl = api.pluginConfig?.baseUrl || DEFAULT_BASE_URL;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
const existingHeaders = api.config.models?.providers?.opencompress?.headers;
|
|
113
|
+
const existingUpstreamKey = existingHeaders?.["X-Upstream-Key"];
|
|
114
|
+
const existingUpstreamBaseUrl = existingHeaders?.["X-Upstream-Base-Url"];
|
|
115
|
+
const providerModels = buildProviderModels(baseUrl, existingUpstreamKey, existingUpstreamBaseUrl);
|
|
116
|
+
opencompressProvider.models = providerModels;
|
|
109
117
|
api.registerProvider(opencompressProvider);
|
|
110
118
|
if (!api.config.models) {
|
|
111
119
|
api.config.models = { providers: {} };
|
|
@@ -113,7 +121,7 @@ var plugin = {
|
|
|
113
121
|
if (!api.config.models.providers) {
|
|
114
122
|
api.config.models.providers = {};
|
|
115
123
|
}
|
|
116
|
-
api.config.models.providers.opencompress =
|
|
124
|
+
api.config.models.providers.opencompress = providerModels;
|
|
117
125
|
api.logger.info("OpenCompress provider registered (20 models, 5-layer compression)");
|
|
118
126
|
api.registerCommand({
|
|
119
127
|
name: "compress-stats",
|
|
@@ -175,10 +183,10 @@ var plugin = {
|
|
|
175
183
|
}
|
|
176
184
|
const upstreamKey = ctx.args?.trim();
|
|
177
185
|
if (!upstreamKey) {
|
|
178
|
-
const
|
|
186
|
+
const res = await fetch(`${baseUrl}/v1/topup`, {
|
|
179
187
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
180
188
|
});
|
|
181
|
-
const
|
|
189
|
+
const data = res.ok ? await res.json() : null;
|
|
182
190
|
return {
|
|
183
191
|
text: [
|
|
184
192
|
"**BYOK (Bring Your Own Key)**",
|
|
@@ -191,19 +199,23 @@ var plugin = {
|
|
|
191
199
|
" `/compress-byok sk-or-xxx` \u2014 Connect OpenRouter key",
|
|
192
200
|
" `/compress-byok off` \u2014 Switch back to router mode",
|
|
193
201
|
"",
|
|
194
|
-
|
|
202
|
+
data ? `**Balance:** $${data.balance.toFixed(2)}` : ""
|
|
195
203
|
].join("\n")
|
|
196
204
|
};
|
|
197
205
|
}
|
|
198
206
|
if (upstreamKey === "off" || upstreamKey === "disable" || upstreamKey === "router") {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
207
|
+
const cleanModels = buildProviderModels(baseUrl);
|
|
208
|
+
if (api.config.models?.providers) {
|
|
209
|
+
api.config.models.providers.opencompress = cleanModels;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
await fetch(`${baseUrl}/v1/byok`, {
|
|
213
|
+
method: "DELETE",
|
|
214
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
215
|
+
});
|
|
216
|
+
} catch {
|
|
205
217
|
}
|
|
206
|
-
return { text: "Switched back to **router mode**.
|
|
218
|
+
return { text: "Switched back to **router mode**. Your upstream key has been removed from local config." };
|
|
207
219
|
}
|
|
208
220
|
if (upstreamKey.startsWith("sk-occ-")) {
|
|
209
221
|
return { text: "That's an OpenCompress key. Provide your LLM provider key (OpenAI, Anthropic, etc.)." };
|
|
@@ -211,24 +223,42 @@ var plugin = {
|
|
|
211
223
|
if (upstreamKey.length < 10) {
|
|
212
224
|
return { text: "Key looks too short. Provide your full LLM API key." };
|
|
213
225
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
|
|
226
|
+
let provider = "unknown";
|
|
227
|
+
let upstreamBaseUrl = "";
|
|
228
|
+
if (upstreamKey.startsWith("sk-proj-") || upstreamKey.startsWith("sk-") && !upstreamKey.startsWith("sk-ant-") && !upstreamKey.startsWith("sk-or-")) {
|
|
229
|
+
provider = "openai";
|
|
230
|
+
upstreamBaseUrl = "https://api.openai.com/v1";
|
|
231
|
+
} else if (upstreamKey.startsWith("sk-ant-")) {
|
|
232
|
+
provider = "anthropic";
|
|
233
|
+
upstreamBaseUrl = "https://api.anthropic.com/v1";
|
|
234
|
+
} else if (upstreamKey.startsWith("sk-or-")) {
|
|
235
|
+
provider = "openrouter";
|
|
236
|
+
upstreamBaseUrl = "https://openrouter.ai/api/v1";
|
|
237
|
+
} else if (upstreamKey.startsWith("AIza")) {
|
|
238
|
+
provider = "google";
|
|
239
|
+
upstreamBaseUrl = "https://generativelanguage.googleapis.com/v1beta/openai";
|
|
240
|
+
}
|
|
241
|
+
const updatedModels = buildProviderModels(baseUrl, upstreamKey, upstreamBaseUrl);
|
|
242
|
+
if (api.config.models?.providers) {
|
|
243
|
+
api.config.models.providers.opencompress = updatedModels;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
await fetch(`${baseUrl}/v1/byok`, {
|
|
247
|
+
method: "POST",
|
|
248
|
+
headers: {
|
|
249
|
+
Authorization: `Bearer ${apiKey}`,
|
|
250
|
+
"Content-Type": "application/json"
|
|
251
|
+
},
|
|
252
|
+
body: JSON.stringify({ provider, passthrough: true })
|
|
253
|
+
});
|
|
254
|
+
} catch {
|
|
225
255
|
}
|
|
226
|
-
const data = await res.json();
|
|
227
256
|
return {
|
|
228
257
|
text: [
|
|
229
|
-
`Switched to **BYOK mode** (${
|
|
258
|
+
`Switched to **BYOK mode** (${provider}).`,
|
|
230
259
|
"",
|
|
231
|
-
|
|
260
|
+
"Your key is stored **locally only** \u2014 never sent to our server for storage.",
|
|
261
|
+
"It's passed through on each request via header and discarded immediately.",
|
|
232
262
|
"",
|
|
233
263
|
"To switch back: `/compress-byok off`"
|
|
234
264
|
].join("\n")
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "opencompress",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"securityProfile": {
|
|
5
|
+
"dataHandling": {
|
|
6
|
+
"promptContent": "pass-through",
|
|
7
|
+
"promptStorage": "none",
|
|
8
|
+
"responseContent": "pass-through",
|
|
9
|
+
"responseStorage": "none",
|
|
10
|
+
"upstreamApiKeys": "local-only",
|
|
11
|
+
"upstreamApiKeyStorage": "never-server-side"
|
|
12
|
+
},
|
|
13
|
+
"networkAccess": {
|
|
14
|
+
"outbound": [
|
|
15
|
+
{
|
|
16
|
+
"host": "www.opencompress.ai",
|
|
17
|
+
"port": 443,
|
|
18
|
+
"protocol": "https",
|
|
19
|
+
"purpose": "API proxy — compress prompts and forward to upstream LLM provider"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"inbound": []
|
|
23
|
+
},
|
|
24
|
+
"localStorage": {
|
|
25
|
+
"authProfiles": {
|
|
26
|
+
"path": "~/.openclaw/agents/*/agent/auth-profiles.json",
|
|
27
|
+
"content": "OpenCompress API key (sk-occ-*)",
|
|
28
|
+
"sensitive": true
|
|
29
|
+
},
|
|
30
|
+
"providerConfig": {
|
|
31
|
+
"path": "~/.openclaw/openclaw.json",
|
|
32
|
+
"content": "Provider config, optional upstream key in headers (BYOK pass-through)",
|
|
33
|
+
"sensitive": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"secrets": {
|
|
37
|
+
"required": [
|
|
38
|
+
{
|
|
39
|
+
"name": "OpenCompress API Key",
|
|
40
|
+
"format": "sk-occ-*",
|
|
41
|
+
"purpose": "Authentication and billing for compression service",
|
|
42
|
+
"serverSideStorage": "hashed (SHA-256), never plaintext"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"optional": [
|
|
46
|
+
{
|
|
47
|
+
"name": "Upstream LLM API Key",
|
|
48
|
+
"format": "sk-proj-* / sk-ant-* / sk-or-* / AIza*",
|
|
49
|
+
"purpose": "BYOK mode — forwarded to user's LLM provider",
|
|
50
|
+
"serverSideStorage": "NEVER stored. Passed via X-Upstream-Key header per-request, discarded after forwarding."
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"permissions": {
|
|
55
|
+
"fileSystem": "read/write ~/.openclaw/ config files only",
|
|
56
|
+
"environment": ["OPENCOMPRESS_API_KEY", "OPENCOMPRESS_LLM_KEY"],
|
|
57
|
+
"shell": "none",
|
|
58
|
+
"network": "outbound HTTPS to www.opencompress.ai only"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"privacyPolicy": {
|
|
62
|
+
"promptsAndResponses": "OpenCompress compresses prompts in-memory and forwards to the upstream LLM provider. Prompt and response content is NEVER stored, logged, or used for training. Only token counts are recorded for billing.",
|
|
63
|
+
"apiKeys": "Your upstream LLM API key (OpenAI, Anthropic, etc.) is stored ONLY on your local machine. It is sent to our server as a per-request header (X-Upstream-Key) and discarded immediately after forwarding. We never persist your upstream keys.",
|
|
64
|
+
"billing": "We record: timestamp, model, original token count, compressed token count, cost. We do NOT record prompt content.",
|
|
65
|
+
"thirdParties": "We do not share any data with third parties. Your requests are forwarded only to the LLM provider you specify."
|
|
66
|
+
},
|
|
67
|
+
"auditability": {
|
|
68
|
+
"pluginSource": "Open source — https://github.com/claw-compactor/openclaw-plugin",
|
|
69
|
+
"serverSource": "Forwarding logic documented in security docs. Core proxy is open for audit.",
|
|
70
|
+
"verification": "Users can inspect all network requests via OpenClaw's diagnostics plugin or standard proxy tools."
|
|
71
|
+
}
|
|
72
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opencompress/opencompress",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "OpenCompress plugin for OpenClaw — automatic 5-layer prompt compression for any LLM",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"dist",
|
|
21
|
-
"openclaw.plugin.json"
|
|
21
|
+
"openclaw.plugin.json",
|
|
22
|
+
"openclaw.security.json"
|
|
22
23
|
],
|
|
23
24
|
"keywords": [
|
|
24
25
|
"openclaw",
|