@workweave/router 0.2.2 → 0.2.4

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/bin.js CHANGED
@@ -17,7 +17,7 @@ const script = path.join(__dirname, scriptName);
17
17
 
18
18
  if (!existsSync(script)) {
19
19
  console.error(
20
- `weave-router: ${scriptName} missing from package — please report at https://github.com/workweave/router/issues`,
20
+ `Weave Router: ${scriptName} missing from package — report it at https://github.com/workweave/router/issues`,
21
21
  );
22
22
  process.exit(1);
23
23
  }
@@ -25,7 +25,7 @@ if (!existsSync(script)) {
25
25
  const bash = pickBash();
26
26
  if (!bash) {
27
27
  console.error(
28
- "weave-router: bash is required. On Windows install Git Bash or run inside WSL.",
28
+ "Weave Router: bash is required. On Windows install Git Bash or run inside WSL.",
29
29
  );
30
30
  process.exit(1);
31
31
  }
@@ -36,7 +36,7 @@ const result = spawnSync(bash, [script, ...args], {
36
36
  });
37
37
 
38
38
  if (result.error) {
39
- console.error("weave-router:", result.error.message);
39
+ console.error("Weave Router:", result.error.message);
40
40
  process.exit(1);
41
41
  }
42
42
  process.exit(result.status ?? 1);
package/cc-statusline.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
- # Claude Code statusline for the Weave router. CC pipes a JSON blob on stdin
3
+ # Claude Code statusline for the Weave Router. CC pipes a JSON blob on stdin
4
4
  # whose `transcript_path` points at the JSONL log of the current session and
5
5
  # whose `model.display_name` is the user's CC-side model selection. The
6
6
  # router rewrites each request's `model` field before forwarding, so
@@ -166,9 +166,11 @@ prices='{
166
166
  "gpt-5.5-nano": 0.00015,
167
167
  "gpt-5.5-pro": 0.03,
168
168
  "minimax/minimax-m2.7": 0.0003,
169
+ "minimax/minimax-m3": 0.0003,
169
170
  "mistralai/mistral-small-2603": 0.0002,
170
171
  "moonshotai/kimi-k2.5": 0.0006,
171
172
  "moonshotai/kimi-k2.6": 0.00095,
173
+ "moonshotai/kimi-k2.7": 0.00095,
172
174
  "qwen/qwen3-235b-a22b-2507": 0.0002266,
173
175
  "qwen/qwen3-30b-a3b-instruct-2507": 0.00015,
174
176
  "qwen/qwen3-coder": 0.0009,
@@ -176,9 +178,11 @@ prices='{
176
178
  "qwen/qwen3-next-80b-a3b-instruct": 0.00015,
177
179
  "qwen/qwen3.5-flash-02-23": 0.00005,
178
180
  "qwen/qwen3.6-35b-a3b": 0.00015,
181
+ "qwen/qwen3.7-plus": 0.0004,
179
182
  "xiaomi/mimo-v2.5-pro": 0.001,
180
183
  "z-ai/glm-5": 0.0006,
181
- "z-ai/glm-5.1": 0.00105
184
+ "z-ai/glm-5.1": 0.00105,
185
+ "z-ai/glm-5.2": 0.0014
182
186
  },
183
187
  "output": {
184
188
  "claude-fable-5": 0.05,
@@ -218,9 +222,11 @@ prices='{
218
222
  "gpt-5.5-nano": 0.0006,
219
223
  "gpt-5.5-pro": 0.12,
220
224
  "minimax/minimax-m2.7": 0.0012,
225
+ "minimax/minimax-m3": 0.0012,
221
226
  "mistralai/mistral-small-2603": 0.0006,
222
227
  "moonshotai/kimi-k2.5": 0.003,
223
228
  "moonshotai/kimi-k2.6": 0.004,
229
+ "moonshotai/kimi-k2.7": 0.004,
224
230
  "qwen/qwen3-235b-a22b-2507": 0.0009064,
225
231
  "qwen/qwen3-30b-a3b-instruct-2507": 0.0006,
226
232
  "qwen/qwen3-coder": 0.0027,
@@ -228,14 +234,18 @@ prices='{
228
234
  "qwen/qwen3-next-80b-a3b-instruct": 0.0012,
229
235
  "qwen/qwen3.5-flash-02-23": 0.00015,
230
236
  "qwen/qwen3.6-35b-a3b": 0.00095,
237
+ "qwen/qwen3.7-plus": 0.0016,
231
238
  "xiaomi/mimo-v2.5-pro": 0.003,
232
239
  "z-ai/glm-5": 0.00208,
233
- "z-ai/glm-5.1": 0.0035
240
+ "z-ai/glm-5.1": 0.0035,
241
+ "z-ai/glm-5.2": 0.0044
234
242
  }
235
243
  }'
236
244
  # END_GENERATED_PRICES
237
245
 
238
246
  routed=""
247
+ forced="false"
248
+ forced_model=""
239
249
  session_savings=""
240
250
  tot_in=0
241
251
  tot_out=0
@@ -273,6 +283,36 @@ if [[ -n "$transcript_path" && -f "$transcript_path" ]]; then
273
283
  routed="$(normalize_model "$routed")"
274
284
  fi
275
285
 
286
+ # Detect an active /force-model pin from the router's synthetic ack turns —
287
+ # the only turns stamped message.model == "weave-router". The router emits
288
+ # one whenever a pin changes state:
289
+ # * /force-model → "force-model applied: <model> (<provider>) …"
290
+ # * /unforce-model → "force-model cleared …"
291
+ # * loop / no-progress break → "… clearing the session pin …" (expires the
292
+ # pin, including a user-forced one)
293
+ # * unrecognized model → "… isn't a recognized model · keeping
294
+ # automatic routing" — a NO-OP: the prior
295
+ # pin, if any, is left untouched
296
+ # These persist on disk (the ingress stripper only scrubs them from upstream
297
+ # requests). Classify each weave-router turn newest-first, skip the no-op
298
+ # "rejected" acks, and let the latest real state change decide: an "applied"
299
+ # marker means the session is pinned (and names the model); anything else
300
+ # (cleared / loop-break / no-progress) means automatic routing has resumed.
301
+ # Restricting to weave-router turns keeps a normal reply that merely quotes
302
+ # these phrases from flipping the tag. (A silent server-side TTL expiry emits
303
+ # no turn and so can't be reflected here — the pin TTL outlives a session.)
304
+ force_state="$("${reverse[@]}" "$transcript_path" 2>/dev/null \
305
+ | jq -r 'select(.type=="assistant" and .message.model=="weave-router")
306
+ | ([.message.content[]? | select(.type? == "text") | .text] | join(" ") | gsub("[\n\r]"; " ")) as $t
307
+ | if ($t | test("force-model applied:")) then "APPLIED " + ($t | capture("force-model applied: (?<m>[^ ]+)").m)
308
+ elif ($t | test("isn.t a recognized model")) then "REJECTED"
309
+ else "CLEARED" end' 2>/dev/null \
310
+ | grep -m1 -v '^REJECTED$' || true)"
311
+ if [[ "$force_state" == APPLIED\ * ]]; then
312
+ forced="true"
313
+ forced_model="${force_state#APPLIED }"
314
+ fi
315
+
276
316
  # Compute a session running total: savings across every assistant turn
277
317
  # whose marker reports a requested ≠ routed swap, plus cumulative token
278
318
  # counts across every assistant turn (rerouted or not — total work the
@@ -375,7 +415,14 @@ if [[ "$tot_in" -gt 0 || "$tot_out" -gt 0 || "$tot_cache_read" -gt 0 || "$tot_ca
375
415
  fi
376
416
  fi
377
417
 
378
- if [[ "$routed" == "failure" ]]; then
418
+ if [[ "$forced" == "true" ]]; then
419
+ # Session is pinned via /force-model. The "← selection · saved $X" clause
420
+ # describes automatic routing and would be misleading on a manual pin, so
421
+ # show the pinned model with a [forced] tag instead. forced_model comes from
422
+ # the marker; fall back to the routed/selected id if parsing came up empty.
423
+ forced_display="${forced_model:-${routed:-$selected_display}}"
424
+ printf '%s — %s [forced]%s' "$brand" "$forced_display" "$tokens_clause"
425
+ elif [[ "$routed" == "failure" ]]; then
379
426
  # Latest turn was a CC-synthesized error stub — don't claim a routing
380
427
  # swap or compute savings against a non-model.
381
428
  printf '%s — %s%s' "$brand" "$routed" "$tokens_clause"
package/commands/fm.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Alias for /force-model - pin this session to a specific model via the Weave Router
2
+ description: Alias for /force-model pin this session to a specific model via the Weave Router.
3
3
  argument-hint: <model-id>
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Pin this session to a specific model via the Weave Router
2
+ description: Pin this session to a specific model via the Weave Router.
3
3
  argument-hint: <model-id>
4
4
  ---
5
5
 
package/commands/rf.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Alias for /router-feedback - submit feedback about router decision or model performance
2
+ description: Alias for /router-feedback submit feedback about router decision or model performance.
3
3
  argument-hint: <feedback-text>
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Submit feedback about router decision or model performance
2
+ description: Submit feedback about router decision or model performance.
3
3
  argument-hint: <feedback-text>
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Route Claude Code directly to Anthropic again (turn the Weave Router off)
2
+ description: Route Claude Code directly to Anthropic again (turn the Weave Router off).
3
3
  allowed-tools: Bash(npx:*)
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Route Claude Code through the Weave Router again (turn it back on)
2
+ description: Route Claude Code through the Weave Router again (turn it back on).
3
3
  allowed-tools: Bash(npx:*)
4
4
  ---
5
5
 
@@ -1,9 +1,9 @@
1
1
  ---
2
- description: Show whether Claude Code is routing through the Weave Router or directly to Anthropic
2
+ description: Show whether Claude Code is routing through the Weave Router or directly to Anthropic.
3
3
  allowed-tools: Bash(npx:*)
4
4
  ---
5
5
 
6
- Report whether Claude Code is currently using the Weave Router by running:
6
+ Report whether Claude Code is using the Weave Router by running:
7
7
 
8
8
  `npx @workweave/router status --claude{{SCOPE}}`
9
9
 
package/commands/ufm.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Alias for /unforce-model - clear an active /force-model pin and resume automatic routing
2
+ description: Alias for /unforce-model clear an active /force-model pin and resume automatic routing.
3
3
  ---
4
4
 
5
5
  /unforce-model
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Clear an active /force-model pin and resume automatic routing
2
+ description: Clear an active /force-model pin and resume automatic routing.
3
3
  ---
4
4
 
5
5
  /unforce-model