opencode-harness-kit 0.2.1 → 0.3.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +303 -0
  2. package/GLOBAL.md +50 -13
  3. package/MIGRATION.md +140 -0
  4. package/README.md +233 -116
  5. package/bin/oc-harness.mjs +474 -96
  6. package/dist/index.js +378 -155
  7. package/docs/KNOWN-LIMITS.md +189 -4
  8. package/docs/RESEARCH.md +80 -5
  9. package/docs/ROUTING.md +254 -0
  10. package/lanes.json +136 -0
  11. package/lanes.schema.json +55 -0
  12. package/package.json +12 -8
  13. package/profiles/beam-free.json +51 -0
  14. package/profiles/big-pickle.json +45 -0
  15. package/profiles/deepseek-v4.1-flash-free.json +49 -0
  16. package/profiles/fleet-all.json +139 -0
  17. package/profiles/fleet-safe.json +139 -0
  18. package/profiles/glm-5.3-flash-free.json +49 -0
  19. package/profiles/index.json +120 -37
  20. package/profiles/longcat-2.5-preview-free.json +14 -10
  21. package/profiles/mimo-v2.6-flash-free.json +44 -0
  22. package/profiles/minimax-m3.1-flash-free.json +51 -0
  23. package/profiles/nemotron-3-ultra-free.json +44 -0
  24. package/profiles/nemotron-3.5-lightning-free.json +44 -0
  25. package/profiles/nemotron-3.5-super-vl-free.json +52 -0
  26. package/profiles/schema.json +30 -11
  27. package/{agents → prompts}/build.md +2 -35
  28. package/prompts/doc.md +42 -0
  29. package/{agents → prompts}/locate.md +1 -16
  30. package/prompts/longform.md +34 -0
  31. package/{agents → prompts}/plan.md +2 -25
  32. package/{agents → prompts}/reviewer.md +2 -22
  33. package/prompts/schema.md +30 -0
  34. package/prompts/sweep.md +29 -0
  35. package/{agents → prompts}/verify.md +6 -29
  36. package/prompts/vision.md +33 -0
  37. package/retention.yml +75 -57
  38. package/skills/space-build/SKILL.md +16 -0
  39. package/skills/space-review/SKILL.md +8 -0
  40. package/src/config.js +94 -69
  41. package/src/effort.js +59 -22
  42. package/src/index.ts +15 -2
  43. package/src/lane-usage.js +142 -0
  44. package/src/profile.js +502 -212
  45. package/src/router.ts +148 -39
  46. package/src/telemetry.ts +98 -0
  47. package/examples/muse-spark-1.3-contributor-free.json +0 -41
  48. package/profiles/deepseek-v4-flash-free.json +0 -41
  49. package/profiles/muse-split-free.json +0 -64
  50. package/profiles/space-bunny-free.json +0 -42
  51. package/profiles/x-preview-f-free.json +0 -41
@@ -0,0 +1,49 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh glm-5.3-flash-free`.",
3
+ "id": "glm-5.3-flash-free",
4
+ "title": "GLM 5.3 Flash Free",
5
+ "provider": "opencode",
6
+ "model": "glm-5.3-flash-free",
7
+ "family": "glm-flash",
8
+ "verified": "2026-10-19",
9
+ "retention": "zero-retention",
10
+ "notes": "Zhipu. The only free model that publishes pdf input, and the only one with structured output and a zero-retention policy at the same time. The pdf does not work: the provider's endpoint rejects a `file` content part, and OpenCode will not read a binary file, so documents are extracted locally first. It measured 4.4-5.8s on the work a lane actually does, and it sits on the thorough lane because it is the careful one rather than the quick one.",
11
+ "limits": {
12
+ "context": 200000,
13
+ "output": 32000
14
+ },
15
+ "supports": {
16
+ "reasoning": true,
17
+ "temperature": true,
18
+ "toolCall": true,
19
+ "structuredOutput": true,
20
+ "attachment": true
21
+ },
22
+ "effort": {
23
+ "levels": [
24
+ "low",
25
+ "high",
26
+ "max"
27
+ ],
28
+ "default": "max",
29
+ "reserveShare": 0.12
30
+ },
31
+ "roles": {
32
+ "plan": "max",
33
+ "build": "max",
34
+ "reviewer": "max",
35
+ "locate": "low",
36
+ "verify": "low"
37
+ },
38
+ "prune": {
39
+ "enabled": true,
40
+ "keepRecentToolCalls": 6,
41
+ "keepRecentTurns": 3,
42
+ "keepUserMessages": true
43
+ },
44
+ "fallback": [
45
+ "deepseek-v4.1-flash-free",
46
+ "longcat-2.5-preview-free",
47
+ "beam-free"
48
+ ]
49
+ }
@@ -1,46 +1,72 @@
1
1
  {
2
- "$comment": "Profiles verified against live provider metadata. `retention` must come from retention.yml; a model missing there cannot enter this list.",
3
- "default": "space-bunny-free",
2
+ "$comment": "Profiles verified against live provider metadata. `retention` must come from retention.yml; a model missing there cannot enter this list. The default is a fleet, because a fleet is the point: ten jobs, ten models, one session. `context` is the input cap the config can actually use: the narrowest lane model's on a fleet, the model's own on a single-model profile. `oc-harness list` recomputes it from the profile rather than trusting this copy.",
3
+ "default": "fleet-safe",
4
4
  "profiles": [
5
5
  {
6
- "id": "muse-split-free",
7
- "file": "profiles/muse-split-free.json",
8
- "title": "Muse Spark 1.3 (heavy) + Space Bunny Free (bulk output)",
6
+ "id": "fleet-safe",
7
+ "file": "profiles/fleet-safe.json",
8
+ "title": "Ten jobs, zero-retention models only",
9
+ "retention": "zero-retention",
10
+ "free": true,
11
+ "topEffort": "max",
12
+ "context": 200000,
13
+ "default": true,
14
+ "note": "The default. Every lane resolves to a provider with a zero-retention policy, at the cost of six jobs not getting the model built for them."
15
+ },
16
+ {
17
+ "id": "fleet-all",
18
+ "file": "profiles/fleet-all.json",
19
+ "title": "Ten jobs, every free model, one of them may train",
9
20
  "retention": "may-train",
10
21
  "free": true,
11
22
  "topEffort": "max",
12
- "context": 1048576,
23
+ "context": 160000,
13
24
  "default": false,
14
- "split": {
15
- "plan": "muse-spark-1.3-contributor-free",
16
- "build": "muse-spark-1.3-contributor-free",
17
- "reviewer": "muse-spark-1.3-contributor-free",
18
- "locate": "space-bunny-free",
19
- "verify": "space-bunny-free"
20
- },
21
- "note": "Retention here is the effective one: three roles run on Muse Spark, so the file is may-train even though the base model is zero-retention."
25
+ "note": "Every lane gets the model built for it. Five of the ten providers may use the data to improve the model, so the whole profile is may-train."
22
26
  },
23
27
  {
24
- "id": "space-bunny-free",
25
- "file": "profiles/space-bunny-free.json",
26
- "title": "Space Bunny Free",
28
+ "id": "minimax-m3.1-flash-free",
29
+ "file": "profiles/minimax-m3.1-flash-free.json",
30
+ "title": "MiniMax M3.1 Flash Free",
27
31
  "retention": "zero-retention",
28
32
  "free": true,
29
33
  "topEffort": "max",
34
+ "context": 1000000,
35
+ "default": false,
36
+ "note": "512k output tokens, the widest of any free route, and the fastest measured image reader at 7.7s."
37
+ },
38
+ {
39
+ "id": "beam-free",
40
+ "file": "profiles/beam-free.json",
41
+ "title": "Beam Free",
42
+ "retention": "retained",
43
+ "free": true,
44
+ "topEffort": "max",
30
45
  "context": 1048576,
31
- "default": true,
32
- "note": "Only free Zen model with a max effort and zero-retention terms."
46
+ "default": false,
47
+ "note": "Text only, freshest knowledge on the tier, fastest measured route. Keeps prompts for 30 days, so it is not zero-retention."
33
48
  },
34
49
  {
35
- "id": "x-preview-f-free",
36
- "file": "profiles/x-preview-f-free.json",
37
- "title": "x-preview-f Free",
50
+ "id": "deepseek-v4.1-flash-free",
51
+ "file": "profiles/deepseek-v4.1-flash-free.json",
52
+ "title": "DeepSeek V4.1 Flash Free",
38
53
  "retention": "zero-retention",
39
54
  "free": true,
40
55
  "topEffort": "max",
41
- "context": 1000000,
56
+ "context": 200000,
57
+ "default": false,
58
+ "note": "Reasoning plus agentic coding plus structured output, on a zero-retention provider."
59
+ },
60
+ {
61
+ "id": "glm-5.3-flash-free",
62
+ "file": "profiles/glm-5.3-flash-free.json",
63
+ "title": "GLM 5.3 Flash Free",
64
+ "retention": "zero-retention",
65
+ "free": true,
66
+ "topEffort": "max",
67
+ "context": 200000,
42
68
  "default": false,
43
- "note": "Three effort levels only; no medium or xhigh."
69
+ "note": "Structured output on a zero-retention provider. Careful rather than fast: 4.4-5.8s on the work a lane does."
44
70
  },
45
71
  {
46
72
  "id": "longcat-2.5-preview-free",
@@ -51,28 +77,85 @@
51
77
  "topEffort": null,
52
78
  "context": 1000000,
53
79
  "default": false,
54
- "note": "No tunable reasoning effort."
80
+ "note": "1M context with image input and a zero-retention provider. A preview endpoint: it can be withdrawn without a rename."
55
81
  },
56
82
  {
57
- "id": "deepseek-v4-flash-free",
58
- "file": "profiles/deepseek-v4-flash-free.json",
59
- "title": "DeepSeek V4 Flash Free",
60
- "retention": "zero-retention",
83
+ "id": "nemotron-3.5-super-vl-free",
84
+ "file": "profiles/nemotron-3.5-super-vl-free.json",
85
+ "title": "Nemotron 3.5 Super VL Free",
86
+ "retention": "may-train",
61
87
  "free": true,
62
- "topEffort": "max",
88
+ "topEffort": "xhigh",
89
+ "context": 1048576,
90
+ "default": false,
91
+ "note": "The only free model publishing a `none` effort level, so it is the reasoning-off sweep lane. It hangs on a file ATTACHMENT - never hand it one - but not on a tool read."
92
+ },
93
+ {
94
+ "id": "nemotron-3-ultra-free",
95
+ "file": "profiles/nemotron-3-ultra-free.json",
96
+ "title": "Nemotron 3 Ultra Free",
97
+ "retention": "may-train",
98
+ "free": true,
99
+ "topEffort": null,
100
+ "context": 1000000,
101
+ "default": false,
102
+ "note": "The largest open MoE on the tier at 550B-A55B. No selectable effort. NVIDIA trial terms: sessions are logged."
103
+ },
104
+ {
105
+ "id": "nemotron-3.5-lightning-free",
106
+ "file": "profiles/nemotron-3.5-lightning-free.json",
107
+ "title": "Nemotron 3.5 Lightning Free",
108
+ "retention": "may-train",
109
+ "free": true,
110
+ "topEffort": null,
111
+ "context": 262144,
112
+ "default": false,
113
+ "note": "Its output cap equals its whole context, so it emits files larger than 128k tokens. Usually the quickest lane on the tier at 3.7s, but one measured call took 114s."
114
+ },
115
+ {
116
+ "id": "mimo-v2.6-flash-free",
117
+ "file": "profiles/mimo-v2.6-flash-free.json",
118
+ "title": "MiMo V2.6 Flash Free",
119
+ "retention": "may-train",
120
+ "free": true,
121
+ "topEffort": null,
63
122
  "context": 200000,
64
123
  "default": false,
65
- "note": "200k context, text only."
124
+ "note": "Reads images correctly, at 19.2s - the slowest lane on the tier. Publishes audio input too, but OpenCode will not read a binary file, so that path is unreachable today."
125
+ },
126
+ {
127
+ "id": "big-pickle",
128
+ "file": "profiles/big-pickle.json",
129
+ "title": "Big Pickle",
130
+ "retention": "may-train",
131
+ "free": true,
132
+ "topEffort": null,
133
+ "context": 160000,
134
+ "default": false,
135
+ "note": "Stealth model, no public identity, no effort levels, no image input. The provider may train on it during its free period."
66
136
  }
67
137
  ],
68
- "excluded": [
138
+ "excluded": [],
139
+ "withdrawn": [
140
+ {
141
+ "id": "space-bunny-free",
142
+ "reason": "Withdrawn from the provider within a month of shipping. It was the default profile, so a config left pointing at it kept working and kept saying it was zero-retention."
143
+ },
144
+ {
145
+ "id": "x-preview-f-free",
146
+ "reason": "Withdrawn from the provider within a month of shipping."
147
+ },
148
+ {
149
+ "id": "deepseek-v4-flash-free",
150
+ "reason": "Withdrawn from the provider within a month of shipping. Its replacement on the tier is deepseek-v4.1-flash-free."
151
+ },
69
152
  {
70
153
  "id": "muse-spark-1.3-contributor-free",
71
- "file": "examples/muse-spark-1.3-contributor-free.json",
72
- "title": "Muse Spark 1.3 Contributor Free",
73
- "retention": "may-train",
74
- "reason": "Provider may train on your prompts and completions (Meta contributor tier). Top effort is xhigh, not max.",
75
- "installable": true
154
+ "reason": "Withdrawn from the provider within a month of shipping. A Meta contributor-tier route whose provider was permitted to train on prompts; the paid muse-spark-1.3 route is still in the catalogue."
155
+ },
156
+ {
157
+ "id": "mimo-v2.5-free",
158
+ "reason": "Withdrawn from the provider. Observed alive for one day. Its replacement on the tier is mimo-v2.6-flash-free."
76
159
  }
77
160
  ]
78
161
  }
@@ -1,13 +1,13 @@
1
1
  {
2
- "$comment": "Fallback tier 2. No tunable reasoning effort at all, so the loader omits `variant` entirely for this profile rather than guessing a level.",
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh longcat-2.5-preview-free`.",
3
3
  "id": "longcat-2.5-preview-free",
4
- "title": "LongCat 2.5 Preview Free (OpenCode Zen)",
4
+ "title": "LongCat 2.5 Preview Free",
5
5
  "provider": "opencode",
6
6
  "model": "longcat-2.5-preview-free",
7
7
  "family": "longcat",
8
- "verified": "2026-10-07",
8
+ "verified": "2026-10-19",
9
9
  "retention": "zero-retention",
10
- "notes": "Zero-retention with a 1M context, but reasoning_options is null upstream: the model has one fixed effort. Any role requesting a level resolves to null and the generated config leaves variant unset.",
10
+ "notes": "Meituan. 1M context with image input, and a reasoning toggle rather than a tier, so no variant is written. It read a screenshot correctly in a live call, which is what makes it the zero-retention fallback for the vision lane. Measured at 9.4-13.2s. A preview endpoint: it can be withdrawn without a rename.",
11
11
  "limits": {
12
12
  "context": 1000000,
13
13
  "output": 131072
@@ -25,11 +25,11 @@
25
25
  "reserveShare": 0.12
26
26
  },
27
27
  "roles": {
28
- "plan": null,
29
- "build": null,
30
- "reviewer": null,
31
- "locate": null,
32
- "verify": null
28
+ "plan": "max",
29
+ "build": "max",
30
+ "reviewer": "max",
31
+ "locate": "low",
32
+ "verify": "low"
33
33
  },
34
34
  "prune": {
35
35
  "enabled": true,
@@ -37,5 +37,9 @@
37
37
  "keepRecentTurns": 3,
38
38
  "keepUserMessages": true
39
39
  },
40
- "fallback": ["deepseek-v4-flash-free"]
40
+ "fallback": [
41
+ "minimax-m3.1-flash-free",
42
+ "deepseek-v4.1-flash-free",
43
+ "beam-free"
44
+ ]
41
45
  }
@@ -0,0 +1,44 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh mimo-v2.6-flash-free`.",
3
+ "id": "mimo-v2.6-flash-free",
4
+ "title": "MiMo V2.6 Flash Free",
5
+ "provider": "opencode",
6
+ "model": "mimo-v2.6-flash-free",
7
+ "family": "mimo",
8
+ "verified": "2026-10-19",
9
+ "retention": "may-train",
10
+ "notes": "Xiaomi. The only free model that publishes audio input, and it read an image correctly in a live call, at 19.2s average - the slowest lane on the tier, and slower than minimax on the same picture. OpenCode 1.19 refuses to read a binary file at all, so the audio path is not reachable through the harness today; the vision path is. No effort levels, so no variant is written.",
11
+ "limits": {
12
+ "context": 200000,
13
+ "output": 32000
14
+ },
15
+ "supports": {
16
+ "reasoning": true,
17
+ "temperature": true,
18
+ "toolCall": true,
19
+ "structuredOutput": false,
20
+ "attachment": true
21
+ },
22
+ "effort": {
23
+ "levels": [],
24
+ "default": null,
25
+ "reserveShare": 0.12
26
+ },
27
+ "roles": {
28
+ "plan": "max",
29
+ "build": "max",
30
+ "reviewer": "max",
31
+ "locate": "low",
32
+ "verify": "low"
33
+ },
34
+ "prune": {
35
+ "enabled": true,
36
+ "keepRecentToolCalls": 6,
37
+ "keepRecentTurns": 3,
38
+ "keepUserMessages": true
39
+ },
40
+ "fallback": [
41
+ "longcat-2.5-preview-free",
42
+ "minimax-m3.1-flash-free"
43
+ ]
44
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh minimax-m3.1-flash-free`.",
3
+ "id": "minimax-m3.1-flash-free",
4
+ "title": "MiniMax M3.1 Flash Free",
5
+ "provider": "opencode",
6
+ "model": "minimax-m3.1-flash-free",
7
+ "family": "minimax",
8
+ "verified": "2026-10-19",
9
+ "retention": "zero-retention",
10
+ "notes": "Flagship coding and agent model on the free tier: 512k output tokens, the widest of any free route, and the fastest measured image reader at 7.7s. Tool calls are stable. It does not support temperature, and models.dev publishes no structured_output flag for it, so JSON output is requested in the prompt rather than negotiated with the API. Measured at 3.1s for a one-word reply.",
11
+ "limits": {
12
+ "context": 1000000,
13
+ "output": 512000
14
+ },
15
+ "supports": {
16
+ "reasoning": true,
17
+ "temperature": false,
18
+ "toolCall": true,
19
+ "structuredOutput": false,
20
+ "attachment": true
21
+ },
22
+ "effort": {
23
+ "levels": [
24
+ "low",
25
+ "medium",
26
+ "high",
27
+ "xhigh",
28
+ "max"
29
+ ],
30
+ "default": "max",
31
+ "reserveShare": 0.12
32
+ },
33
+ "roles": {
34
+ "plan": "max",
35
+ "build": "max",
36
+ "reviewer": "max",
37
+ "locate": "low",
38
+ "verify": "low"
39
+ },
40
+ "prune": {
41
+ "enabled": true,
42
+ "keepRecentToolCalls": 6,
43
+ "keepRecentTurns": 3,
44
+ "keepUserMessages": true
45
+ },
46
+ "fallback": [
47
+ "deepseek-v4.1-flash-free",
48
+ "longcat-2.5-preview-free",
49
+ "glm-5.3-flash-free"
50
+ ]
51
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh nemotron-3-ultra-free`.",
3
+ "id": "nemotron-3-ultra-free",
4
+ "title": "Nemotron 3 Ultra Free",
5
+ "provider": "opencode",
6
+ "model": "nemotron-3-ultra-free",
7
+ "family": "nemotron-free",
8
+ "verified": "2026-10-19",
9
+ "retention": "may-train",
10
+ "notes": "The largest open MoE on the free tier at 550B-A55B. It reasons but publishes no selectable effort level, so no variant is ever written for it. Measured at 4.7s, though a cold first request took 34s. Text only. NVIDIA trial terms: sessions are logged, so it is not the lane for private code.",
11
+ "limits": {
12
+ "context": 1000000,
13
+ "output": 128000
14
+ },
15
+ "supports": {
16
+ "reasoning": true,
17
+ "temperature": true,
18
+ "toolCall": true,
19
+ "structuredOutput": false,
20
+ "attachment": false
21
+ },
22
+ "effort": {
23
+ "levels": [],
24
+ "default": null,
25
+ "reserveShare": 0.12
26
+ },
27
+ "roles": {
28
+ "plan": "max",
29
+ "build": "max",
30
+ "reviewer": "max",
31
+ "locate": "low",
32
+ "verify": "low"
33
+ },
34
+ "prune": {
35
+ "enabled": true,
36
+ "keepRecentToolCalls": 6,
37
+ "keepRecentTurns": 3,
38
+ "keepUserMessages": true
39
+ },
40
+ "fallback": [
41
+ "glm-5.3-flash-free",
42
+ "deepseek-v4.1-flash-free"
43
+ ]
44
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh nemotron-3.5-lightning-free`.",
3
+ "id": "nemotron-3.5-lightning-free",
4
+ "title": "Nemotron 3.5 Lightning Free",
5
+ "provider": "opencode",
6
+ "model": "nemotron-3.5-lightning-free",
7
+ "family": "nemotron-free",
8
+ "verified": "2026-10-19",
9
+ "retention": "may-train",
10
+ "notes": "Its output cap equals its whole context window, so it is the lane for emitting a file larger than 128k tokens. It publishes no effort level, so it spends nothing on reasoning. It is usually the quickest lane on the tier - 3.7s average over four requests - but one measured call took 114s, so it is not on a latency-sensitive path.",
11
+ "limits": {
12
+ "context": 262144,
13
+ "output": 262144
14
+ },
15
+ "supports": {
16
+ "reasoning": true,
17
+ "temperature": true,
18
+ "toolCall": true,
19
+ "structuredOutput": true,
20
+ "attachment": false
21
+ },
22
+ "effort": {
23
+ "levels": [],
24
+ "default": null,
25
+ "reserveShare": 0.12
26
+ },
27
+ "roles": {
28
+ "plan": "max",
29
+ "build": "max",
30
+ "reviewer": "max",
31
+ "locate": "low",
32
+ "verify": "low"
33
+ },
34
+ "prune": {
35
+ "enabled": true,
36
+ "keepRecentToolCalls": 6,
37
+ "keepRecentTurns": 3,
38
+ "keepUserMessages": true
39
+ },
40
+ "fallback": [
41
+ "big-pickle",
42
+ "longcat-2.5-preview-free"
43
+ ]
44
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$comment": "Metadata verified against models.dev on 2026-10-19 and confirmed by a live call the same day. Regenerate the capability fields with `oc-harness refresh nemotron-3.5-super-vl-free`.",
3
+ "id": "nemotron-3.5-super-vl-free",
4
+ "title": "Nemotron 3.5 Super VL Free",
5
+ "provider": "opencode",
6
+ "model": "nemotron-3.5-super-vl-free",
7
+ "family": "nemotron-free",
8
+ "verified": "2026-10-19",
9
+ "retention": "may-train",
10
+ "notes": "NVIDIA 120B-A12B. The only free model that publishes a `none` effort level, which is what makes it the cheap no-reasoning sweep lane. The catalog says it takes images, but a live call with an image attachment hangs and never returns: it is used here for text and for reasoning off, never for pictures. The hang is specific to an attachment - a tool read of the same file answers in 4.2s - so the rule is 'never hand it a file', not 'never use it'.",
11
+ "limits": {
12
+ "context": 1048576,
13
+ "input": 1048576,
14
+ "output": 131072
15
+ },
16
+ "supports": {
17
+ "reasoning": true,
18
+ "temperature": true,
19
+ "toolCall": true,
20
+ "structuredOutput": false,
21
+ "attachment": true
22
+ },
23
+ "effort": {
24
+ "levels": [
25
+ "none",
26
+ "minimal",
27
+ "low",
28
+ "medium",
29
+ "high",
30
+ "xhigh"
31
+ ],
32
+ "default": "xhigh",
33
+ "reserveShare": 0.12
34
+ },
35
+ "roles": {
36
+ "plan": "max",
37
+ "build": "max",
38
+ "reviewer": "max",
39
+ "locate": "low",
40
+ "verify": "low"
41
+ },
42
+ "prune": {
43
+ "enabled": true,
44
+ "keepRecentToolCalls": 6,
45
+ "keepRecentTurns": 3,
46
+ "keepUserMessages": true
47
+ },
48
+ "fallback": [
49
+ "longcat-2.5-preview-free",
50
+ "beam-free"
51
+ ]
52
+ }
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "model": {
20
20
  "type": "string",
21
- "description": "Model id without the provider prefix, e.g. space-bunny-free."
21
+ "description": "Model id without the provider prefix, e.g. beam-free."
22
22
  },
23
23
  "family": {
24
24
  "type": ["string", "null"],
@@ -29,15 +29,19 @@
29
29
  "description": "ISO date a human checked this profile against live metadata."
30
30
  },
31
31
  "retention": {
32
- "enum": ["zero-retention", "may-train", "unknown"],
32
+ "enum": ["zero-retention", "retained", "may-train", "unknown"],
33
33
  "description": "Must match an entry in retention.yml. A profile whose model is unknown there cannot become the default."
34
34
  },
35
+ "maxRetention": {
36
+ "enum": ["zero-retention", "retained", "may-train"],
37
+ "description": "The worst retention a lane in this profile is allowed to resolve to. A lane walks its model chain and takes the first rung at or below this ceiling, so one profile can serve a fleet without sending a prompt to a provider that trains on it. Defaults to the profile's own retention."
38
+ },
35
39
  "notes": { "type": "string" },
36
40
  "limits": {
37
41
  "type": "object",
38
42
  "required": ["context", "output"],
39
43
  "additionalProperties": false,
40
- "description": "Token ceilings from the provider catalog. `input` is absent for several Zen models, in which case the loader derives it from `context`.",
44
+ "description": "Token ceilings from the provider catalog. `input` is absent for several free models, in which case the loader derives it from `context`.",
41
45
  "properties": {
42
46
  "context": { "type": "integer", "minimum": 1 },
43
47
  "input": { "type": "integer", "minimum": 1 },
@@ -74,32 +78,42 @@
74
78
  "minimum": 0,
75
79
  "maximum": 0.5,
76
80
  "default": 0.12,
77
- "description": "Share of the input ceiling held back for reasoning and tool output growth."
81
+ "description": "Share of the narrowest input ceiling in play held back for reasoning and tool output growth."
78
82
  }
79
83
  }
80
84
  },
81
85
  "roles": {
82
86
  "type": "object",
83
- "description": "Requested effort per agent role. Resolved against effort.levels, never emitted raw.",
87
+ "description": "Requested effort per lane. Resolved against effort.levels, never emitted raw. A lane listed here is enabled; a lane absent from here is not installed.",
84
88
  "additionalProperties": false,
85
89
  "properties": {
86
- "plan": { "$ref": "#/definitions/effortRequest" },
87
90
  "build": { "$ref": "#/definitions/effortRequest" },
91
+ "plan": { "$ref": "#/definitions/effortRequest" },
88
92
  "reviewer": { "$ref": "#/definitions/effortRequest" },
89
93
  "locate": { "$ref": "#/definitions/effortRequest" },
90
- "verify": { "$ref": "#/definitions/effortRequest" }
94
+ "verify": { "$ref": "#/definitions/effortRequest" },
95
+ "vision": { "$ref": "#/definitions/effortRequest" },
96
+ "doc": { "$ref": "#/definitions/effortRequest" },
97
+ "schema": { "$ref": "#/definitions/effortRequest" },
98
+ "sweep": { "$ref": "#/definitions/effortRequest" },
99
+ "longform": { "$ref": "#/definitions/effortRequest" }
91
100
  }
92
101
  },
93
102
  "roleModels": {
94
103
  "type": "object",
95
- "description": "Model per agent role, for a profile that splits the heavy reasoning roles onto a stronger model while the bulk-output roles stay on a high-output one. `model` remains the base: roles not named here, the top-level `model`, and `small_model` all resolve to it.",
104
+ "description": "Model per lane. A lane absent from `roles` is not enabled. A lane absent from `roleModels` runs on the profile's base model.",
96
105
  "additionalProperties": false,
97
106
  "properties": {
98
- "plan": { "$ref": "#/definitions/roleModel" },
99
107
  "build": { "$ref": "#/definitions/roleModel" },
108
+ "plan": { "$ref": "#/definitions/roleModel" },
100
109
  "reviewer": { "$ref": "#/definitions/roleModel" },
101
110
  "locate": { "$ref": "#/definitions/roleModel" },
102
- "verify": { "$ref": "#/definitions/roleModel" }
111
+ "verify": { "$ref": "#/definitions/roleModel" },
112
+ "vision": { "$ref": "#/definitions/roleModel" },
113
+ "doc": { "$ref": "#/definitions/roleModel" },
114
+ "schema": { "$ref": "#/definitions/roleModel" },
115
+ "sweep": { "$ref": "#/definitions/roleModel" },
116
+ "longform": { "$ref": "#/definitions/roleModel" }
103
117
  }
104
118
  },
105
119
  "prune": {
@@ -136,7 +150,7 @@
136
150
  "definitions": {
137
151
  "roleModel": {
138
152
  "type": "object",
139
- "description": "A model for one role, plus the effort levels that model actually offers. Required when the model differs from the base, because a level the model does not have must never be written onto the agent.",
153
+ "description": "A model for one lane, plus the effort levels that model actually offers, plus the ordered list of models that may serve the lane when the first one is spent or too private.",
140
154
  "additionalProperties": false,
141
155
  "required": ["model"],
142
156
  "properties": {
@@ -148,6 +162,11 @@
148
162
  "type": "array",
149
163
  "items": { "type": "string" },
150
164
  "description": "Effort levels this role's model offers. Omitted means the role emits no variant at all, which is the right reading for a model with no tunable effort."
165
+ },
166
+ "chain": {
167
+ "type": "array",
168
+ "items": { "type": "string" },
169
+ "description": "Ordered models that may serve this lane, best first. The first rung the profile's maxRetention ceiling allows is the one that runs it, and the router walks the same chain when a route is spent."
151
170
  }
152
171
  }
153
172
  },