clawmux 0.1.8 → 0.2.1
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 +7 -14
- package/dist/cli.cjs +30 -37
- package/dist/index.cjs +3223 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Copy `clawmux.example.json` to `clawmux.json` and adjust as needed:
|
|
|
49
49
|
"LIGHT": "anthropic/claude-3-5-haiku-20241022",
|
|
50
50
|
"MEDIUM": "anthropic/claude-sonnet-4-20250514",
|
|
51
51
|
"HEAVY": "anthropic/claude-opus-4-20250514"
|
|
52
|
-
// Model IDs use 'provider/model' format. Do NOT use
|
|
52
|
+
// Model IDs use 'provider/model' format. Do NOT use "clawmux" as provider — causes infinite loops
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"server": {
|
|
@@ -81,20 +81,13 @@ All three providers must be configured in your `openclaw.json`. ClawMux handles
|
|
|
81
81
|
|
|
82
82
|
Supported translation pairs: Anthropic ↔ OpenAI ↔ Google ↔ Ollama ↔ Bedrock (all combinations).
|
|
83
83
|
|
|
84
|
-
##
|
|
84
|
+
## Provider
|
|
85
85
|
|
|
86
|
-
ClawMux registers
|
|
86
|
+
ClawMux registers as a single provider `clawmux` in OpenClaw with model `auto`. It accepts all API formats (Anthropic, OpenAI, Google, Ollama, Bedrock) and translates between them automatically.
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
| `openai-completions` | OpenAI, Moonshot, ZAI, Cerebras, vLLM, SGLang, LM Studio, OpenRouter, Together, NVIDIA, Venice, Groq, Mistral, xAI, HuggingFace, Cloudflare, Volcengine, BytePlus, Vercel, Kilocode, Qianfan, ModelStudio, MiniMax, Xiaomi |
|
|
92
|
-
| `openai-responses` | OpenAI (newer), OpenAI Codex |
|
|
93
|
-
| `google-generative-ai` | Google Gemini, Google Vertex |
|
|
94
|
-
| `ollama` | Ollama |
|
|
95
|
-
| `bedrock-converse-stream` | AWS Bedrock |
|
|
96
|
-
|
|
97
|
-
Use `clawmux-anthropic`, `clawmux-openai`, `clawmux-openai-responses`, `clawmux-google`, `clawmux-ollama`, or `clawmux-bedrock` as the provider name in OpenClaw.
|
|
88
|
+
```bash
|
|
89
|
+
openclaw provider clawmux
|
|
90
|
+
```
|
|
98
91
|
|
|
99
92
|
## How It Works
|
|
100
93
|
|
|
@@ -155,4 +148,4 @@ Tests are co-located with source files as `*.test.ts`.
|
|
|
155
148
|
clawmux uninstall
|
|
156
149
|
```
|
|
157
150
|
|
|
158
|
-
Stops the system service, removes the service file, and removes
|
|
151
|
+
Stops the system service, removes the service file, and removes the `clawmux` provider from your OpenClaw config. A backup is created before any changes.
|
package/dist/cli.cjs
CHANGED
|
@@ -338,14 +338,8 @@ Options:
|
|
|
338
338
|
Environment:
|
|
339
339
|
CLAWMUX_PORT Server port override
|
|
340
340
|
OPENCLAW_CONFIG_PATH Path to openclaw.json`;
|
|
341
|
-
var
|
|
342
|
-
|
|
343
|
-
{ key: "clawmux-openai", api: "openai-completions" },
|
|
344
|
-
{ key: "clawmux-openai-responses", api: "openai-responses" },
|
|
345
|
-
{ key: "clawmux-google", api: "google-generative-ai" },
|
|
346
|
-
{ key: "clawmux-ollama", api: "ollama" },
|
|
347
|
-
{ key: "clawmux-bedrock", api: "bedrock-converse-stream" }
|
|
348
|
-
];
|
|
341
|
+
var PROVIDER_KEY = "clawmux";
|
|
342
|
+
var PROVIDER_API = "anthropic-messages";
|
|
349
343
|
async function fileExistsLocal(path) {
|
|
350
344
|
try {
|
|
351
345
|
await import_promises.access(path);
|
|
@@ -354,11 +348,23 @@ async function fileExistsLocal(path) {
|
|
|
354
348
|
return false;
|
|
355
349
|
}
|
|
356
350
|
}
|
|
351
|
+
function detectPackageManager() {
|
|
352
|
+
try {
|
|
353
|
+
import_node_child_process.execSync("which bun", { stdio: "pipe" });
|
|
354
|
+
return "bunx";
|
|
355
|
+
} catch {
|
|
356
|
+
return "npx";
|
|
357
|
+
}
|
|
358
|
+
}
|
|
357
359
|
function resolveClawmuxBin() {
|
|
358
360
|
try {
|
|
359
|
-
|
|
361
|
+
const bin = import_node_child_process.execSync("which clawmux", { encoding: "utf-8" }).trim();
|
|
362
|
+
if (bin.includes("/tmp/") || bin.includes("bunx-") || bin.includes("npx-")) {
|
|
363
|
+
return detectPackageManager() === "bunx" ? "bunx clawmux" : "npx clawmux";
|
|
364
|
+
}
|
|
365
|
+
return bin;
|
|
360
366
|
} catch {
|
|
361
|
-
return "npx clawmux";
|
|
367
|
+
return detectPackageManager() === "bunx" ? "bunx clawmux" : "npx clawmux";
|
|
362
368
|
}
|
|
363
369
|
}
|
|
364
370
|
function getHomeDir() {
|
|
@@ -540,14 +546,6 @@ async function checkForUpdate() {
|
|
|
540
546
|
}
|
|
541
547
|
} catch (_) {}
|
|
542
548
|
}
|
|
543
|
-
function detectPackageManager() {
|
|
544
|
-
try {
|
|
545
|
-
import_node_child_process.execSync("which bun", { stdio: "pipe" });
|
|
546
|
-
return "bunx";
|
|
547
|
-
} catch {
|
|
548
|
-
return "npx";
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
549
|
async function update() {
|
|
552
550
|
const pm = detectPackageManager();
|
|
553
551
|
console.log(`[clawmux] Checking for updates...`);
|
|
@@ -616,7 +614,13 @@ async function init() {
|
|
|
616
614
|
await import_promises.copyFile(examplePath, clawmuxJsonPath);
|
|
617
615
|
console.log("[info] Created clawmux.json from clawmux.example.json");
|
|
618
616
|
} else {
|
|
619
|
-
|
|
617
|
+
const defaultConfig = {
|
|
618
|
+
compression: { threshold: 0.75, model: "" },
|
|
619
|
+
routing: { models: { LIGHT: "", MEDIUM: "", HEAVY: "" } }
|
|
620
|
+
};
|
|
621
|
+
await import_promises.writeFile(clawmuxJsonPath, JSON.stringify(defaultConfig, null, 2) + `
|
|
622
|
+
`);
|
|
623
|
+
console.log("[info] Created default clawmux.json (configure models before use)");
|
|
620
624
|
}
|
|
621
625
|
}
|
|
622
626
|
const raw = await import_promises.readFile(openclawConfigPath, "utf-8");
|
|
@@ -627,28 +631,17 @@ async function init() {
|
|
|
627
631
|
if (!models.providers)
|
|
628
632
|
models.providers = {};
|
|
629
633
|
const providers = models.providers;
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
continue;
|
|
635
|
-
}
|
|
636
|
-
providers[key] = {
|
|
634
|
+
if (providers[PROVIDER_KEY]) {
|
|
635
|
+
console.log(` skip ${PROVIDER_KEY} (already exists)`);
|
|
636
|
+
} else {
|
|
637
|
+
providers[PROVIDER_KEY] = {
|
|
637
638
|
baseUrl: "http://localhost:3456",
|
|
638
|
-
api,
|
|
639
|
+
api: PROVIDER_API,
|
|
639
640
|
models: [{ id: "auto", name: "ClawMux Auto Router" }]
|
|
640
641
|
};
|
|
641
|
-
added++;
|
|
642
|
-
console.log(` added ${key}`);
|
|
643
|
-
}
|
|
644
|
-
if (added > 0) {
|
|
645
642
|
await import_promises.writeFile(openclawConfigPath, JSON.stringify(config, null, 2) + `
|
|
646
643
|
`);
|
|
647
|
-
console.log(`
|
|
648
|
-
Added ${added} provider(s) to openclaw.json`);
|
|
649
|
-
} else {
|
|
650
|
-
console.log(`
|
|
651
|
-
All ClawMux providers already registered.`);
|
|
644
|
+
console.log(` added ${PROVIDER_KEY} provider to openclaw.json`);
|
|
652
645
|
}
|
|
653
646
|
const port = process.env.CLAWMUX_PORT ?? "3456";
|
|
654
647
|
if (!noService) {
|
|
@@ -696,7 +689,7 @@ async function uninstall() {
|
|
|
696
689
|
const providers = models.providers ?? {};
|
|
697
690
|
let removed = 0;
|
|
698
691
|
for (const key of Object.keys(providers)) {
|
|
699
|
-
if (key.startsWith("clawmux-")) {
|
|
692
|
+
if (key === "clawmux" || key.startsWith("clawmux-")) {
|
|
700
693
|
delete providers[key];
|
|
701
694
|
removed++;
|
|
702
695
|
}
|