@kontextmind/kxm 0.7.200 → 0.7.202
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +17 -0
- package/docs/audits/2026-10-gap-audit.md +3 -5
- package/docs/contributing/decisions.md +24 -1
- package/docs/reference/cli-reference.md +7 -7
- package/docs/reference/config-reference.md +4 -2
- package/docs/start/first-workflow.md +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +15 -18
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime-supervisor.js +7 -7
- package/plugins/kxm/dist/runtime.js +15 -15
- package/plugins/kxm/dist/server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-browser-verify/SKILL.md +1 -1
- package/plugins/kxm/src/cli/system.ts +1 -1
- package/plugins/kxm/src/cli.ts +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/modes.ts +5 -5
- package/plugins/kxm/src/pi-producer.ts +1 -1
- package/plugins/kxm/src/subagent-control.ts +2 -2
- package/plugins/kxm/src/template.ts +10 -8
- package/plugins/kxm/src/vision-gate.ts +3 -7
- package/plugins/kxm/src/workforce-names.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -225,6 +225,23 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
225
225
|
|
|
226
226
|
### Changed
|
|
227
227
|
|
|
228
|
+
- **`kxm vision assert` defaults to the admitted OpenRouter GLM route.**
|
|
229
|
+
The built-in route is `openrouter/z-ai/glm-5.3-flash`, invoked as
|
|
230
|
+
`pi --model openrouter/z-ai/glm-5.3-flash`. The old default
|
|
231
|
+
`zai-coding-cn/glm-5.3-flash` is not allowlisted, and that id no longer
|
|
232
|
+
has a special argv. `kxm init` admits the vision route and does not add
|
|
233
|
+
a model file or a roster entry for it. A live accuracy witness is
|
|
234
|
+
`test/core/vision-accuracy.test.ts`. It calls Pi only when
|
|
235
|
+
`OPENROUTER_API_KEY` is set; otherwise it checks
|
|
236
|
+
`test/fixtures/vision/` and does not use the network.
|
|
237
|
+
- **`kxm init` starts the writer on Grok 4.7.** The starter model file is
|
|
238
|
+
`.kxm/models/grok-grok-4-7.yaml` (`grok` / `grok-4.7`, selector
|
|
239
|
+
`xai/grok-4.7`, alias `grok-default`). The writer roster, the built-in
|
|
240
|
+
coder and browser modes, the general subagent default, the Pi producer
|
|
241
|
+
default, and the `kxm routing benchmark` arm list use the same model.
|
|
242
|
+
Guide candidates and selector examples may still show `grok-4.6`.
|
|
243
|
+
`.kxm/prices.yaml` keeps both price rows.
|
|
244
|
+
|
|
228
245
|
- **The planner fallback is Claude Sonnet 5.5.** `claude-fable` stays the
|
|
229
246
|
planner primary. `claude-claude-sonnet-5-5` (`claude` / `claude-sonnet-5.5`,
|
|
230
247
|
selector `anthropic/claude-sonnet-5.5`, read-only, effort `medium`) is the
|
|
@@ -17,7 +17,7 @@ Each fix is a small pull request with squash auto-merge. None of them needs a se
|
|
|
17
17
|
|
|
18
18
|
`kxm suggest` used to treat a keyword as a substring. "guide" and "build" took the feature workflow because they contain `ui`, "author" took vulnerability remediation because it contains `auth`, and "change" took bug-fix because it contains `hang`. Hyphenated keywords such as `circuit-breaker` still match as one token. A prompt with no keyword still selects `feature-implementation` at score 0.
|
|
19
19
|
|
|
20
|
-
`kxm vision assert` accepted `--route` and then ignored it. The flag now selects that Pi model after admission. An unknown route names `kxm routes admit`. A native-vendor id is refused before `pi` starts. The CLI reference documents the command.
|
|
20
|
+
`kxm vision assert` accepted `--route` and then ignored it. The flag now selects that Pi model after admission. An unknown route names `kxm routes admit`. A native-vendor id is refused before `pi` starts. The CLI reference documents the command. That pull request left the built-in default route unchanged. Decision 2 changes it.
|
|
21
21
|
|
|
22
22
|
`kxm init` outside any Git worktree now says to run `git init` and then `kxm init` again. A directory that is not the worktree root still says to run from that root. `kxm hub view` says to start the hub when nothing is listening on a loopback URL, and names the tunnel and `kxm hub bind` for any other URL. An auth proxy or redirect keeps its existing probe note.
|
|
23
23
|
|
|
@@ -66,13 +66,11 @@ Observed on 2026-10-21, before the runner split:
|
|
|
66
66
|
|
|
67
67
|
### 2. The built-in vision route
|
|
68
68
|
|
|
69
|
-
`kxm vision assert`
|
|
70
|
-
|
|
71
|
-
Changing the default needs a vision accuracy witness on the admitted id. This pass kept the verified default argv.
|
|
69
|
+
Approved 2026-10-21 in [pull request #419](https://github.com/kontextmind/kxm/pull/419). `kxm vision assert` defaults to `openrouter/z-ai/glm-5.3-flash` and runs `pi --model <id>` for every route, including that default. `zai-coding-cn/glm-5.3-flash` no longer has a special argv. `kxm init` admits the vision selector and does not write a model file for it. The accuracy witness is `test/fixtures/vision/` and `test/core/vision-accuracy.test.ts`. That test calls Pi only when `OPENROUTER_API_KEY` is set.
|
|
72
70
|
|
|
73
71
|
### 3. The starter writer model
|
|
74
72
|
|
|
75
|
-
`kxm init`
|
|
73
|
+
Approved 2026-10-21 in [pull request #418](https://github.com/kontextmind/kxm/pull/418). `kxm init` admits `xai/grok-4.7`, writes `.kxm/models/grok-grok-4-7.yaml`, and puts that route on the writer roster. `modes.ts`, `subagent-control.ts`, and the Pi producer default name grok-4.7. Glossary and catalog examples that show grok-4.6 stay selector shapes.
|
|
76
74
|
|
|
77
75
|
### 4. Confirm or reverse the defaults already in Tracking
|
|
78
76
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: "Decisions"
|
|
3
3
|
description: "Decisions of medium significance or higher made by automated KXM work in this repository. One entry per decision: the options evaluated with their weights, and why the selected option won. Recorded the turn the decision is taken."
|
|
4
4
|
audience: "agents and maintainers"
|
|
5
|
-
updated: "2026-10-
|
|
5
|
+
updated: "2026-10-21"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Decisions
|
|
@@ -229,3 +229,26 @@ Evidence: `plugins/kxm/src/cli/plugins.ts`, `plugins/kxm/src/session-work.ts`, a
|
|
|
229
229
|
unverified gate.
|
|
230
230
|
Evidence: `plans/implementation-plan.md`, `plans/plan-python-migration.md`,
|
|
231
231
|
`python/kxm-control/tests/test_mg1.py`, and `.github/workflows/ci.yml`.
|
|
232
|
+
|
|
233
|
+
## 2026-10-21 — How `kxm init` admits the vision route (routing)
|
|
234
|
+
|
|
235
|
+
- Context: Eddie approved moving `kxm vision assert` to
|
|
236
|
+
`openrouter/z-ai/glm-5.3-flash` and asked `kxm init` to admit that route
|
|
237
|
+
when the change stays small. The gate checks `.kxm/routes.yaml` only.
|
|
238
|
+
Workforce lint treats an admitted selector with no model file as a warning
|
|
239
|
+
(`admitted_unrouted`), and a model file that no roster names as an error
|
|
240
|
+
(`route_unused`).
|
|
241
|
+
- Options:
|
|
242
|
+
- Admit the selector and skip the model file — weight 0.9. Vision works
|
|
243
|
+
on a fresh project, and dispatch rosters stay the writer and the planner.
|
|
244
|
+
The warning does not fail init or `workforce lint`.
|
|
245
|
+
- Add a model file and put it on a roster — weight 0.3. Clears the warning,
|
|
246
|
+
but it also makes GLM a dispatch candidate for whichever role receives it.
|
|
247
|
+
- Leave init unchanged — weight 0.2. A new project still fail-closes on the
|
|
248
|
+
new default until someone admits the route by hand.
|
|
249
|
+
- Selected: admit the selector only. No model file, no roster entry.
|
|
250
|
+
- Solid recommendation: when a vision role exists, give the route its own
|
|
251
|
+
read-only model file and roster so the warning goes away without sharing
|
|
252
|
+
the writer.
|
|
253
|
+
- Interim recommendation: the admitted selector is enough for `kxm vision assert`.
|
|
254
|
+
Evidence: `plugins/kxm/src/template.ts`, `plugins/kxm/src/workforce-names.mjs`, and `test/core/vision-gate.test.ts`.
|
|
@@ -201,7 +201,7 @@ kxm init --dry-run --json
|
|
|
201
201
|
```
|
|
202
202
|
|
|
203
203
|
```text
|
|
204
|
-
{"schema":"kxm.cli-result.v1","ok":true,"command":"init","action":"planned","mode":"create","inspectedFrom":"/work/proj","projectRoot":"/work/proj","changesRequired":true,"legacyInputs":[],"issues":[],"files":[".kxm/agents/planner.yaml",".kxm/agents/writer.yaml",".kxm/gates.yaml",".kxm/models/claude-fable.yaml",".kxm/models/grok-grok-4-
|
|
204
|
+
{"schema":"kxm.cli-result.v1","ok":true,"command":"init","action":"planned","mode":"create","inspectedFrom":"/work/proj","projectRoot":"/work/proj","changesRequired":true,"legacyInputs":[],"issues":[],"files":[".kxm/agents/planner.yaml",".kxm/agents/writer.yaml",".kxm/gates.yaml",".kxm/models/claude-fable.yaml",".kxm/models/grok-grok-4-7.yaml",".kxm/project.yaml",".kxm/repo/repo.yaml",".kxm/roles/planner.yaml",".kxm/roles/writer.yaml",".kxm/routes.yaml",".kxm/template-provenance.yaml",".kxm/workflows/default.yaml"],"plannedOnly":true}
|
|
205
205
|
```
|
|
206
206
|
|
|
207
207
|
Create the project:
|
|
@@ -922,13 +922,13 @@ kxm vision assert --image <path> --question <text> [--route <id>] [--timeout-ms
|
|
|
922
922
|
|---|---|---|---|
|
|
923
923
|
| `--image` | `<path>` | required | Screenshot file. A missing file fails closed with `image unreadable` |
|
|
924
924
|
| `--question` | `<text>` | required | Yes/no assertion, trimmed to 500 characters inside the prompt |
|
|
925
|
-
| `--route` | `<id>` | `
|
|
925
|
+
| `--route` | `<id>` | `openrouter/z-ai/glm-5.3-flash` | Admitted route id. Pi is invoked as `pi --model <id>` after the native-vendor brake |
|
|
926
926
|
| `--timeout-ms` | `<n>` | `90000` | Integer from 5000 through 300000 |
|
|
927
927
|
| `--expect` | `true` or `false` | none | Exit 0 only when the verdict equals this value |
|
|
928
928
|
|
|
929
929
|
- Global options apply, except `--dry-run`, which exits 2 with `dry_run_unsupported` because the command calls Pi.
|
|
930
|
-
- The route must be listed under `admitted` in `.kxm/routes.yaml`. Otherwise the command exits 1 and the `divergence` names the id and `kxm routes admit --model <id>`.
|
|
931
|
-
-
|
|
930
|
+
- The route must be listed under `admitted` in `.kxm/routes.yaml`. Otherwise the command exits 1 and the `divergence` names the id and `kxm routes admit --model <id>`. `kxm init` admits the default. This repository already admits `openrouter/z-ai/glm-5.3-flash`.
|
|
931
|
+
- A live accuracy witness for that id is `test/fixtures/vision/manifest.json` plus `test/core/vision-accuracy.test.ts`. It calls Pi only when `OPENROUTER_API_KEY` is set. Otherwise it checks the fixture set and does not call the network. Run it with `node --disable-warning=ExperimentalWarning --experimental-strip-types --test --test-force-exit test/core/vision-accuracy.test.ts`.
|
|
932
932
|
- A native-vendor id such as `xai/grok-4.7` or `anthropic/fable` is refused before Pi starts, even when that id is admitted. The `divergence` is the Pi brake message.
|
|
933
933
|
- Exit 0 when the verdict resolves and, if `--expect` is set, matches it. Exit 1 for a fail-closed divergence. Exit 2 when `--image` or `--question` is missing, `--expect` is not `true` or `false`, or `--timeout-ms` is not an integer.
|
|
934
934
|
- JSON keys: `ok`, `command` (`vision assert`), `verdict` (`true`, `false`, or `null`), `route`, `raw`, `divergence` when the gate fails closed, and `expect` when `--expect` is set.
|
|
@@ -3036,7 +3036,7 @@ KXM PRE-FLIGHT CONTEXT EXPLAIN
|
|
|
3036
3036
|
════════════════════════════════════════════════════════════
|
|
3037
3037
|
Major Mode: coder
|
|
3038
3038
|
Enabled Domains: (none)
|
|
3039
|
-
Target Model: grok/grok-4.
|
|
3039
|
+
Target Model: grok/grok-4.7
|
|
3040
3040
|
Catalog status: price catalog missing
|
|
3041
3041
|
|
|
3042
3042
|
CONTEXT BREAKDOWN:
|
|
@@ -3661,7 +3661,7 @@ Dedicated offline benchmark for side-by-side model comparison (Decision Q12). To
|
|
|
3661
3661
|
| Option | Argument | Default | Description |
|
|
3662
3662
|
|---|---|---|---|
|
|
3663
3663
|
| `--task` | `<fixture>` | `Deterministic benchmark task` | Task prompt or fixture path for benchmark comparison |
|
|
3664
|
-
| `--arms` | `<models>` | `grok/grok-4.
|
|
3664
|
+
| `--arms` | `<models>` | `grok/grok-4.7,claude/fable,pi/qwen3.7-plus` | Comma-separated model routes to benchmark (e.g. grok/grok-4.6,claude/fable) |
|
|
3665
3665
|
| `--runs` | `<count>` | `1` | Benchmark runs per arm |
|
|
3666
3666
|
|
|
3667
3667
|
- Reads nothing. JSON keys: `task`, `runs`, `timestamp`, `arms` (`harness`, `model`, `latencyMs`, `tokensIn`, `tokensOut`, `costUsd`, `outcome`).
|
|
@@ -3673,7 +3673,7 @@ kxm routing benchmark
|
|
|
3673
3673
|
```text
|
|
3674
3674
|
Routing Benchmark Results (task: Deterministic benchmark task, runs: 1)
|
|
3675
3675
|
Harness Model Latency(ms) TokensIn TokensOut Cost($) Outcome
|
|
3676
|
-
grok grok-4.
|
|
3676
|
+
grok grok-4.7 420 1200 450 $0.17 passed
|
|
3677
3677
|
claude fable 680 1200 450 $0.45 passed
|
|
3678
3678
|
pi qwen3.7-plus 560 1200 450 $0.12 passed
|
|
3679
3679
|
```
|
|
@@ -398,8 +398,10 @@ resultSchema: kxm.assignment-result.v1
|
|
|
398
398
|
|
|
399
399
|
`kxm init` creates `planner` (`role: planner`, alias `coordinator`) and `writer`
|
|
400
400
|
(`role: writer`, alias `implementer`) without `harness` or `model`, and admits
|
|
401
|
-
`anthropic/fable
|
|
402
|
-
`
|
|
401
|
+
`anthropic/fable`, `xai/grok-4.7`, and the vision route
|
|
402
|
+
`openrouter/z-ai/glm-5.3-flash` in `.kxm/routes.yaml`. The model files are
|
|
403
|
+
`claude-fable` and `grok-grok-4-7`. The vision route has no model file and is
|
|
404
|
+
not a roster entry. An interactive `kxm init` can add
|
|
403
405
|
workflow-guide agents for reviewed pairs whose harness is authenticated, and
|
|
404
406
|
admits their selectors too, but skips Google guide candidates because the
|
|
405
407
|
Runtime cannot reach the `antigravity` Pi provider yet. `kxm run` and the
|
|
@@ -258,7 +258,7 @@ The file is a `kxm.workflow.v1` definition. `coordinator` names the agent that o
|
|
|
258
258
|
|
|
259
259
|
### Why start with `first` and not `default`
|
|
260
260
|
|
|
261
|
-
`kxm init` also writes a `default` workflow. Its coordinator plans on `claude` / `anthropic/fable`, its implementer writes the checkout on `grok` / `xai/grok-4.
|
|
261
|
+
`kxm init` also writes a `default` workflow. Its coordinator plans on `claude` / `anthropic/fable`, its implementer writes the checkout on `grok` / `xai/grok-4.7`, and a `test` gate runs `npm test`. `kxm init` admits those two models and the vision route `openrouter/z-ai/glm-5.3-flash` in `.kxm/routes.yaml`. The vision id has no model file and is not on a roster. You can drive it, but even a simulated drive runs `npm test` in your checkout, and a live drive spends both subscriptions and passes the implement step only when Grok changes the checkout. `first` calls no model and runs no command, so it is the safer first run. [Steps the Runtime does not execute yet](../reference/config-reference.md#steps-the-runtime-does-not-execute-yet) lists every setting that makes a drive hand the run off.
|
|
262
262
|
|
|
263
263
|
### Two kinds of runs
|
|
264
264
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "kxm",
|
|
4
4
|
"displayName": "KXM",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.202",
|
|
6
6
|
"description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "KontextMind",
|
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -18623,7 +18623,7 @@ var init_workforce_names = __esm({
|
|
|
18623
18623
|
["fable-claude", "claude-fable"],
|
|
18624
18624
|
// sol-codex stays the GPT-5.6 route. codex-gpt-6-1-sol is a separate route.
|
|
18625
18625
|
["sol-codex", "codex-gpt-5-6-sol"],
|
|
18626
|
-
["grok-default", "grok-grok-4-
|
|
18626
|
+
["grok-default", "grok-grok-4-7"],
|
|
18627
18627
|
["fable-default", "claude-fable"]
|
|
18628
18628
|
]);
|
|
18629
18629
|
AGENT_RENAMES = Object.freeze([
|
|
@@ -18824,16 +18824,16 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
18824
18824
|
}
|
|
18825
18825
|
files.set(".kxm/routes.yaml", {
|
|
18826
18826
|
schema: "kxm.routes.v2",
|
|
18827
|
-
updatedAt: "2026-
|
|
18828
|
-
admitted: ["anthropic/fable", "xai/grok-4.
|
|
18827
|
+
updatedAt: "2026-10-21T00:00:00.000Z",
|
|
18828
|
+
admitted: ["anthropic/fable", "xai/grok-4.7", "openrouter/z-ai/glm-5.3-flash"],
|
|
18829
18829
|
disabled: []
|
|
18830
18830
|
});
|
|
18831
|
-
files.set(".kxm/models/grok-grok-4-
|
|
18831
|
+
files.set(".kxm/models/grok-grok-4-7.yaml", {
|
|
18832
18832
|
schema: "kxm.model.v2",
|
|
18833
|
-
id: "grok-grok-4-
|
|
18833
|
+
id: "grok-grok-4-7",
|
|
18834
18834
|
aliases: ["grok-default"],
|
|
18835
18835
|
harness: "grok",
|
|
18836
|
-
model: "grok-4.
|
|
18836
|
+
model: "grok-4.7",
|
|
18837
18837
|
vendor: "xai",
|
|
18838
18838
|
status: "admitted",
|
|
18839
18839
|
permissions: ["edit"]
|
|
@@ -18854,7 +18854,7 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
18854
18854
|
purpose: "writer",
|
|
18855
18855
|
permission: "edit",
|
|
18856
18856
|
description: "Primary implementation agent.",
|
|
18857
|
-
roster: [{ route: "grok-grok-4-
|
|
18857
|
+
roster: [{ route: "grok-grok-4-7", effort: "medium" }]
|
|
18858
18858
|
});
|
|
18859
18859
|
files.set(".kxm/roles/planner.yaml", {
|
|
18860
18860
|
schema: "kxm.role.v2",
|
|
@@ -28904,9 +28904,6 @@ function parseVisionVerdict(raw) {
|
|
|
28904
28904
|
return match ? match[1] === "true" : null;
|
|
28905
28905
|
}
|
|
28906
28906
|
function visionPiArgs(route) {
|
|
28907
|
-
if (route === VISION_GATE_DEFAULT_ROUTE) {
|
|
28908
|
-
return { ok: true, args: ["--provider", "zai-coding-cn", "--model", "glm-5.3-flash", "-p", "--no-session"] };
|
|
28909
|
-
}
|
|
28910
28907
|
const validation = validateHarnessModelPair("pi", route);
|
|
28911
28908
|
if (!validation.valid) {
|
|
28912
28909
|
return { ok: false, divergence: validation.message ?? "route_not_pi" };
|
|
@@ -28959,7 +28956,7 @@ var init_vision_gate = __esm({
|
|
|
28959
28956
|
"use strict";
|
|
28960
28957
|
init_harness();
|
|
28961
28958
|
init_routes();
|
|
28962
|
-
VISION_GATE_DEFAULT_ROUTE = "
|
|
28959
|
+
VISION_GATE_DEFAULT_ROUTE = "openrouter/z-ai/glm-5.3-flash";
|
|
28963
28960
|
QUESTION_MAX_CHARS = 500;
|
|
28964
28961
|
RAW_MAX_CHARS = 2e3;
|
|
28965
28962
|
}
|
|
@@ -55403,7 +55400,7 @@ var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
|
55403
55400
|
baseTools: ["read", "edit", "write", "bash"],
|
|
55404
55401
|
contextFiles: ["AGENTS.md"],
|
|
55405
55402
|
thinkingLevel: "medium",
|
|
55406
|
-
model: "grok/grok-4.
|
|
55403
|
+
model: "grok/grok-4.7"
|
|
55407
55404
|
},
|
|
55408
55405
|
planner: {
|
|
55409
55406
|
description: "High-level architectural planning, scoping, and decomposition",
|
|
@@ -55424,7 +55421,7 @@ var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
|
55424
55421
|
baseTools: ["read", "bash"],
|
|
55425
55422
|
contextFiles: ["docs/guides/browser-automation.md"],
|
|
55426
55423
|
thinkingLevel: "medium",
|
|
55427
|
-
model: "grok/grok-4.
|
|
55424
|
+
model: "grok/grok-4.7"
|
|
55428
55425
|
}
|
|
55429
55426
|
},
|
|
55430
55427
|
domains: {
|
|
@@ -55501,7 +55498,7 @@ function resolveActiveMode(config, majorModeName = "coder", domainNames = []) {
|
|
|
55501
55498
|
contextFiles: Array.from(contextFiles),
|
|
55502
55499
|
promptSnippets,
|
|
55503
55500
|
thinkingLevel: major.thinkingLevel,
|
|
55504
|
-
model: major.model || "grok/grok-4.
|
|
55501
|
+
model: major.model || "grok/grok-4.7"
|
|
55505
55502
|
};
|
|
55506
55503
|
}
|
|
55507
55504
|
var CATALOG_DATE_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
@@ -55592,7 +55589,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
55592
55589
|
catalogDateForStatus(loaded2, catalog, projectRoot)
|
|
55593
55590
|
);
|
|
55594
55591
|
const cat = loaded2.catalog;
|
|
55595
|
-
const rawModel = resolved.model || "grok/grok-4.
|
|
55592
|
+
const rawModel = resolved.model || "grok/grok-4.7";
|
|
55596
55593
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [void 0, rawModel];
|
|
55597
55594
|
const inputCost = cat ? calculateModelCost(cat, {
|
|
55598
55595
|
model: mod || rawModel,
|
|
@@ -55621,7 +55618,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
55621
55618
|
return {
|
|
55622
55619
|
majorMode: resolved.majorMode,
|
|
55623
55620
|
enabledDomains: resolved.enabledDomains,
|
|
55624
|
-
model: resolved.model || "grok/grok-4.
|
|
55621
|
+
model: resolved.model || "grok/grok-4.7",
|
|
55625
55622
|
breakdown,
|
|
55626
55623
|
totalChars,
|
|
55627
55624
|
totalTokens,
|
|
@@ -58146,7 +58143,7 @@ async function cmdRoutingReport(runtime, options) {
|
|
|
58146
58143
|
}
|
|
58147
58144
|
async function cmdRoutingBenchmark(runtime, options) {
|
|
58148
58145
|
const task = options.task || "Deterministic benchmark task";
|
|
58149
|
-
const armsStr = options.arms || "grok/grok-4.
|
|
58146
|
+
const armsStr = options.arms || "grok/grok-4.7,claude/fable,pi/qwen3.7-plus";
|
|
58150
58147
|
const armsList = armsStr.split(",").map((s) => s.trim()).filter(Boolean);
|
|
58151
58148
|
const runsCount = Math.max(1, parseInt(options.runs || "1", 10) || 1);
|
|
58152
58149
|
const arms = armsList.map((arm) => {
|
|
@@ -58732,7 +58729,7 @@ function createProgram(ctx, result, argv) {
|
|
|
58732
58729
|
}
|
|
58733
58730
|
const visionCmd = addGlobalOptions(program2.command("vision").description("Judge captured UI screenshots through the admitted vision gate"));
|
|
58734
58731
|
visionCmd.helpCommand("help", "Show vision help");
|
|
58735
|
-
addGlobalOptions(visionCmd.command("assert").description("Assert a UI state on a screenshot (deterministic vision gate)")).requiredOption("--image <path>", "Path to the captured screenshot").requiredOption("--question <text>", "Yes/no assertion to verify on the screenshot").option("--route <id>", `Vision route (default ${"
|
|
58732
|
+
addGlobalOptions(visionCmd.command("assert").description("Assert a UI state on a screenshot (deterministic vision gate)")).requiredOption("--image <path>", "Path to the captured screenshot").requiredOption("--question <text>", "Yes/no assertion to verify on the screenshot").option("--route <id>", `Vision route (default ${"openrouter/z-ai/glm-5.3-flash"})`).option("--timeout-ms <n>", "Transport timeout in milliseconds (5000-300000)").option("--expect <bool>", "Exit 0 only when the verdict matches true|false").action(async function visionAssertAction(options) {
|
|
58736
58733
|
result.code = await cmdVisionAssert(runtimeFrom(ctx, this), options ?? {});
|
|
58737
58734
|
});
|
|
58738
58735
|
const harnessCmd = addGlobalOptions(program2.command("harness").description("Detect coding-agent harnesses and authentication"));
|
|
@@ -25462,7 +25462,7 @@ function sessionTokenFixHint(policy) {
|
|
|
25462
25462
|
}
|
|
25463
25463
|
|
|
25464
25464
|
// plugins/kxm/src/mcp-server.ts
|
|
25465
|
-
var VERSION = "0.7.
|
|
25465
|
+
var VERSION = "0.7.202";
|
|
25466
25466
|
var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
25467
25467
|
var inbox = /* @__PURE__ */ new Map();
|
|
25468
25468
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
|
@@ -15547,7 +15547,7 @@ var ROUTE_RENAMES = Object.freeze([
|
|
|
15547
15547
|
["fable-claude", "claude-fable"],
|
|
15548
15548
|
// sol-codex stays the GPT-5.6 route. codex-gpt-6-1-sol is a separate route.
|
|
15549
15549
|
["sol-codex", "codex-gpt-5-6-sol"],
|
|
15550
|
-
["grok-default", "grok-grok-4-
|
|
15550
|
+
["grok-default", "grok-grok-4-7"],
|
|
15551
15551
|
["fable-default", "claude-fable"]
|
|
15552
15552
|
]);
|
|
15553
15553
|
var AGENT_RENAMES = Object.freeze([
|
|
@@ -15972,16 +15972,16 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
15972
15972
|
}
|
|
15973
15973
|
files.set(".kxm/routes.yaml", {
|
|
15974
15974
|
schema: "kxm.routes.v2",
|
|
15975
|
-
updatedAt: "2026-
|
|
15976
|
-
admitted: ["anthropic/fable", "xai/grok-4.
|
|
15975
|
+
updatedAt: "2026-10-21T00:00:00.000Z",
|
|
15976
|
+
admitted: ["anthropic/fable", "xai/grok-4.7", "openrouter/z-ai/glm-5.3-flash"],
|
|
15977
15977
|
disabled: []
|
|
15978
15978
|
});
|
|
15979
|
-
files.set(".kxm/models/grok-grok-4-
|
|
15979
|
+
files.set(".kxm/models/grok-grok-4-7.yaml", {
|
|
15980
15980
|
schema: "kxm.model.v2",
|
|
15981
|
-
id: "grok-grok-4-
|
|
15981
|
+
id: "grok-grok-4-7",
|
|
15982
15982
|
aliases: ["grok-default"],
|
|
15983
15983
|
harness: "grok",
|
|
15984
|
-
model: "grok-4.
|
|
15984
|
+
model: "grok-4.7",
|
|
15985
15985
|
vendor: "xai",
|
|
15986
15986
|
status: "admitted",
|
|
15987
15987
|
permissions: ["edit"]
|
|
@@ -16002,7 +16002,7 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
16002
16002
|
purpose: "writer",
|
|
16003
16003
|
permission: "edit",
|
|
16004
16004
|
description: "Primary implementation agent.",
|
|
16005
|
-
roster: [{ route: "grok-grok-4-
|
|
16005
|
+
roster: [{ route: "grok-grok-4-7", effort: "medium" }]
|
|
16006
16006
|
});
|
|
16007
16007
|
files.set(".kxm/roles/planner.yaml", {
|
|
16008
16008
|
schema: "kxm.role.v2",
|
|
@@ -15520,7 +15520,7 @@ var ROUTE_RENAMES = Object.freeze([
|
|
|
15520
15520
|
["fable-claude", "claude-fable"],
|
|
15521
15521
|
// sol-codex stays the GPT-5.6 route. codex-gpt-6-1-sol is a separate route.
|
|
15522
15522
|
["sol-codex", "codex-gpt-5-6-sol"],
|
|
15523
|
-
["grok-default", "grok-grok-4-
|
|
15523
|
+
["grok-default", "grok-grok-4-7"],
|
|
15524
15524
|
["fable-default", "claude-fable"]
|
|
15525
15525
|
]);
|
|
15526
15526
|
var AGENT_RENAMES = Object.freeze([
|
|
@@ -15945,16 +15945,16 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
15945
15945
|
}
|
|
15946
15946
|
files.set(".kxm/routes.yaml", {
|
|
15947
15947
|
schema: "kxm.routes.v2",
|
|
15948
|
-
updatedAt: "2026-
|
|
15949
|
-
admitted: ["anthropic/fable", "xai/grok-4.
|
|
15948
|
+
updatedAt: "2026-10-21T00:00:00.000Z",
|
|
15949
|
+
admitted: ["anthropic/fable", "xai/grok-4.7", "openrouter/z-ai/glm-5.3-flash"],
|
|
15950
15950
|
disabled: []
|
|
15951
15951
|
});
|
|
15952
|
-
files.set(".kxm/models/grok-grok-4-
|
|
15952
|
+
files.set(".kxm/models/grok-grok-4-7.yaml", {
|
|
15953
15953
|
schema: "kxm.model.v2",
|
|
15954
|
-
id: "grok-grok-4-
|
|
15954
|
+
id: "grok-grok-4-7",
|
|
15955
15955
|
aliases: ["grok-default"],
|
|
15956
15956
|
harness: "grok",
|
|
15957
|
-
model: "grok-4.
|
|
15957
|
+
model: "grok-4.7",
|
|
15958
15958
|
vendor: "xai",
|
|
15959
15959
|
status: "admitted",
|
|
15960
15960
|
permissions: ["edit"]
|
|
@@ -15975,7 +15975,7 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
15975
15975
|
purpose: "writer",
|
|
15976
15976
|
permission: "edit",
|
|
15977
15977
|
description: "Primary implementation agent.",
|
|
15978
|
-
roster: [{ route: "grok-grok-4-
|
|
15978
|
+
roster: [{ route: "grok-grok-4-7", effort: "medium" }]
|
|
15979
15979
|
});
|
|
15980
15980
|
files.set(".kxm/roles/planner.yaml", {
|
|
15981
15981
|
schema: "kxm.role.v2",
|
|
@@ -34555,7 +34555,7 @@ var PiSession = class {
|
|
|
34555
34555
|
};
|
|
34556
34556
|
function createKxmPiProducer(options = {}) {
|
|
34557
34557
|
const sessions = /* @__PURE__ */ new Map();
|
|
34558
|
-
const defaultModel = options.defaultModel ?? "xai/grok-4.
|
|
34558
|
+
const defaultModel = options.defaultModel ?? "xai/grok-4.7";
|
|
34559
34559
|
const defaultProvider = options.defaultProvider ?? "xai";
|
|
34560
34560
|
function parseModelString(spec) {
|
|
34561
34561
|
const trimmed = spec.trim();
|
|
@@ -35776,7 +35776,7 @@ var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
|
35776
35776
|
baseTools: ["read", "edit", "write", "bash"],
|
|
35777
35777
|
contextFiles: ["AGENTS.md"],
|
|
35778
35778
|
thinkingLevel: "medium",
|
|
35779
|
-
model: "grok/grok-4.
|
|
35779
|
+
model: "grok/grok-4.7"
|
|
35780
35780
|
},
|
|
35781
35781
|
planner: {
|
|
35782
35782
|
description: "High-level architectural planning, scoping, and decomposition",
|
|
@@ -35797,7 +35797,7 @@ var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
|
35797
35797
|
baseTools: ["read", "bash"],
|
|
35798
35798
|
contextFiles: ["docs/guides/browser-automation.md"],
|
|
35799
35799
|
thinkingLevel: "medium",
|
|
35800
|
-
model: "grok/grok-4.
|
|
35800
|
+
model: "grok/grok-4.7"
|
|
35801
35801
|
}
|
|
35802
35802
|
},
|
|
35803
35803
|
domains: {
|
|
@@ -35874,7 +35874,7 @@ function resolveActiveMode(config, majorModeName = "coder", domainNames = []) {
|
|
|
35874
35874
|
contextFiles: Array.from(contextFiles),
|
|
35875
35875
|
promptSnippets,
|
|
35876
35876
|
thinkingLevel: major.thinkingLevel,
|
|
35877
|
-
model: major.model || "grok/grok-4.
|
|
35877
|
+
model: major.model || "grok/grok-4.7"
|
|
35878
35878
|
};
|
|
35879
35879
|
}
|
|
35880
35880
|
var CATALOG_DATE_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
@@ -35965,7 +35965,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
35965
35965
|
catalogDateForStatus(loaded, catalog, projectRoot)
|
|
35966
35966
|
);
|
|
35967
35967
|
const cat = loaded.catalog;
|
|
35968
|
-
const rawModel = resolved.model || "grok/grok-4.
|
|
35968
|
+
const rawModel = resolved.model || "grok/grok-4.7";
|
|
35969
35969
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [void 0, rawModel];
|
|
35970
35970
|
const inputCost = cat ? calculateModelCost(cat, {
|
|
35971
35971
|
model: mod || rawModel,
|
|
@@ -35994,7 +35994,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
35994
35994
|
return {
|
|
35995
35995
|
majorMode: resolved.majorMode,
|
|
35996
35996
|
enabledDomains: resolved.enabledDomains,
|
|
35997
|
-
model: resolved.model || "grok/grok-4.
|
|
35997
|
+
model: resolved.model || "grok/grok-4.7",
|
|
35998
35998
|
breakdown,
|
|
35999
35999
|
totalChars,
|
|
36000
36000
|
totalTokens,
|
|
@@ -36451,7 +36451,7 @@ var SUBAGENT_TYPES = Object.freeze([
|
|
|
36451
36451
|
"Auditor"
|
|
36452
36452
|
]);
|
|
36453
36453
|
var DEFAULT_SUBAGENT_MODELS = Object.freeze({
|
|
36454
|
-
general: "grok/grok-4.
|
|
36454
|
+
general: "grok/grok-4.7",
|
|
36455
36455
|
Explore: "openrouter/qwen/qwen3.7-plus",
|
|
36456
36456
|
Plan: "claude/fable",
|
|
36457
36457
|
Reviewer: "openai/gpt-5.6-sol",
|
|
@@ -36491,7 +36491,7 @@ var SubagentManager = class {
|
|
|
36491
36491
|
throw new Error('Subagent "description" is required.');
|
|
36492
36492
|
}
|
|
36493
36493
|
const type = params.type ?? "general";
|
|
36494
|
-
const model = params.model ?? DEFAULT_SUBAGENT_MODELS[type] ?? "grok/grok-4.
|
|
36494
|
+
const model = params.model ?? DEFAULT_SUBAGENT_MODELS[type] ?? "grok/grok-4.7";
|
|
36495
36495
|
const thinking = params.thinking ?? "low";
|
|
36496
36496
|
const allowedTools = narrowSubagentTools(params.allowed_tools, params.parent_tools);
|
|
36497
36497
|
const id = `ag_${randomUUID5().replaceAll("-", "").slice(0, 10)}`;
|
|
@@ -15012,7 +15012,7 @@ var ROUTE_RENAMES = Object.freeze([
|
|
|
15012
15012
|
["fable-claude", "claude-fable"],
|
|
15013
15013
|
// sol-codex stays the GPT-5.6 route. codex-gpt-6-1-sol is a separate route.
|
|
15014
15014
|
["sol-codex", "codex-gpt-5-6-sol"],
|
|
15015
|
-
["grok-default", "grok-grok-4-
|
|
15015
|
+
["grok-default", "grok-grok-4-7"],
|
|
15016
15016
|
["fable-default", "claude-fable"]
|
|
15017
15017
|
]);
|
|
15018
15018
|
var AGENT_RENAMES = Object.freeze([
|
package/plugins/kxm/package.json
CHANGED
|
@@ -106,5 +106,5 @@ kxm vision assert --image .kxm/artifacts/browser/shot.png \
|
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
- Exit 0 only when the verdict resolves and matches `--expect`; fail-closed divergences (`route_not_admitted`, `image unreadable`, `verdict unreadable`, or the Pi native-vendor brake) exit 1.
|
|
109
|
-
- The route must be admitted in `.kxm/routes.yaml`. The built-in default is `
|
|
109
|
+
- The route must be admitted in `.kxm/routes.yaml`. The built-in default is `openrouter/z-ai/glm-5.3-flash`, invoked as `pi --model openrouter/z-ai/glm-5.3-flash`. `kxm init` admits that id, and this checkout already admits it. `--route` selects the Pi model; a native-vendor id is refused before Pi starts.
|
|
110
110
|
- The gate is a supplement to deterministic Playwright assertions, never a replacement.
|
|
@@ -1071,7 +1071,7 @@ export async function cmdRoutingBenchmark(
|
|
|
1071
1071
|
options: { task?: string | undefined; arms?: string | undefined; runs?: string | undefined },
|
|
1072
1072
|
): Promise<number> {
|
|
1073
1073
|
const task = options.task || "Deterministic benchmark task";
|
|
1074
|
-
const armsStr = options.arms || "grok/grok-4.
|
|
1074
|
+
const armsStr = options.arms || "grok/grok-4.7,claude/fable,pi/qwen3.7-plus";
|
|
1075
1075
|
const armsList = armsStr.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1076
1076
|
const runsCount = Math.max(1, parseInt(options.runs || "1", 10) || 1);
|
|
1077
1077
|
|
package/plugins/kxm/src/cli.ts
CHANGED
|
@@ -757,7 +757,7 @@ function createProgram(ctx: CliContext, result: { code: number }, argv: readonly
|
|
|
757
757
|
addGlobalOptions(visionCmd.command("assert").description("Assert a UI state on a screenshot (deterministic vision gate)"))
|
|
758
758
|
.requiredOption("--image <path>", "Path to the captured screenshot")
|
|
759
759
|
.requiredOption("--question <text>", "Yes/no assertion to verify on the screenshot")
|
|
760
|
-
.option("--route <id>", `Vision route (default ${"
|
|
760
|
+
.option("--route <id>", `Vision route (default ${"openrouter/z-ai/glm-5.3-flash"})`)
|
|
761
761
|
.option("--timeout-ms <n>", "Transport timeout in milliseconds (5000-300000)")
|
|
762
762
|
.option("--expect <bool>", "Exit 0 only when the verdict matches true|false")
|
|
763
763
|
.action(async function visionAssertAction(this: Command, options: { image?: string; question?: string; route?: string; timeoutMs?: string; expect?: string }) { result.code = await cmdVisionAssert(runtimeFrom(ctx, this), options ?? {}); });
|
|
@@ -11,7 +11,7 @@ import { deliverInboxNotification } from "./inbox.ts";
|
|
|
11
11
|
import type { HubEvent, MessageRecord } from "./protocol.ts";
|
|
12
12
|
import { sessionTokenFixHint } from "./session-token-hint.ts";
|
|
13
13
|
|
|
14
|
-
const VERSION = "0.7.
|
|
14
|
+
const VERSION = "0.7.202";
|
|
15
15
|
const CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
16
16
|
const inbox = new Map<string, MessageRecord>();
|
|
17
17
|
const notifiedInbox = new Set<string>();
|
package/plugins/kxm/src/modes.ts
CHANGED
|
@@ -80,7 +80,7 @@ export const DEFAULT_MODES_CONFIG: ModesConfig = Object.freeze({
|
|
|
80
80
|
baseTools: ["read", "edit", "write", "bash"],
|
|
81
81
|
contextFiles: ["AGENTS.md"],
|
|
82
82
|
thinkingLevel: "medium" as const,
|
|
83
|
-
model: "grok/grok-4.
|
|
83
|
+
model: "grok/grok-4.7",
|
|
84
84
|
},
|
|
85
85
|
planner: {
|
|
86
86
|
description: "High-level architectural planning, scoping, and decomposition",
|
|
@@ -101,7 +101,7 @@ export const DEFAULT_MODES_CONFIG: ModesConfig = Object.freeze({
|
|
|
101
101
|
baseTools: ["read", "bash"],
|
|
102
102
|
contextFiles: ["docs/guides/browser-automation.md"],
|
|
103
103
|
thinkingLevel: "medium" as const,
|
|
104
|
-
model: "grok/grok-4.
|
|
104
|
+
model: "grok/grok-4.7",
|
|
105
105
|
},
|
|
106
106
|
},
|
|
107
107
|
domains: {
|
|
@@ -201,7 +201,7 @@ export function resolveActiveMode(
|
|
|
201
201
|
contextFiles: Array.from(contextFiles),
|
|
202
202
|
promptSnippets,
|
|
203
203
|
thinkingLevel: major.thinkingLevel,
|
|
204
|
-
model: major.model || "grok/grok-4.
|
|
204
|
+
model: major.model || "grok/grok-4.7",
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -330,7 +330,7 @@ export function calculatePromptFootprint(
|
|
|
330
330
|
catalogDateForStatus(loaded, catalog, projectRoot),
|
|
331
331
|
);
|
|
332
332
|
const cat = loaded.catalog;
|
|
333
|
-
const rawModel = resolved.model || "grok/grok-4.
|
|
333
|
+
const rawModel = resolved.model || "grok/grok-4.7";
|
|
334
334
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [undefined, rawModel];
|
|
335
335
|
|
|
336
336
|
const inputCost = cat
|
|
@@ -369,7 +369,7 @@ export function calculatePromptFootprint(
|
|
|
369
369
|
return {
|
|
370
370
|
majorMode: resolved.majorMode,
|
|
371
371
|
enabledDomains: resolved.enabledDomains,
|
|
372
|
-
model: resolved.model || "grok/grok-4.
|
|
372
|
+
model: resolved.model || "grok/grok-4.7",
|
|
373
373
|
breakdown,
|
|
374
374
|
totalChars,
|
|
375
375
|
totalTokens,
|
|
@@ -448,7 +448,7 @@ export interface KxmPiProducer extends KxmProducer {
|
|
|
448
448
|
|
|
449
449
|
export function createKxmPiProducer(options: KxmPiProducerOptions = {}): KxmPiProducer {
|
|
450
450
|
const sessions = new Map<string, PiSession>();
|
|
451
|
-
const defaultModel = options.defaultModel ?? "xai/grok-4.
|
|
451
|
+
const defaultModel = options.defaultModel ?? "xai/grok-4.7";
|
|
452
452
|
const defaultProvider = options.defaultProvider ?? "xai";
|
|
453
453
|
|
|
454
454
|
function parseModelString(spec: string): { provider: string; model: string } {
|
|
@@ -76,7 +76,7 @@ export const SUBAGENT_TYPES: readonly SubagentType[] = Object.freeze([
|
|
|
76
76
|
]);
|
|
77
77
|
|
|
78
78
|
export const DEFAULT_SUBAGENT_MODELS: Readonly<Record<SubagentType, string>> = Object.freeze({
|
|
79
|
-
general: "grok/grok-4.
|
|
79
|
+
general: "grok/grok-4.7",
|
|
80
80
|
Explore: "openrouter/qwen/qwen3.7-plus",
|
|
81
81
|
Plan: "claude/fable",
|
|
82
82
|
Reviewer: "openai/gpt-5.6-sol",
|
|
@@ -135,7 +135,7 @@ export class SubagentManager {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
const type = params.type ?? "general";
|
|
138
|
-
const model = params.model ?? DEFAULT_SUBAGENT_MODELS[type] ?? "grok/grok-4.
|
|
138
|
+
const model = params.model ?? DEFAULT_SUBAGENT_MODELS[type] ?? "grok/grok-4.7";
|
|
139
139
|
const thinking = params.thinking ?? "low";
|
|
140
140
|
const allowedTools = narrowSubagentTools(params.allowed_tools, params.parent_tools);
|
|
141
141
|
const id = `ag_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
|
|
@@ -209,22 +209,24 @@ function coreTemplate(projectId: string, projectName: string, variant: KxmTempla
|
|
|
209
209
|
});
|
|
210
210
|
files.set(".kxm/workflows/default.yaml", { ...workflow, coordinator: "planner", limits, steps });
|
|
211
211
|
}
|
|
212
|
-
// The two models the template names,
|
|
213
|
-
//
|
|
212
|
+
// The two roster models the template names, plus the vision selector the
|
|
213
|
+
// built-in gate defaults to. That selector has no model file and is not a
|
|
214
|
+
// roster route. A fresh project can be driven without falling through to
|
|
215
|
+
// an unadmitted default model.
|
|
214
216
|
// Route ids follow <harness>-<model-slug>. grok-default and fable-default
|
|
215
217
|
// remain aliases so an existing --route flag still resolves.
|
|
216
218
|
files.set(".kxm/routes.yaml", {
|
|
217
219
|
schema: "kxm.routes.v2",
|
|
218
|
-
updatedAt: "2026-
|
|
219
|
-
admitted: ["anthropic/fable", "xai/grok-4.
|
|
220
|
+
updatedAt: "2026-10-21T00:00:00.000Z",
|
|
221
|
+
admitted: ["anthropic/fable", "xai/grok-4.7", "openrouter/z-ai/glm-5.3-flash"],
|
|
220
222
|
disabled: [],
|
|
221
223
|
});
|
|
222
|
-
files.set(".kxm/models/grok-grok-4-
|
|
224
|
+
files.set(".kxm/models/grok-grok-4-7.yaml", {
|
|
223
225
|
schema: "kxm.model.v2",
|
|
224
|
-
id: "grok-grok-4-
|
|
226
|
+
id: "grok-grok-4-7",
|
|
225
227
|
aliases: ["grok-default"],
|
|
226
228
|
harness: "grok",
|
|
227
|
-
model: "grok-4.
|
|
229
|
+
model: "grok-4.7",
|
|
228
230
|
vendor: "xai",
|
|
229
231
|
status: "admitted",
|
|
230
232
|
permissions: ["edit"],
|
|
@@ -245,7 +247,7 @@ function coreTemplate(projectId: string, projectName: string, variant: KxmTempla
|
|
|
245
247
|
purpose: "writer",
|
|
246
248
|
permission: "edit",
|
|
247
249
|
description: "Primary implementation agent.",
|
|
248
|
-
roster: [{ route: "grok-grok-4-
|
|
250
|
+
roster: [{ route: "grok-grok-4-7", effort: "medium" }],
|
|
249
251
|
});
|
|
250
252
|
files.set(".kxm/roles/planner.yaml", {
|
|
251
253
|
schema: "kxm.role.v2",
|
|
@@ -10,7 +10,7 @@ import { isRouteAdmitted } from "./routes.ts";
|
|
|
10
10
|
* `divergence` reason. Transport is injectable so tests run without
|
|
11
11
|
* network. */
|
|
12
12
|
|
|
13
|
-
export const VISION_GATE_DEFAULT_ROUTE = "
|
|
13
|
+
export const VISION_GATE_DEFAULT_ROUTE = "openrouter/z-ai/glm-5.3-flash";
|
|
14
14
|
const QUESTION_MAX_CHARS = 500;
|
|
15
15
|
const RAW_MAX_CHARS = 2000;
|
|
16
16
|
|
|
@@ -54,13 +54,9 @@ export function parseVisionVerdict(raw: string): boolean | null {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/** Pi argv for an admitted vision route, without the prompt.
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* `--route` selects the model instead of only the admission check. */
|
|
57
|
+
* Every id, including the default, is `pi --model <id>` after the
|
|
58
|
+
* native-vendor brake, so `--route` selects the model. */
|
|
60
59
|
export function visionPiArgs(route: string): { ok: true; args: readonly string[] } | { ok: false; divergence: string } {
|
|
61
|
-
if (route === VISION_GATE_DEFAULT_ROUTE) {
|
|
62
|
-
return { ok: true, args: ["--provider", "zai-coding-cn", "--model", "glm-5.3-flash", "-p", "--no-session"] };
|
|
63
|
-
}
|
|
64
60
|
const validation = validateHarnessModelPair("pi", route);
|
|
65
61
|
if (!validation.valid) {
|
|
66
62
|
return { ok: false, divergence: validation.message ?? "route_not_pi" };
|
|
@@ -38,7 +38,7 @@ export const ROUTE_RENAMES = Object.freeze([
|
|
|
38
38
|
["fable-claude", "claude-fable"],
|
|
39
39
|
// sol-codex stays the GPT-5.6 route. codex-gpt-6-1-sol is a separate route.
|
|
40
40
|
["sol-codex", "codex-gpt-5-6-sol"],
|
|
41
|
-
["grok-default", "grok-grok-4-
|
|
41
|
+
["grok-default", "grok-grok-4-7"],
|
|
42
42
|
["fable-default", "claude-fable"],
|
|
43
43
|
]);
|
|
44
44
|
|