@workweave/router 0.2.11 → 0.2.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workweave/router",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "One-command installer that points Claude Code, Codex, opencode, or pi at the Weave Router. For pi it also ships the routing extension, loaded via pi.extensions.",
5
5
  "bin": {
6
6
  "weave-router": "bin.js",
@@ -19,6 +19,7 @@
19
19
  "install.sh",
20
20
  "uninstall.sh",
21
21
  "cc-statusline.sh",
22
+ "codex-status.sh",
22
23
  "registry.sh",
23
24
  "directives.tsv",
24
25
  "commands/",
@@ -31,6 +31,9 @@ from npm on next start and loads this extension via its `pi.extensions` field.
31
31
  current router session; `/ufm` and `/unforce-model` resume automatic routing.
32
32
  The persistent status changes to `WEAVE ROUTER — <model> [forced]` after the
33
33
  router validates and canonicalizes the requested model.
34
+ - **Beta routing toggle.** `/beta` toggles the router's beta HMM strategy for
35
+ the current session. The router confirms whether beta routing is enabled or
36
+ disabled; run `/beta` again to switch back.
34
37
  - **Per-process routing bias.** Static `x-weave-routing-*` knob headers bias the
35
38
  router: quality on the main loop and speed + cheap on subagents.
36
39
  - **Long tool-loop compaction.** Pi can cross its context threshold inside an
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Forward Pi's local /beta command to the router as one canonical user turn.
3
+ *
4
+ * The router owns the session strategy state and the enabled/disabled reply;
5
+ * the client only validates the command shape and preserves busy-turn ordering.
6
+ */
7
+
8
+ import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
9
+
10
+ export function registerBetaCommand(pi: ExtensionAPI): void {
11
+ pi.registerCommand("beta", {
12
+ description: "Toggle beta HMM routing for this Weave Router session",
13
+ handler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {
14
+ if (args.trim()) {
15
+ ctx.ui.notify("Usage: /beta", "warning");
16
+ return;
17
+ }
18
+ pi.sendUserMessage("/beta", ctx.isIdle() ? undefined : { deliverAs: "followUp" });
19
+ },
20
+ });
21
+ }
@@ -22,6 +22,7 @@
22
22
 
23
23
  import { fileURLToPath } from "node:url";
24
24
  import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
25
+ import { registerBetaCommand } from "./beta.js";
25
26
  import { isSubagent } from "./config.js";
26
27
  import { registerCompaction } from "./compaction.js";
27
28
  import { registerDispatch } from "./dispatch.js";
@@ -42,6 +43,7 @@ export default function (pi: ExtensionAPI): void {
42
43
  pi.on("session_start", () => registerWeave(pi));
43
44
 
44
45
  registerMetadata(pi);
46
+ registerBetaCommand(pi);
45
47
  registerForceModelCommands(pi);
46
48
  registerRoutedModel(pi);
47
49
  registerCompaction(pi);
@@ -4,83 +4,85 @@
4
4
  export interface ModelPricing {
5
5
  inputUsdPerMillion: number;
6
6
  outputUsdPerMillion: number;
7
+ cacheReadMultiplier: number;
7
8
  }
8
9
 
9
- export const PRICING_VERSION = "catalog-sha256:3863968c8737c92a";
10
+ export const PRICING_VERSION = "catalog-sha256:f2403470b0f8838c";
10
11
 
11
12
  export const MODEL_PRICING: Readonly<Record<string, ModelPricing>> = Object.freeze({
12
- "claude-fable-5": { inputUsdPerMillion: 10, outputUsdPerMillion: 50 },
13
- "claude-haiku-4-5": { inputUsdPerMillion: 1, outputUsdPerMillion: 5 },
14
- "claude-opus-4-0": { inputUsdPerMillion: 15, outputUsdPerMillion: 75 },
15
- "claude-opus-4-1": { inputUsdPerMillion: 15, outputUsdPerMillion: 75 },
16
- "claude-opus-4-5": { inputUsdPerMillion: 5, outputUsdPerMillion: 25 },
17
- "claude-opus-4-6": { inputUsdPerMillion: 5, outputUsdPerMillion: 25 },
18
- "claude-opus-4-7": { inputUsdPerMillion: 5, outputUsdPerMillion: 25 },
19
- "claude-opus-4-8": { inputUsdPerMillion: 5, outputUsdPerMillion: 25 },
20
- "claude-opus-5": { inputUsdPerMillion: 5, outputUsdPerMillion: 25 },
21
- "claude-sonnet-4-5": { inputUsdPerMillion: 3, outputUsdPerMillion: 15 },
22
- "claude-sonnet-4-6": { inputUsdPerMillion: 3, outputUsdPerMillion: 15 },
23
- "claude-sonnet-5": { inputUsdPerMillion: 3, outputUsdPerMillion: 15 },
24
- "deepseek/deepseek-v4-flash": { inputUsdPerMillion: 0.1134, outputUsdPerMillion: 0.2791 },
25
- "deepseek/deepseek-v4-pro": { inputUsdPerMillion: 1.74, outputUsdPerMillion: 3.48 },
26
- "deepseek/deepseek-v4-pro-0813": { inputUsdPerMillion: 1.74, outputUsdPerMillion: 3.48 },
27
- "gemini-2.0-flash": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
28
- "gemini-2.0-flash-lite": { inputUsdPerMillion: 0.075, outputUsdPerMillion: 0.3 },
29
- "gemini-2.5-flash": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2 },
30
- "gemini-2.5-flash-lite": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
31
- "gemini-2.5-pro": { inputUsdPerMillion: 1.25, outputUsdPerMillion: 5 },
32
- "gemini-3-flash-preview": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2 },
33
- "gemini-3-pro-preview": { inputUsdPerMillion: 2, outputUsdPerMillion: 8 },
34
- "gemini-3.1-flash-lite-preview": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
35
- "gemini-3.1-pro-preview": { inputUsdPerMillion: 2, outputUsdPerMillion: 8 },
36
- "gemini-3.5-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 9 },
37
- "gemini-3.5-flash-lite": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 2.5 },
38
- "gemini-3.6-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 7.5 },
39
- "gemini-3.7-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 7.5 },
40
- "google/gemma-4-26b-a4b-it": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6 },
41
- "gpt-4.1": { inputUsdPerMillion: 2, outputUsdPerMillion: 8 },
42
- "gpt-4.1-mini": { inputUsdPerMillion: 0.4, outputUsdPerMillion: 1.6 },
43
- "gpt-4.1-nano": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
44
- "gpt-4o": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10 },
45
- "gpt-4o-mini": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6 },
46
- "gpt-5": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10 },
47
- "gpt-5-chat": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10 },
48
- "gpt-5-mini": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2 },
49
- "gpt-5-nano": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
50
- "gpt-5.4": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 15 },
51
- "gpt-5.4-mini": { inputUsdPerMillion: 0.75, outputUsdPerMillion: 4.5 },
52
- "gpt-5.4-nano": { inputUsdPerMillion: 0.2, outputUsdPerMillion: 1.25 },
53
- "gpt-5.4-pro": { inputUsdPerMillion: 30, outputUsdPerMillion: 180 },
54
- "gpt-5.5": { inputUsdPerMillion: 5, outputUsdPerMillion: 30 },
55
- "gpt-5.5-mini": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2.5 },
56
- "gpt-5.5-nano": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6 },
57
- "gpt-5.5-pro": { inputUsdPerMillion: 30, outputUsdPerMillion: 180 },
58
- "gpt-5.6-luna": { inputUsdPerMillion: 1, outputUsdPerMillion: 6 },
59
- "gpt-5.6-luna-pro": { inputUsdPerMillion: 1, outputUsdPerMillion: 6 },
60
- "gpt-5.6-sol": { inputUsdPerMillion: 5, outputUsdPerMillion: 30 },
61
- "gpt-5.6-sol-pro": { inputUsdPerMillion: 5, outputUsdPerMillion: 30 },
62
- "gpt-5.6-terra": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 15 },
63
- "grok-4.5": { inputUsdPerMillion: 2, outputUsdPerMillion: 6 },
64
- "grok-4.6": { inputUsdPerMillion: 2, outputUsdPerMillion: 6 },
65
- "minimax/minimax-m2.7": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2 },
66
- "minimax/minimax-m3": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2 },
67
- "mistralai/mistral-small-2603": { inputUsdPerMillion: 0.2, outputUsdPerMillion: 0.6 },
68
- "moonshotai/kimi-k2.5": { inputUsdPerMillion: 0.6, outputUsdPerMillion: 3 },
69
- "moonshotai/kimi-k2.6": { inputUsdPerMillion: 0.95, outputUsdPerMillion: 4 },
70
- "moonshotai/kimi-k2.7": { inputUsdPerMillion: 0.95, outputUsdPerMillion: 4 },
71
- "moonshotai/kimi-k3": { inputUsdPerMillion: 3, outputUsdPerMillion: 15 },
72
- "qwen/qwen3-235b-a22b-2507": { inputUsdPerMillion: 0.2266, outputUsdPerMillion: 0.9064 },
73
- "qwen/qwen3-30b-a3b-instruct-2507": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6 },
74
- "qwen/qwen3-coder": { inputUsdPerMillion: 0.9, outputUsdPerMillion: 2.7 },
75
- "qwen/qwen3-coder-next": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 1.2 },
76
- "qwen/qwen3-next-80b-a3b-instruct": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 1.2 },
77
- "qwen/qwen3.5-flash-02-23": { inputUsdPerMillion: 0.05, outputUsdPerMillion: 0.15 },
78
- "qwen/qwen3.6-35b-a3b": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 1 },
79
- "qwen/qwen3.7-plus": { inputUsdPerMillion: 0.4, outputUsdPerMillion: 1.6 },
80
- "qwen/qwen3.8-max": { inputUsdPerMillion: 2, outputUsdPerMillion: 6 },
81
- "xiaomi/mimo-v2.5-pro": { inputUsdPerMillion: 1, outputUsdPerMillion: 3 },
82
- "z-ai/glm-5": { inputUsdPerMillion: 1, outputUsdPerMillion: 3.2 },
83
- "z-ai/glm-5.1": { inputUsdPerMillion: 1.4, outputUsdPerMillion: 4.4 },
84
- "z-ai/glm-5.2": { inputUsdPerMillion: 1.4, outputUsdPerMillion: 4.4 },
85
- "z-ai/glm-5.3-flash": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.5 },
13
+ "claude-fable-5": { inputUsdPerMillion: 10, outputUsdPerMillion: 50, cacheReadMultiplier: 0.1 },
14
+ "claude-haiku-4-5": { inputUsdPerMillion: 1, outputUsdPerMillion: 5, cacheReadMultiplier: 0.1 },
15
+ "claude-opus-4-0": { inputUsdPerMillion: 15, outputUsdPerMillion: 75, cacheReadMultiplier: 0.1 },
16
+ "claude-opus-4-1": { inputUsdPerMillion: 15, outputUsdPerMillion: 75, cacheReadMultiplier: 0.1 },
17
+ "claude-opus-4-5": { inputUsdPerMillion: 5, outputUsdPerMillion: 25, cacheReadMultiplier: 0.1 },
18
+ "claude-opus-4-6": { inputUsdPerMillion: 5, outputUsdPerMillion: 25, cacheReadMultiplier: 0.1 },
19
+ "claude-opus-4-7": { inputUsdPerMillion: 5, outputUsdPerMillion: 25, cacheReadMultiplier: 0.1 },
20
+ "claude-opus-4-8": { inputUsdPerMillion: 5, outputUsdPerMillion: 25, cacheReadMultiplier: 0.1 },
21
+ "claude-opus-5": { inputUsdPerMillion: 5, outputUsdPerMillion: 25, cacheReadMultiplier: 0.1 },
22
+ "claude-sonnet-4-5": { inputUsdPerMillion: 3, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
23
+ "claude-sonnet-4-6": { inputUsdPerMillion: 3, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
24
+ "claude-sonnet-5": { inputUsdPerMillion: 3, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
25
+ "deepseek/deepseek-v4-flash": { inputUsdPerMillion: 0.1134, outputUsdPerMillion: 0.2791, cacheReadMultiplier: 0.2 },
26
+ "deepseek/deepseek-v4-pro": { inputUsdPerMillion: 1.74, outputUsdPerMillion: 3.48, cacheReadMultiplier: 0.11494252873563218 },
27
+ "deepseek/deepseek-v4-pro-0813": { inputUsdPerMillion: 1.74, outputUsdPerMillion: 3.48, cacheReadMultiplier: 0.11494252873563218 },
28
+ "gemini-2.0-flash": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4, cacheReadMultiplier: 0.25 },
29
+ "gemini-2.0-flash-lite": { inputUsdPerMillion: 0.075, outputUsdPerMillion: 0.3, cacheReadMultiplier: 0.25 },
30
+ "gemini-2.5-flash": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2, cacheReadMultiplier: 0.1 },
31
+ "gemini-2.5-flash-lite": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4, cacheReadMultiplier: 0.1 },
32
+ "gemini-2.5-pro": { inputUsdPerMillion: 1.25, outputUsdPerMillion: 5, cacheReadMultiplier: 0.1 },
33
+ "gemini-3-flash-preview": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2, cacheReadMultiplier: 0.1 },
34
+ "gemini-3-pro-preview": { inputUsdPerMillion: 2, outputUsdPerMillion: 8, cacheReadMultiplier: 0.1 },
35
+ "gemini-3.1-flash-lite-preview": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4, cacheReadMultiplier: 0.1 },
36
+ "gemini-3.1-pro-preview": { inputUsdPerMillion: 2, outputUsdPerMillion: 8, cacheReadMultiplier: 0.1 },
37
+ "gemini-3.5-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 9, cacheReadMultiplier: 0.1 },
38
+ "gemini-3.5-flash-lite": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 2.5, cacheReadMultiplier: 0.1 },
39
+ "gemini-3.6-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 7.5, cacheReadMultiplier: 0.1 },
40
+ "gemini-3.7-flash": { inputUsdPerMillion: 1.5, outputUsdPerMillion: 7.5, cacheReadMultiplier: 0.1 },
41
+ "google/gemma-4-26b-a4b-it": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6, cacheReadMultiplier: 0.1 },
42
+ "gpt-4.1": { inputUsdPerMillion: 2, outputUsdPerMillion: 8, cacheReadMultiplier: 0.25 },
43
+ "gpt-4.1-mini": { inputUsdPerMillion: 0.4, outputUsdPerMillion: 1.6, cacheReadMultiplier: 0.25 },
44
+ "gpt-4.1-nano": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4, cacheReadMultiplier: 0.25 },
45
+ "gpt-4o": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10, cacheReadMultiplier: 0.5 },
46
+ "gpt-4o-mini": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6, cacheReadMultiplier: 0.5 },
47
+ "gpt-5": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10, cacheReadMultiplier: 0.1 },
48
+ "gpt-5-chat": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10, cacheReadMultiplier: 0.1 },
49
+ "gpt-5-mini": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2, cacheReadMultiplier: 0.1 },
50
+ "gpt-5-nano": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4, cacheReadMultiplier: 0.1 },
51
+ "gpt-5.4": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
52
+ "gpt-5.4-mini": { inputUsdPerMillion: 0.75, outputUsdPerMillion: 4.5, cacheReadMultiplier: 0.1 },
53
+ "gpt-5.4-nano": { inputUsdPerMillion: 0.2, outputUsdPerMillion: 1.25, cacheReadMultiplier: 0.1 },
54
+ "gpt-5.4-pro": { inputUsdPerMillion: 30, outputUsdPerMillion: 180, cacheReadMultiplier: 1 },
55
+ "gpt-5.5": { inputUsdPerMillion: 5, outputUsdPerMillion: 30, cacheReadMultiplier: 0.1 },
56
+ "gpt-5.5-mini": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 2.5, cacheReadMultiplier: 0.1 },
57
+ "gpt-5.5-nano": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6, cacheReadMultiplier: 0.1 },
58
+ "gpt-5.5-pro": { inputUsdPerMillion: 30, outputUsdPerMillion: 180, cacheReadMultiplier: 1 },
59
+ "gpt-5.6-luna": { inputUsdPerMillion: 1, outputUsdPerMillion: 6, cacheReadMultiplier: 0.1 },
60
+ "gpt-5.6-luna-pro": { inputUsdPerMillion: 1, outputUsdPerMillion: 6, cacheReadMultiplier: 0.1 },
61
+ "gpt-5.6-sol": { inputUsdPerMillion: 5, outputUsdPerMillion: 30, cacheReadMultiplier: 0.1 },
62
+ "gpt-5.6-sol-pro": { inputUsdPerMillion: 5, outputUsdPerMillion: 30, cacheReadMultiplier: 0.1 },
63
+ "gpt-5.6-terra": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
64
+ "grok-4.5": { inputUsdPerMillion: 2, outputUsdPerMillion: 6, cacheReadMultiplier: 0.25 },
65
+ "grok-4.6": { inputUsdPerMillion: 2, outputUsdPerMillion: 6, cacheReadMultiplier: 0.25 },
66
+ "minimax/minimax-m2.7": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2, cacheReadMultiplier: 0.2 },
67
+ "minimax/minimax-m3": { inputUsdPerMillion: 0.3, outputUsdPerMillion: 1.2, cacheReadMultiplier: 0.2 },
68
+ "mistralai/mistral-small-2603": { inputUsdPerMillion: 0.2, outputUsdPerMillion: 0.6, cacheReadMultiplier: 0.1 },
69
+ "moonshotai/kimi-k2.5": { inputUsdPerMillion: 0.6, outputUsdPerMillion: 3, cacheReadMultiplier: 0.5 },
70
+ "moonshotai/kimi-k2.6": { inputUsdPerMillion: 0.95, outputUsdPerMillion: 4, cacheReadMultiplier: 0.1684 },
71
+ "moonshotai/kimi-k2.7": { inputUsdPerMillion: 0.95, outputUsdPerMillion: 4, cacheReadMultiplier: 0.2 },
72
+ "moonshotai/kimi-k3": { inputUsdPerMillion: 3, outputUsdPerMillion: 15, cacheReadMultiplier: 0.1 },
73
+ "qwen/qwen3-235b-a22b-2507": { inputUsdPerMillion: 0.2266, outputUsdPerMillion: 0.9064, cacheReadMultiplier: 0.5 },
74
+ "qwen/qwen3-30b-a3b-instruct-2507": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6, cacheReadMultiplier: 0.1684 },
75
+ "qwen/qwen3-coder": { inputUsdPerMillion: 0.9, outputUsdPerMillion: 2.7, cacheReadMultiplier: 0.1684 },
76
+ "qwen/qwen3-coder-next": { inputUsdPerMillion: 0.5, outputUsdPerMillion: 1.2, cacheReadMultiplier: 0.5 },
77
+ "qwen/qwen3-next-80b-a3b-instruct": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 1.2, cacheReadMultiplier: 0.5 },
78
+ "qwen/qwen3.5-flash-02-23": { inputUsdPerMillion: 0.05, outputUsdPerMillion: 0.15, cacheReadMultiplier: 0.1 },
79
+ "qwen/qwen3.6-35b-a3b": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 1, cacheReadMultiplier: 0.1 },
80
+ "qwen/qwen3.7-plus": { inputUsdPerMillion: 0.4, outputUsdPerMillion: 1.6, cacheReadMultiplier: 0.2 },
81
+ "qwen/qwen3.8-max": { inputUsdPerMillion: 2, outputUsdPerMillion: 6, cacheReadMultiplier: 0.125 },
82
+ "xiaomi/mimo-v2.5-pro": { inputUsdPerMillion: 1, outputUsdPerMillion: 3, cacheReadMultiplier: 0.1 },
83
+ "z-ai/glm-5": { inputUsdPerMillion: 1, outputUsdPerMillion: 3.2, cacheReadMultiplier: 0.2 },
84
+ "z-ai/glm-5.1": { inputUsdPerMillion: 1.4, outputUsdPerMillion: 4.4, cacheReadMultiplier: 0.18571428571428572 },
85
+ "z-ai/glm-5.2": { inputUsdPerMillion: 1.4, outputUsdPerMillion: 4.4, cacheReadMultiplier: 0.18571428571428572 },
86
+ "z-ai/glm-5.3": { inputUsdPerMillion: 1.4, outputUsdPerMillion: 4.4, cacheReadMultiplier: 0.18571428571428572 },
87
+ "z-ai/glm-5.3-flash": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.5, cacheReadMultiplier: 0.2 },
86
88
  });
@@ -60,7 +60,7 @@ function normalizedUsage(usage: TokenUsage): TokenUsage | undefined {
60
60
  function modelCostUsd(model: string, usage: TokenUsage): number | undefined {
61
61
  const price = MODEL_PRICING[normalizeModelId(model)];
62
62
  if (!price) return undefined;
63
- const inputTokens = usage.input + 1.25 * usage.cacheWrite + 0.1 * usage.cacheRead;
63
+ const inputTokens = usage.input + 1.25 * usage.cacheWrite + price.cacheReadMultiplier * usage.cacheRead;
64
64
  return (inputTokens * price.inputUsdPerMillion + usage.output * price.outputUsdPerMillion) / 1_000_000;
65
65
  }
66
66
 
package/registry.sh CHANGED
@@ -58,6 +58,7 @@ weave_registry_skill_names() {
58
58
  cursor) [ "$cursor" = yes ] || continue ;;
59
59
  esac
60
60
  printf '%s\n' "$canonical"
61
+ [ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
61
62
  done <<EOF
62
63
  $(weave_registry_rows)
63
64
  EOF
@@ -77,6 +78,7 @@ weave_registry_skill_assets() {
77
78
  cursor) [ "$cursor" = yes ] || continue ;;
78
79
  esac
79
80
  printf '%s\n' "$canonical"
81
+ [ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
80
82
  done <<EOF
81
83
  $(weave_registry_rows)
82
84
  EOF
package/uninstall.sh CHANGED
@@ -42,12 +42,13 @@ WEAVE_REGISTRY_DATA=$(cat <<'WEAVE_REGISTRY_EOF'
42
42
  force-model|fm|prompt|yes|yes|yes|yes|manual|command,skill
43
43
  unforce-model|ufm|prompt|yes|yes|yes|yes|manual|command,skill
44
44
  router-feedback|rf|prompt|yes|yes|yes|no|manual|command,skill
45
- router-off||local-toggle|yes|no|no|no|manual|command
46
- router-on||local-toggle|yes|no|no|no|manual|command
47
- router-status||local-toggle|yes|no|no|no|manual|command
45
+ router-off||local-toggle|yes|yes|no|no|manual|command,skill
46
+ router-on||local-toggle|yes|yes|no|no|manual|command,skill
47
+ router-status||local-toggle|yes|yes|no|no|manual|command,skill
48
48
  router-session||prompt|yes|no|no|no|manual|command
49
- router-models|models|local-toggle|yes|no|no|no|manual|command
49
+ router-models|models|local-toggle|yes|yes|no|no|manual|command,skill
50
50
  disable-routing||local-toggle|no|yes|no|no|manual|skill
51
+ beta||prompt|yes|no|no|yes|manual|command
51
52
  WEAVE_REGISTRY_EOF
52
53
  )
53
54
 
@@ -96,6 +97,7 @@ weave_registry_skill_names() {
96
97
  cursor) [ "$cursor" = yes ] || continue ;;
97
98
  esac
98
99
  printf '%s\n' "$canonical"
100
+ [ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
99
101
  done <<EOF
100
102
  $(weave_registry_rows)
101
103
  EOF
@@ -115,6 +117,7 @@ weave_registry_skill_assets() {
115
117
  cursor) [ "$cursor" = yes ] || continue ;;
116
118
  esac
117
119
  printf '%s\n' "$canonical"
120
+ [ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
118
121
  done <<EOF
119
122
  $(weave_registry_rows)
120
123
  EOF
@@ -202,7 +205,6 @@ fi
202
205
  # Markers must stay in sync with install.sh. Keep verbatim.
203
206
  WEAVE_CODEX_BEGIN_MARKER="# >>> weave-router managed (do not edit between markers) >>>"
204
207
  WEAVE_CODEX_END_MARKER="# <<< weave-router managed <<<"
205
- WEAVE_CODEX_SKILL_MARKER="<!-- weave-router managed disable-routing skill -->"
206
208
 
207
209
  # strip_codex_block rewrites config.toml without the managed block and any
208
210
  # top-level `model_provider = "weave"` that lived outside the markers (which
@@ -521,7 +523,15 @@ if [ "$target" = "codex" ]; then
521
523
  refuse_if_symlink "$codex_dir"
522
524
  fi
523
525
  codex_config_file="$codex_dir/config.toml"
526
+ if [ "$scope" = "user" ] && [ -z "$install_dir" ]; then
527
+ codex_status_file="$HOME/.weave/codex-status.sh"
528
+ else
529
+ codex_status_file="$codex_dir/weave-status.sh"
530
+ fi
531
+ codex_status_disabled_marker="$(dirname "$codex_status_file")/.weave-router-disabled"
524
532
  refuse_if_symlink "$codex_config_file"
533
+ refuse_if_symlink "$codex_status_file"
534
+ refuse_if_symlink "$codex_status_disabled_marker"
525
535
 
526
536
  if [ -f "$codex_config_file" ]; then
527
537
  strip_codex_block "$codex_config_file"
@@ -538,6 +548,25 @@ if [ "$target" = "codex" ]; then
538
548
  info "No Codex config at $codex_config_file (already uninstalled?)"
539
549
  fi
540
550
 
551
+ # A user config with an existing [features] table receives the installer
552
+ # hook setting outside the managed block; remove only our tagged line.
553
+ if [ -f "$codex_config_file" ]; then
554
+ tmp="$(mktemp -t weave-codex-features-uninstall.XXXXXX)"
555
+ awk '$0 != "hooks = true # weave-router managed codex hooks" { print }' "$codex_config_file" >"$tmp"
556
+ mv "$tmp" "$codex_config_file"
557
+ fi
558
+
559
+ if [ -f "$codex_status_file" ]; then
560
+ if grep -Fq '<!-- weave-router managed codex status -->' "$codex_status_file"; then
561
+ rm -f "$codex_status_file"
562
+ rm -f "$codex_status_disabled_marker"
563
+ ok "Removed $codex_status_file"
564
+ rmdir "$(dirname "$codex_status_file")" 2>/dev/null || true
565
+ else
566
+ warn "Leaving user-owned Codex status helper at $codex_status_file untouched."
567
+ fi
568
+ fi
569
+
541
570
  # Remove only the prompt files this installer owns; leave any user-authored
542
571
  # entries in prompts/ alone. The dir itself is dropped only if empty after.
543
572
  codex_prompts_dir="$codex_dir/prompts"
@@ -580,6 +609,13 @@ EOF
580
609
  if grep -Fq "<!-- weave-router managed $canonical skill -->" "$skill_file"; then
581
610
  rm -f "$skill_file"
582
611
  ok "Removed $skill_file"
612
+ # The prompt skills also ship scripts/emit.sh; leaving it behind
613
+ # strands a directory Codex still advertises as a skill.
614
+ emit_file="$skill_dir/scripts/emit.sh"
615
+ if [ ! -L "$skill_dir/scripts" ] && [ ! -L "$emit_file" ] && [ -f "$emit_file" ]; then
616
+ rm -f "$emit_file"
617
+ rmdir "$skill_dir/scripts" 2>/dev/null || true
618
+ fi
583
619
  else
584
620
  warn "Leaving user-owned Codex skill at $skill_file untouched."
585
621
  fi