@opencompress/opencompress 1.4.0 → 1.5.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.
Files changed (2) hide show
  1. package/dist/index.js +36 -63
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -17,48 +17,26 @@ var FALLBACK_MODELS = [
17
17
  { id: "deepseek/deepseek-chat-v3-0324", name: "DeepSeek V3", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192 },
18
18
  { id: "deepseek/deepseek-reasoner", name: "DeepSeek Reasoner", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192 }
19
19
  ];
20
- function upstreamToModels(data) {
21
- return data.map((m) => {
22
- const promptPrice = m.pricing?.prompt ? parseFloat(m.pricing.prompt) * 1e6 : 0;
23
- const completionPrice = m.pricing?.completion ? parseFloat(m.pricing.completion) * 1e6 : 0;
24
- const isReasoning = /\bo[34]\b|reasoner|thinking|deepthink/i.test(m.id);
25
- const inputMods = ["text"];
26
- const archInputs = m.architecture?.input_modalities || [];
27
- if (archInputs.includes("image") || /vision|4o|gemini|claude-.*[34]/i.test(m.id)) {
28
- inputMods.push("image");
20
+ function readExistingModels(api) {
21
+ const providers = api.config.models?.providers;
22
+ if (!providers) return null;
23
+ const seen = /* @__PURE__ */ new Set();
24
+ const models = [];
25
+ for (const [providerId, providerConfig] of Object.entries(providers)) {
26
+ if (providerId === "opencompress") continue;
27
+ const providerModels = providerConfig.models || [];
28
+ for (const m of providerModels) {
29
+ if (m.name?.includes("\u2192")) continue;
30
+ if (seen.has(m.id)) continue;
31
+ seen.add(m.id);
32
+ models.push({
33
+ ...m,
34
+ // Zero out cost — billing handled by OpenCompress proxy
35
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }
36
+ });
29
37
  }
30
- return {
31
- id: m.id,
32
- name: m.id,
33
- reasoning: isReasoning,
34
- input: inputMods,
35
- cost: {
36
- input: promptPrice,
37
- output: completionPrice,
38
- cacheRead: 0,
39
- cacheWrite: 0
40
- },
41
- contextWindow: m.context_length || 128e3,
42
- maxTokens: Math.min(m.context_length || 128e3, 65536)
43
- };
44
- });
45
- }
46
- async function fetchUpstreamModels(baseUrl, apiKey, upstreamKey, upstreamBaseUrl) {
47
- try {
48
- const headers = {
49
- Authorization: `Bearer ${apiKey}`
50
- };
51
- if (upstreamKey) headers["X-Upstream-Key"] = upstreamKey;
52
- if (upstreamBaseUrl) headers["X-Upstream-Base-Url"] = upstreamBaseUrl;
53
- const res = await fetch(`${baseUrl}/v1/models`, { headers });
54
- if (!res.ok) return null;
55
- const data = await res.json();
56
- const models = data.data || [];
57
- if (models.length === 0) return null;
58
- return upstreamToModels(models);
59
- } catch {
60
- return null;
61
38
  }
39
+ return models.length > 0 ? models : null;
62
40
  }
63
41
  function buildProviderModels(baseUrl, upstreamKey, upstreamBaseUrl, models) {
64
42
  const config = {
@@ -141,8 +119,7 @@ var opencompressProvider = {
141
119
  });
142
120
  } catch {
143
121
  }
144
- const upstreamModels = await fetchUpstreamModels(DEFAULT_BASE_URL, data.apiKey, llmKey, upstreamBaseUrl);
145
- const modelCount = upstreamModels ? upstreamModels.length : FALLBACK_MODELS.length;
122
+ const modelCount = FALLBACK_MODELS.length;
146
123
  return {
147
124
  profiles: [
148
125
  {
@@ -153,7 +130,7 @@ var opencompressProvider = {
153
130
  configPatch: {
154
131
  models: {
155
132
  providers: {
156
- opencompress: buildProviderModels(DEFAULT_BASE_URL, llmKey, upstreamBaseUrl, upstreamModels || void 0)
133
+ opencompress: buildProviderModels(DEFAULT_BASE_URL, llmKey, upstreamBaseUrl)
157
134
  }
158
135
  }
159
136
  },
@@ -182,12 +159,8 @@ var plugin = {
182
159
  const existingHeaders = api.config.models?.providers?.opencompress?.headers;
183
160
  const existingUpstreamKey = existingHeaders?.["X-Upstream-Key"];
184
161
  const existingUpstreamBaseUrl = existingHeaders?.["X-Upstream-Base-Url"];
185
- const apiKey = getApiKey(api);
186
- let dynamicModels = null;
187
- if (apiKey && existingUpstreamKey) {
188
- dynamicModels = await fetchUpstreamModels(baseUrl, apiKey, existingUpstreamKey, existingUpstreamBaseUrl);
189
- }
190
- const providerModels = buildProviderModels(baseUrl, existingUpstreamKey, existingUpstreamBaseUrl, dynamicModels || void 0);
162
+ const existingModels = readExistingModels(api);
163
+ const providerModels = buildProviderModels(baseUrl, existingUpstreamKey, existingUpstreamBaseUrl, existingModels || void 0);
191
164
  opencompressProvider.models = providerModels;
192
165
  api.registerProvider(opencompressProvider);
193
166
  if (!api.config.models) {
@@ -197,24 +170,24 @@ var plugin = {
197
170
  api.config.models.providers = {};
198
171
  }
199
172
  api.config.models.providers.opencompress = providerModels;
200
- const modelCount = dynamicModels ? dynamicModels.length : FALLBACK_MODELS.length;
201
- const source = dynamicModels ? "upstream" : "fallback";
202
- api.logger.info(`OpenCompress provider registered (${modelCount} ${source} models, 5-layer compression)`);
173
+ const modelCount = existingModels ? existingModels.length : FALLBACK_MODELS.length;
174
+ const source = existingModels ? "from existing providers" : "fallback";
175
+ api.logger.info(`OpenCompress provider registered (${modelCount} models ${source}, 5-layer compression)`);
203
176
  api.registerCommand({
204
177
  name: "compress-stats",
205
178
  description: "Show OpenCompress usage statistics and savings",
206
179
  acceptsArgs: true,
207
180
  requireAuth: false,
208
181
  handler: async () => {
209
- const apiKey2 = getApiKey(api);
210
- if (!apiKey2) {
182
+ const apiKey = getApiKey(api);
183
+ if (!apiKey) {
211
184
  return {
212
185
  text: "No API key found. Run `openclaw onboard opencompress` to set up."
213
186
  };
214
187
  }
215
188
  try {
216
189
  const res = await fetch(`${baseUrl}/user/stats`, {
217
- headers: { Authorization: `Bearer ${apiKey2}` }
190
+ headers: { Authorization: `Bearer ${apiKey}` }
218
191
  });
219
192
  if (!res.ok) {
220
193
  return { text: `Failed to fetch stats: HTTP ${res.status}` };
@@ -254,14 +227,14 @@ var plugin = {
254
227
  acceptsArgs: true,
255
228
  requireAuth: false,
256
229
  handler: async (ctx) => {
257
- const apiKey2 = getApiKey(api);
258
- if (!apiKey2) {
230
+ const apiKey = getApiKey(api);
231
+ if (!apiKey) {
259
232
  return { text: "Not set up. Run `openclaw onboard opencompress` first." };
260
233
  }
261
234
  const upstreamKey = ctx.args?.trim();
262
235
  if (!upstreamKey) {
263
236
  const res = await fetch(`${baseUrl}/v1/topup`, {
264
- headers: { Authorization: `Bearer ${apiKey2}` }
237
+ headers: { Authorization: `Bearer ${apiKey}` }
265
238
  });
266
239
  const data = res.ok ? await res.json() : null;
267
240
  return {
@@ -288,7 +261,7 @@ var plugin = {
288
261
  try {
289
262
  await fetch(`${baseUrl}/v1/byok`, {
290
263
  method: "DELETE",
291
- headers: { Authorization: `Bearer ${apiKey2}` }
264
+ headers: { Authorization: `Bearer ${apiKey}` }
292
265
  });
293
266
  } catch {
294
267
  }
@@ -315,8 +288,8 @@ var plugin = {
315
288
  provider = "google";
316
289
  upstreamBaseUrl = "https://generativelanguage.googleapis.com/v1beta/openai";
317
290
  }
318
- const upstreamModels = await fetchUpstreamModels(baseUrl, apiKey2, upstreamKey, upstreamBaseUrl);
319
- const updatedModels = buildProviderModels(baseUrl, upstreamKey, upstreamBaseUrl, upstreamModels || void 0);
291
+ const existingModels2 = readExistingModels(api);
292
+ const updatedModels = buildProviderModels(baseUrl, upstreamKey, upstreamBaseUrl, existingModels2 || void 0);
320
293
  if (api.config.models?.providers) {
321
294
  api.config.models.providers.opencompress = updatedModels;
322
295
  }
@@ -324,14 +297,14 @@ var plugin = {
324
297
  await fetch(`${baseUrl}/v1/byok`, {
325
298
  method: "POST",
326
299
  headers: {
327
- Authorization: `Bearer ${apiKey2}`,
300
+ Authorization: `Bearer ${apiKey}`,
328
301
  "Content-Type": "application/json"
329
302
  },
330
303
  body: JSON.stringify({ provider, passthrough: true })
331
304
  });
332
305
  } catch {
333
306
  }
334
- const modelCount2 = upstreamModels ? upstreamModels.length : FALLBACK_MODELS.length;
307
+ const modelCount2 = existingModels2 ? existingModels2.length : FALLBACK_MODELS.length;
335
308
  return {
336
309
  text: [
337
310
  `Switched to **BYOK mode** (${provider}).`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencompress/opencompress",
3
- "version": "1.4.0",
3
+ "version": "1.5.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",