clawmux 0.2.3 → 0.3.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/cli.cjs CHANGED
@@ -317,7 +317,7 @@ function getLogDir() {
317
317
  }
318
318
 
319
319
  // src/cli.ts
320
- var VERSION2 = process.env.npm_package_version ?? "0.2.3";
320
+ var VERSION2 = process.env.npm_package_version ?? "0.3.0";
321
321
  var SERVICE_NAME = "clawmux";
322
322
  var HELP = `Usage: clawmux <command>
323
323
 
package/dist/index.cjs CHANGED
@@ -596,7 +596,20 @@ async function readAuthProfiles(agentId, profilesPath) {
596
596
  provider: profile.provider ?? key.split(":")[0],
597
597
  apiKey: profile.access ?? profile.apiKey,
598
598
  token: profile.token
599
- }));
599
+ })).filter((p) => {
600
+ const token = p.apiKey ?? p.token;
601
+ if (!token || !token.includes("."))
602
+ return true;
603
+ try {
604
+ const payload = token.split(".")[1];
605
+ const decoded = JSON.parse(Buffer.from(payload, "base64").toString());
606
+ if (decoded.exp && decoded.exp * 1000 < Date.now())
607
+ return false;
608
+ } catch (_) {
609
+ return true;
610
+ }
611
+ return true;
612
+ });
600
613
  }
601
614
  return [];
602
615
  } catch (err) {
@@ -2250,6 +2263,57 @@ ${JSON.stringify({
2250
2263
  var bedrockAdapter = new BedrockAdapter;
2251
2264
  registerAdapter(bedrockAdapter);
2252
2265
 
2266
+ // src/adapters/openai-codex.ts
2267
+ class OpenAICodexAdapter {
2268
+ apiType = "openai-codex-responses";
2269
+ parseRequest(body) {
2270
+ return parseOpenAIBody(body);
2271
+ }
2272
+ buildUpstreamRequest(parsed, targetModel, baseUrl, auth) {
2273
+ const { rawBody } = parsed;
2274
+ const upstreamBody = { ...rawBody };
2275
+ upstreamBody.model = targetModel;
2276
+ upstreamBody.stream = true;
2277
+ upstreamBody.store = false;
2278
+ if (!upstreamBody.instructions) {
2279
+ upstreamBody.instructions = upstreamBody.system ?? "You are a helpful assistant.";
2280
+ }
2281
+ delete upstreamBody.system;
2282
+ if (!upstreamBody.input && upstreamBody.messages) {
2283
+ upstreamBody.input = upstreamBody.messages;
2284
+ delete upstreamBody.messages;
2285
+ }
2286
+ delete upstreamBody.max_tokens;
2287
+ delete upstreamBody.max_output_tokens;
2288
+ return {
2289
+ url: `${baseUrl}/codex/responses`,
2290
+ method: "POST",
2291
+ headers: {
2292
+ "Content-Type": "application/json",
2293
+ Authorization: `Bearer ${auth.apiKey}`
2294
+ },
2295
+ body: JSON.stringify(upstreamBody)
2296
+ };
2297
+ }
2298
+ modifyMessages(rawBody, compressedMessages) {
2299
+ return openaiResponsesAdapter.modifyMessages(rawBody, compressedMessages);
2300
+ }
2301
+ parseResponse(body) {
2302
+ return openaiResponsesAdapter.parseResponse(body);
2303
+ }
2304
+ buildResponse(parsed) {
2305
+ return openaiResponsesAdapter.buildResponse(parsed);
2306
+ }
2307
+ parseStreamChunk(chunk) {
2308
+ return openaiResponsesAdapter.parseStreamChunk(chunk);
2309
+ }
2310
+ buildStreamChunk(event) {
2311
+ return openaiResponsesAdapter.buildStreamChunk(event);
2312
+ }
2313
+ }
2314
+ var openaiCodexAdapter = new OpenAICodexAdapter;
2315
+ registerAdapter(openaiCodexAdapter);
2316
+
2253
2317
  // src/compression/compaction-detector.ts
2254
2318
  var COMPACTION_PATTERNS = [
2255
2319
  "merge these partial summaries into a single cohesive summary",
@@ -3386,6 +3450,48 @@ function createCompressionMiddleware(config) {
3386
3450
 
3387
3451
  // src/proxy/pipeline.ts
3388
3452
  registerAdapter(new AnthropicAdapter);
3453
+ async function collectCodexStream(sourceAdapter, response) {
3454
+ const reader = response.body.getReader();
3455
+ const decoder2 = new TextDecoder;
3456
+ let buffer = "";
3457
+ let id = "";
3458
+ let model = "";
3459
+ const textParts = [];
3460
+ let usage;
3461
+ for (;; ) {
3462
+ const { done, value } = await reader.read();
3463
+ if (done)
3464
+ break;
3465
+ buffer += decoder2.decode(value, { stream: true });
3466
+ let idx;
3467
+ while ((idx = buffer.indexOf(`
3468
+
3469
+ `)) !== -1) {
3470
+ const frame = buffer.slice(0, idx);
3471
+ buffer = buffer.slice(idx + 2);
3472
+ if (!frame.trim() || !sourceAdapter.parseStreamChunk)
3473
+ continue;
3474
+ for (const event of sourceAdapter.parseStreamChunk(frame)) {
3475
+ if (event.type === "message_start") {
3476
+ id = event.id ?? "";
3477
+ model = event.model ?? "";
3478
+ } else if (event.type === "content_delta") {
3479
+ textParts.push(event.text ?? "");
3480
+ } else if (event.type === "message_stop" && event.usage) {
3481
+ usage = event.usage;
3482
+ }
3483
+ }
3484
+ }
3485
+ }
3486
+ return {
3487
+ id,
3488
+ model,
3489
+ content: textParts.join(""),
3490
+ role: "assistant",
3491
+ stopReason: "completed",
3492
+ usage
3493
+ };
3494
+ }
3389
3495
  function findProviderForModel(modelString, openclawConfig) {
3390
3496
  const providers = openclawConfig.models?.providers;
3391
3497
  if (!providers)
@@ -3495,6 +3601,18 @@ async function handleApiRequest(req, body, apiType, config, openclawConfig, auth
3495
3601
  if (compressionMiddleware && upstreamResponse.ok) {
3496
3602
  compressionMiddleware.afterResponse(parsed, adapter, baseUrl, authInfo);
3497
3603
  }
3604
+ const isCodexUpstream = targetApiType === "openai-codex-responses";
3605
+ if (isCodexUpstream && upstreamResponse.ok && upstreamResponse.body) {
3606
+ if (effectiveParsed.stream) {
3607
+ return translateResponse(requestAdapter, adapter, upstreamResponse, true);
3608
+ }
3609
+ const collected = await collectCodexStream(requestAdapter, upstreamResponse);
3610
+ const translated = adapter.buildResponse(collected);
3611
+ return new Response(JSON.stringify(translated), {
3612
+ status: 200,
3613
+ headers: { "content-type": "application/json" }
3614
+ });
3615
+ }
3498
3616
  if (targetAdapter && upstreamResponse.ok) {
3499
3617
  return translateResponse(targetAdapter, adapter, upstreamResponse, effectiveParsed.stream);
3500
3618
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmux",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Smart model routing + context compression proxy for OpenClaw",
5
5
  "type": "module",
6
6
  "bin": {