@lawaty/lacode 0.4.2 → 0.5.0

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/CHANGELOG.md CHANGED
@@ -9,6 +9,33 @@ commit as the changelog entry it describes.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.5.0] — a user-only /manager-directive, instant limit failover, and the longcat preset
13
+
14
+ ### Added
15
+
16
+ - **`/manager-directive <text>`** — a client-only command that runs a hidden
17
+ `manager` agent to apply your instruction to `.opencode/context/manager.md`
18
+ (record it, move it between sections, rewrite `## Current`, …). The `manager`
19
+ agent is the only agent permitted to edit that file, its grant is scoped to
20
+ `manager.md` alone, and no other agent can spawn it — the command is the only
21
+ route in. The one-writer guard (`writer-rule.ts` Direction 3) now exempts
22
+ exactly that agent name and still reports every other writer.
23
+
24
+ ### Changed
25
+
26
+ - **Bundled pool preset** — `opencode-go/step-5-preview-free` and
27
+ `opencode/step-5-preview-free` were retired upstream. Slots 2 and 4 now name
28
+ `longcat-2.5-preview-free` on the same providers (`opencode-go`, `opencode`).
29
+ Update `~/.config/lacode/pool.txt` if you pinned the old ids there.
30
+
31
+ ### Fixed
32
+
33
+ - **Immediate failover on a usage limit** — when a limit-shaped assistant error or
34
+ a limit-shaped `session.status` retry names the session an in-flight claim is
35
+ running on, the pool aborts that session at once instead of leaving it for the
36
+ ~5-minute hang reaper. The claim is released and the next spawn routes to a slot
37
+ that answers; a limit on an unrelated session never kills a claim.
38
+
12
39
  ## [0.4.2] — fix silent claim eviction, unkillable chatty tasks, and gateway 5xx misclassification
13
40
 
14
41
  ### Fixed
@@ -166,7 +193,8 @@ commit as the changelog entry it describes.
166
193
 
167
194
  - First published release: pooled subagents over a shared set of models.
168
195
 
169
- [Unreleased]: https://github.com/lawaty/lacode/compare/v0.4.1...HEAD
196
+ [Unreleased]: https://github.com/lawaty/lacode/compare/v0.5.0...HEAD
197
+ [0.5.0]: https://github.com/lawaty/lacode/compare/v0.4.2...v0.5.0
170
198
  [0.4.1]: https://github.com/lawaty/lacode/compare/v0.4.0...v0.4.1
171
199
  [0.4.0]: https://github.com/lawaty/lacode/compare/v0.3.0...v0.4.0
172
200
  [0.3.0]: https://github.com/lawaty/lacode/compare/v0.2.2...v0.3.0
package/README.md CHANGED
@@ -178,8 +178,9 @@ only thing that works: naming a variant lets the caller choose the provider
178
178
  directly, which is exactly what the rotation and the per-slot ceiling exist to
179
179
  prevent, so it is refused.
180
180
 
181
- Four commands: `/context-init`, `/context-update`, `/context-review` and
182
- `/lacode-doctor`. Everything is added **only when your config does not already
181
+ Five commands: `/context-init`, `/context-update`, `/context-review`,
182
+ `/lacode-doctor` and `/manager-directive`. Everything is added **only when your
183
+ config does not already
183
184
  define it** — an agent or command you wrote yourself is left byte-identical,
184
185
  never patched or partially merged. `{"enabled": false}` turns the whole thing off
185
186
  without leaving a trace. The exact injection list, and the three keys that are
@@ -212,6 +213,7 @@ are reading:
212
213
  /context-update # incremental refresh; accepts a focus, e.g. /context-update src/payments
213
214
  /context-review # audit it for staleness, contradictions, duplication and bloat
214
215
  /lacode-doctor # check the pool, model resolution and the OmniRoute gateway. Report only
216
+ /manager-directive # record a managerial direction in manager.md — client-only, see below
215
217
  ```
216
218
 
217
219
  The map is local and untracked — it describes your checkout on your machine, so
@@ -251,6 +253,15 @@ agent working in your live session may write it only when you explicitly ask
251
253
  it to, and only what you asked for — never on its own initiative, and never
252
254
  to "keep it up to date".
253
255
 
256
+ **`/manager-directive` — the one sanctioned write path.** Type
257
+ `/manager-directive <text>` and the `manager` agent applies your instruction to
258
+ `manager.md` — recording it, moving it between sections, rewriting `## Current`,
259
+ whatever you asked — then reports what it changed. It is a normal agent turn, not
260
+ a dead append: tell it what you want and review the result. The `manager` agent
261
+ is the one agent permitted to edit that file, its grant is scoped to
262
+ `manager.md` alone, and no other agent can spawn it — the command is the only
263
+ route in.
264
+
254
265
  ## Cost
255
266
 
256
267
  The mechanism is specific and small: bulk exploration, implementation and
package/dist/agents.js CHANGED
@@ -46,6 +46,9 @@ var USER_MODELS_PATH = join2(USER_CONFIG_DIR, "pool.json");
46
46
  var USER_MODELS_TXT = join2(USER_CONFIG_DIR, "pool.txt");
47
47
  var CHILD_MEMORY_MS = 30 * 6e4;
48
48
 
49
+ // src/lib/manager-directive.ts
50
+ var MANAGER_AGENT_NAME = "manager";
51
+
49
52
  // src/agents.ts
50
53
  var POOLED_BASES = ["explore", "implement", "context"];
51
54
  var AGENTS = {
@@ -722,6 +725,68 @@ Finish with a short report:
722
725
  }
723
726
  }
724
727
  };
728
+ var MANAGER_AGENT = {
729
+ description: "Records and edits the client's .opencode/context/manager.md. Run only by the /manager-directive command; no agent or subagent can spawn it.",
730
+ mode: "subagent",
731
+ hidden: true,
732
+ temperature: 0.1,
733
+ prompt: `# Role
734
+
735
+ You maintain one file and nothing else: \`.opencode/context/manager.md\`, the
736
+ client's own statement of intent. You are not a coding agent and you touch no
737
+ other path.
738
+
739
+ You are run only by the \`/manager-directive\` command. The client tells you what
740
+ they want recorded or changed in the file; you apply that to the file and report
741
+ what you changed. You have no permission to edit anything else, and you need
742
+ none.
743
+
744
+ # The file
745
+
746
+ It records what is being worked on (\`## Current\`), what comes next
747
+ (\`## Next\`), what the client has ratified (\`## Confirmed\`), and standing
748
+ direction (\`## Instructions\`). The client may use any headings \u2014 every heading
749
+ is direction, and the four above are a convenience, not a schema.
750
+
751
+ # How to apply a directive
752
+
753
+ - Do what the client asked. "Append", "rewrite Current", "move X to Confirmed",
754
+ "add a heading" all mean exactly that; a bare sentence goes under the most
755
+ fitting existing heading, and you create one only if none fits.
756
+ - Never invent facts, never record your own inference as the client's, and never
757
+ tidy, reorder or delete content the client did not ask you to touch.
758
+ - \`## Current\` is rewritten, not appended to, so it does not become a running
759
+ history.
760
+ - Keep the file concise. If it is growing past roughly 150 lines, say so.
761
+
762
+ # Reporting
763
+
764
+ Report briefly what you changed and where. Do not edit any other file.`,
765
+ permission: {
766
+ // Read is scoped to the one file too: the directive is about manager.md, and
767
+ // nothing else is any of this agent's business.
768
+ read: {
769
+ "*": "deny",
770
+ ".opencode/context/manager.md": "allow",
771
+ "*/.opencode/context/manager.md": "allow"
772
+ },
773
+ glob: "deny",
774
+ grep: "deny",
775
+ list: "deny",
776
+ edit: {
777
+ "*": "deny",
778
+ ".opencode/context/manager.md": "allow",
779
+ "*/.opencode/context/manager.md": "allow"
780
+ },
781
+ bash: "deny",
782
+ webfetch: "deny",
783
+ websearch: "deny",
784
+ question: "allow",
785
+ task: {
786
+ "*": "deny"
787
+ }
788
+ }
789
+ };
725
790
  function buildAgentSet() {
726
791
  const set = { ...AGENTS };
727
792
  for (const base of POOLED_BASES) {
@@ -737,6 +802,7 @@ function buildAgentSet() {
737
802
  set[`${base}-${slot}`] = variant;
738
803
  }
739
804
  }
805
+ set[MANAGER_AGENT_NAME] = MANAGER_AGENT;
740
806
  return set;
741
807
  }
742
808
  function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
@@ -756,6 +822,7 @@ function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
756
822
  }
757
823
  export {
758
824
  AGENTS,
825
+ MANAGER_AGENT,
759
826
  POOLED_BASES,
760
827
  applyAgents,
761
828
  buildAgentSet
package/dist/commands.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/lib/manager-directive.ts
2
+ var MANAGER_AGENT_NAME = "manager";
3
+
1
4
  // src/commands.ts
2
5
  var COMMANDS = {
3
6
  "context-init": {
@@ -77,6 +80,16 @@ Audit the five context files for:
77
80
 
78
81
  Fix what you find in \`.opencode/context/\` only, then report: findings, fixes,
79
82
  and anything you could not verify.`
83
+ },
84
+ "manager-directive": {
85
+ description: "Apply a client instruction to .opencode/context/manager.md. Client-only \u2014 runs the manager agent, the only writer of that file.",
86
+ agent: MANAGER_AGENT_NAME,
87
+ subtask: true,
88
+ template: `Apply this instruction to \`.opencode/context/manager.md\`, and edit only that file:
89
+
90
+ $ARGUMENTS
91
+
92
+ Follow the rules for the file in your system prompt, then report what you changed.`
80
93
  },
81
94
  "lacode-doctor": {
82
95
  description: "Check the LaCode setup \u2014 pool slots, model resolution, and the OmniRoute gateway. Report only; changes nothing.",
package/dist/index.js CHANGED
@@ -49,9 +49,9 @@ var USER_MODELS_PATH = join2(USER_CONFIG_DIR, "pool.json");
49
49
  var USER_MODELS_TXT = join2(USER_CONFIG_DIR, "pool.txt");
50
50
  var FALLBACK_SLOTS = [
51
51
  { index: 1, model: "opencode/space-bunny-free", weight: 3 },
52
- { index: 2, model: "opencode-go/step-5-preview-free", weight: 2 },
52
+ { index: 2, model: "opencode-go/longcat-2.5-preview-free", weight: 2 },
53
53
  { index: 3, model: "opencode/big-pickle", weight: 1 },
54
- { index: 4, model: "opencode/step-5-preview-free", weight: 1 }
54
+ { index: 4, model: "opencode/longcat-2.5-preview-free", weight: 1 }
55
55
  ];
56
56
  function parseSlots(parsed, origin) {
57
57
  const problems = [];
@@ -611,6 +611,9 @@ function coolProvider(s, provider, until, reason) {
611
611
  return affected;
612
612
  }
613
613
 
614
+ // src/lib/manager-directive.ts
615
+ var MANAGER_AGENT_NAME = "manager";
616
+
614
617
  // src/agents.ts
615
618
  var POOLED_BASES = ["explore", "implement", "context"];
616
619
  var AGENTS = {
@@ -1287,6 +1290,68 @@ Finish with a short report:
1287
1290
  }
1288
1291
  }
1289
1292
  };
1293
+ var MANAGER_AGENT = {
1294
+ description: "Records and edits the client's .opencode/context/manager.md. Run only by the /manager-directive command; no agent or subagent can spawn it.",
1295
+ mode: "subagent",
1296
+ hidden: true,
1297
+ temperature: 0.1,
1298
+ prompt: `# Role
1299
+
1300
+ You maintain one file and nothing else: \`.opencode/context/manager.md\`, the
1301
+ client's own statement of intent. You are not a coding agent and you touch no
1302
+ other path.
1303
+
1304
+ You are run only by the \`/manager-directive\` command. The client tells you what
1305
+ they want recorded or changed in the file; you apply that to the file and report
1306
+ what you changed. You have no permission to edit anything else, and you need
1307
+ none.
1308
+
1309
+ # The file
1310
+
1311
+ It records what is being worked on (\`## Current\`), what comes next
1312
+ (\`## Next\`), what the client has ratified (\`## Confirmed\`), and standing
1313
+ direction (\`## Instructions\`). The client may use any headings \u2014 every heading
1314
+ is direction, and the four above are a convenience, not a schema.
1315
+
1316
+ # How to apply a directive
1317
+
1318
+ - Do what the client asked. "Append", "rewrite Current", "move X to Confirmed",
1319
+ "add a heading" all mean exactly that; a bare sentence goes under the most
1320
+ fitting existing heading, and you create one only if none fits.
1321
+ - Never invent facts, never record your own inference as the client's, and never
1322
+ tidy, reorder or delete content the client did not ask you to touch.
1323
+ - \`## Current\` is rewritten, not appended to, so it does not become a running
1324
+ history.
1325
+ - Keep the file concise. If it is growing past roughly 150 lines, say so.
1326
+
1327
+ # Reporting
1328
+
1329
+ Report briefly what you changed and where. Do not edit any other file.`,
1330
+ permission: {
1331
+ // Read is scoped to the one file too: the directive is about manager.md, and
1332
+ // nothing else is any of this agent's business.
1333
+ read: {
1334
+ "*": "deny",
1335
+ ".opencode/context/manager.md": "allow",
1336
+ "*/.opencode/context/manager.md": "allow"
1337
+ },
1338
+ glob: "deny",
1339
+ grep: "deny",
1340
+ list: "deny",
1341
+ edit: {
1342
+ "*": "deny",
1343
+ ".opencode/context/manager.md": "allow",
1344
+ "*/.opencode/context/manager.md": "allow"
1345
+ },
1346
+ bash: "deny",
1347
+ webfetch: "deny",
1348
+ websearch: "deny",
1349
+ question: "allow",
1350
+ task: {
1351
+ "*": "deny"
1352
+ }
1353
+ }
1354
+ };
1290
1355
  function buildAgentSet() {
1291
1356
  const set = { ...AGENTS };
1292
1357
  for (const base of POOLED_BASES) {
@@ -1302,6 +1367,7 @@ function buildAgentSet() {
1302
1367
  set[`${base}-${slot}`] = variant;
1303
1368
  }
1304
1369
  }
1370
+ set[MANAGER_AGENT_NAME] = MANAGER_AGENT;
1305
1371
  return set;
1306
1372
  }
1307
1373
  function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
@@ -1399,6 +1465,16 @@ Audit the five context files for:
1399
1465
 
1400
1466
  Fix what you find in \`.opencode/context/\` only, then report: findings, fixes,
1401
1467
  and anything you could not verify.`
1468
+ },
1469
+ "manager-directive": {
1470
+ description: "Apply a client instruction to .opencode/context/manager.md. Client-only \u2014 runs the manager agent, the only writer of that file.",
1471
+ agent: MANAGER_AGENT_NAME,
1472
+ subtask: true,
1473
+ template: `Apply this instruction to \`.opencode/context/manager.md\`, and edit only that file:
1474
+
1475
+ $ARGUMENTS
1476
+
1477
+ Follow the rules for the file in your system prompt, then report what you changed.`
1402
1478
  },
1403
1479
  "lacode-doctor": {
1404
1480
  description: "Check the LaCode setup \u2014 pool slots, model resolution, and the OmniRoute gateway. Report only; changes nothing.",
@@ -1527,6 +1603,19 @@ var agentPoolHooks = (async ({ client, serverUrl }, options) => {
1527
1603
  const strike = recordStrike(s, claim.m, "hang", HANG_FALLBACK_MS);
1528
1604
  if (strike) await log2("warn", `cooling ${claim.m} for ${Math.round((strike.until - now) / 1e3)}s (hang)`);
1529
1605
  };
1606
+ const failOver = async (sessionID, model, reason) => {
1607
+ if (!sessionID) return;
1608
+ const entry = [...s.own.entries()].find(([, claim2]) => claim2.g === sessionID);
1609
+ if (!entry) return;
1610
+ const [key, claim] = entry;
1611
+ const kill = await abortSession(sessionID);
1612
+ release(s, key);
1613
+ await log(
1614
+ "warn",
1615
+ kill.ok ? `limit (${reason}) on ${model}; aborted in-flight ${claim.v} session ${sessionID} to fail over now` : `limit (${reason}) on ${model}; released in-flight ${claim.v} claim after a failed abort (${kill.why})`,
1616
+ { base: claim.v, model: claim.m, slot: claim.k, session: sessionID, aborted: kill.ok, reason }
1617
+ );
1618
+ };
1530
1619
  const reapStuck = async () => {
1531
1620
  if (s.reaping) return;
1532
1621
  s.reaping = true;
@@ -1642,18 +1731,21 @@ var agentPoolHooks = (async ({ client, serverUrl }, options) => {
1642
1731
  try {
1643
1732
  const props = event.properties ?? {};
1644
1733
  if (event.type === "session.status") {
1734
+ const sessionID = typeof props.sessionID === "string" ? props.sessionID : void 0;
1645
1735
  const status2 = props.status;
1646
- if (status2?.type === "retry" && status2.action?.reason === "free_tier_limit" && status2.action.provider) {
1736
+ const reason2 = status2?.action?.reason ?? "";
1737
+ if (status2?.type === "retry" && status2.action?.provider && (reason2 === "free_tier_limit" || isLimitText(reason2))) {
1647
1738
  const provider = status2.action.provider;
1648
1739
  const until = typeof status2.next === "number" && status2.next > Date.now() ? status2.next : Date.now() + HANG_FALLBACK_MS;
1649
- const cooled = coolProvider(s, provider, until, "free_tier_limit");
1740
+ const cooled = coolProvider(s, provider, until, reason2 || "rate-limited");
1650
1741
  if (cooled.length > 0) {
1651
- await log("warn", `free tier exhausted on provider ${provider}; cooling ${cooled.length} slot(s) until ${new Date(until).toISOString().slice(11, 19)}Z`, {
1742
+ await log("warn", `limit on provider ${provider} (${reason2 || "rate-limited"}); cooling ${cooled.length} slot(s) until ${new Date(until).toISOString().slice(11, 19)}Z`, {
1652
1743
  provider,
1653
1744
  until,
1654
1745
  models: cooled.map((c) => c.model)
1655
1746
  });
1656
1747
  }
1748
+ await failOver(sessionID, provider, reason2 || "rate-limited");
1657
1749
  }
1658
1750
  return;
1659
1751
  }
@@ -1687,6 +1779,7 @@ var agentPoolHooks = (async ({ client, serverUrl }, options) => {
1687
1779
  const reason = haystack.match(/rate[\s_-]?limit|usage limit|too many requests|quota|freelimiterror|overloaded/i)?.[0]?.toLowerCase().replace(/[\s_]/g, "-");
1688
1780
  const strike = recordStrike(s, model, reason ?? "rate-limited", stated);
1689
1781
  if (strike) await log("warn", `cooling ${model} for ${Math.round((strike.until - Date.now()) / 1e3)}s (${reason ?? "rate-limited"}, strike ${strike.strikes})`);
1782
+ await failOver(info.sessionID, model, reason ?? "rate-limited");
1690
1783
  } catch (error) {
1691
1784
  await log("error", `limit detection failed: ${String(error)}`);
1692
1785
  }
@@ -1858,6 +1951,7 @@ import { readFileSync as readFileSync3 } from "node:fs";
1858
1951
  import * as path from "node:path";
1859
1952
  var CONTEXT_DIR = path.join(".opencode", "context");
1860
1953
  var WRITER = "context";
1954
+ var MANAGER_WRITER = MANAGER_AGENT_NAME;
1861
1955
  var toPosix = (value) => value.split(path.sep).join("/");
1862
1956
  var compilePattern = (pattern) => {
1863
1957
  const escaped = toPosix(pattern).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
@@ -1926,11 +2020,12 @@ var verifyWriterRule = (configPath, mapDir, projectRoot) => {
1926
2020
  if (agentDefs) {
1927
2021
  const writers = [];
1928
2022
  for (const [name, def] of Object.entries(agentDefs)) {
2023
+ if (name === MANAGER_WRITER) continue;
1929
2024
  const win = winningRule(permissionOf(def), managerPath);
1930
2025
  if (win?.action === "allow") writers.push(`${name} (edit rule "${win.pattern}": "${win.action}")`);
1931
2026
  }
1932
2027
  if (writers.length > 0) {
1933
- return `${CONTEXT_DIR}/manager.md is writable by permission: ${writers.join(", ")}. It is the client's own file \u2014 what they are working on, what is ratified, what every agent must respect \u2014 and no agent writes it. Deny it LAST, after any broad allow, because opencode takes the LAST matching rule: "*": "allow", "*/${CONTEXT_DIR}/manager.md": "deny", "${CONTEXT_DIR}/manager.md": "deny". Declare this on every agent above, including \`${WRITER}\`: an agent you define yourself replaces the shipped one wholesale, permission and all.`;
2028
+ return `${CONTEXT_DIR}/manager.md is writable by permission: ${writers.join(", ")}. It is the client's own file \u2014 what they are working on, what is ratified, what every agent must respect \u2014 and only the \`${MANAGER_WRITER}\` agent (run solely by /manager-directive) may write it. Deny it LAST on every other agent, after any broad allow, because opencode takes the LAST matching rule: "*": "allow", "*/${CONTEXT_DIR}/manager.md": "deny", "${CONTEXT_DIR}/manager.md": "deny". Declare this on every agent above, including \`${WRITER}\`: an agent you define yourself replaces the shipped one wholesale, permission and all.`;
1934
2029
  }
1935
2030
  }
1936
2031
  return void 0;
package/dist/pool.js CHANGED
@@ -49,9 +49,9 @@ var USER_MODELS_PATH = join2(USER_CONFIG_DIR, "pool.json");
49
49
  var USER_MODELS_TXT = join2(USER_CONFIG_DIR, "pool.txt");
50
50
  var FALLBACK_SLOTS = [
51
51
  { index: 1, model: "opencode/space-bunny-free", weight: 3 },
52
- { index: 2, model: "opencode-go/step-5-preview-free", weight: 2 },
52
+ { index: 2, model: "opencode-go/longcat-2.5-preview-free", weight: 2 },
53
53
  { index: 3, model: "opencode/big-pickle", weight: 1 },
54
- { index: 4, model: "opencode/step-5-preview-free", weight: 1 }
54
+ { index: 4, model: "opencode/longcat-2.5-preview-free", weight: 1 }
55
55
  ];
56
56
  function parseSlots(parsed, origin) {
57
57
  const problems = [];
@@ -75,9 +75,11 @@ process.
75
75
 
76
76
  ## What gets injected
77
77
 
78
- **17 agent keys**: the 5 bases `build`, `plan`, `explore`, `implement`,
78
+ **18 agent keys**: the 5 bases `build`, `plan`, `explore`, `implement`,
79
79
  `context`, plus one hidden
80
- `<base>-1`..`-4` pool variant for each of the 3 pooled bases.
80
+ `<base>-1`..`-4` pool variant for each of the 3 pooled bases, plus the hidden
81
+ `manager` agent — the one writer of `.opencode/context/manager.md`, reachable
82
+ only from the `/manager-directive` command.
81
83
 
82
84
  `build` and `plan` exist in opencode as built-ins, so on a stock config those
83
85
  two keys are already taken and merge-without-clobber keeps the built-in — the
package/docs/OMNIROUTE.md CHANGED
@@ -102,7 +102,7 @@ your pool like any other model:
102
102
  # ~/.config/lacode/pool.txt
103
103
  omniroute/auto 3
104
104
  opencode/space-bunny-free 2
105
- opencode-go/step-5-preview-free 1
105
+ opencode-go/longcat-2.5-preview-free 1
106
106
  opencode/big-pickle 1
107
107
  ```
108
108
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lawaty/lacode",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Ultimate opencode setup for Go users — cost-controlled pooled subagents, hang recovery, and notifications for opencode.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/presets/README.md CHANGED
@@ -36,10 +36,10 @@ in place, no JSON and no objects:
36
36
 
37
37
  ```text
38
38
  # provider/model-id weight
39
- opencode-go/step-5-preview-free 3
39
+ opencode-go/longcat-2.5-preview-free 3
40
40
  opencode/space-bunny-free 2
41
41
  opencode/big-pickle 1
42
- opencode/step-5-preview-free 1
42
+ opencode/longcat-2.5-preview-free 1
43
43
  ```
44
44
 
45
45
  `#` starts a comment (whole-line or trailing), blank lines are ignored, and the
@@ -25,8 +25,8 @@
25
25
  " 3. once EVERY slot is at its ceiling, the overflow goes to the least loaded slot,",
26
26
  " so a burst past the summed ceilings degrades to even spreading and never blocks",
27
27
  "",
28
- "With this file: space-bunny takes 3 consecutive turns, then step-5-preview",
29
- "(opencode-go) takes 2, then big-pickle and step-5-preview (Zen) take 1 each -- sequence 1,1,1,2,2,3,4,...",
28
+ "With this file: space-bunny takes 3 consecutive turns, then longcat-2.5-preview",
29
+ "(opencode-go) takes 2, then big-pickle and longcat-2.5-preview (Zen) take 1 each -- sequence 1,1,1,2,2,3,4,...",
30
30
  "Equal weights give a plain round robin in list order. 2,2,1,1 reproduces the old",
31
31
  "primary/overflow cycle exactly, which is why the old tier values still work.",
32
32
  "",
@@ -67,8 +67,8 @@
67
67
  ],
68
68
  "slots": [
69
69
  { "model": "opencode/space-bunny-free", "weight": 3 },
70
- { "model": "opencode-go/step-5-preview-free", "weight": 2 },
70
+ { "model": "opencode-go/longcat-2.5-preview-free", "weight": 2 },
71
71
  { "model": "opencode/big-pickle", "weight": 1 },
72
- { "model": "opencode/step-5-preview-free", "weight": 1 }
72
+ { "model": "opencode/longcat-2.5-preview-free", "weight": 1 }
73
73
  ]
74
74
  }