@khanglvm/llm-router 2.2.0 → 2.2.2

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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  LLM Router is a local and Cloudflare-deployable gateway for routing one client endpoint across multiple LLM providers, models, aliases, fallbacks, and rate limits.
4
4
 
5
+ ![LLM Router Web Console](./assets/screenshots/web-ui-dashboard.png)
6
+
5
7
  **Current version**: `2.2.0`
6
8
 
7
9
  NPM package:
@@ -109,6 +111,28 @@ What it covers:
109
111
 
110
112
  The Web UI is localhost-only by default because it can expose secrets and live configuration.
111
113
 
114
+ ### Screenshots
115
+
116
+ **Alias & Fallback**
117
+
118
+ ![Alias & Fallback](./assets/screenshots/web-ui-aliases.png)
119
+
120
+ **AMP Configuration**
121
+
122
+ ![AMP Configuration](./assets/screenshots/web-ui-amp.png)
123
+
124
+ **Claude Code Routing**
125
+
126
+ ![Claude Code Routing](./assets/screenshots/web-ui-claude-code.png)
127
+
128
+ **Codex CLI Routing**
129
+
130
+ ![Codex CLI Routing](./assets/screenshots/web-ui-codex-cli.png)
131
+
132
+ **Web Search**
133
+
134
+ ![Web Search](./assets/screenshots/web-ui-web-search.png)
135
+
112
136
  ## CLI Parity
113
137
 
114
138
  The browser UI still gives the best interactive overview, but the CLI now exposes the main management flows an agent needs without relying on private web endpoints.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanglvm/llm-router",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "LLM Router: single gateway endpoint for multi-provider LLMs with unified OpenAI+Anthropic format and seamless fallback",
5
5
  "keywords": [
6
6
  "llm-router",
@@ -6538,6 +6538,15 @@ async function doSetClaudeCodeEffortLevel(context) {
6538
6538
  const settingsFilePath = String(readArg(args, ["claude-code-settings-file", "claudeCodeSettingsFile", "claude-settings-file", "claudeSettingsFile"], "") || "").trim();
6539
6539
  const effortLevel = String(readArg(args, ["thinking-level", "thinkingLevel", "effort-level", "effortLevel"], "") || "").trim();
6540
6540
 
6541
+ if (effortLevel && !normalizeClaudeCodeEffortLevel(effortLevel)) {
6542
+ return {
6543
+ ok: false,
6544
+ mode: context.mode,
6545
+ exitCode: EXIT_VALIDATION,
6546
+ errorMessage: `Invalid effort level '${effortLevel}'. Valid values: low, medium, high, max.`
6547
+ };
6548
+ }
6549
+
6541
6550
  const result = await patchClaudeCodeEffortLevel({
6542
6551
  settingsFilePath,
6543
6552
  effortLevel,
@@ -3164,6 +3164,10 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
3164
3164
  if (method === "POST" && requestUrl.pathname === "/api/claude-code/effort-level") {
3165
3165
  const body = await readJsonBody(req);
3166
3166
  const effortLevel = String(body?.effortLevel || body?.thinkingLevel || "").trim();
3167
+ if (effortLevel && !normalizeClaudeCodeEffortLevel(effortLevel)) {
3168
+ sendJson(res, 400, { error: `Invalid effort level '${effortLevel}'. Valid values: low, medium, high, max.` });
3169
+ return;
3170
+ }
3167
3171
  const result = await patchClaudeCodeEffortLevel({
3168
3172
  effortLevel,
3169
3173
  env: claudeCodeEnv