@inetafrica/open-claudia 3.4.19 → 3.4.20

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
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.4.20
4
+
5
+ - Make `claude-opus-5-5` the default Claude model. 3.4.19 only added it to the picker; the default stayed on `claude-opus-4-8`, so a room that had never run `/model` kept the old model.
6
+ - The default governs main conversation turns only. Utility work remains tier-pinned — `low` to `claude-haiku-4-5-20251001` and `medium` to `claude-sonnet-4-6` — so recall, pack review, the dedup adjudicator and the enforcer do not reprice with it, and a room's own `/model` choice still wins over the default.
7
+ - Note for operators: `CLAUDE_MODEL` in `~/.open-claudia/.env` (or the process env) overrides this. An install that pinned the old default there keeps it until that line is changed. Pod images carry no `CLAUDE_MODEL` and the entrypoint never writes one, so pods resolve the shipped constant.
8
+ - `claude-opus-5-5` requires Claude Code >= 2.1.280; an older CLI refuses it with an API 400 rather than degrading. The pod image installs the CLI unpinned, so an image built before that release must not run this default.
9
+
3
10
  ## 3.4.19
4
11
 
5
12
  - Offer `claude-opus-5-5` in the Claude model picker. Verified against the live API rather than assumed: on Claude Code 2.1.280 the API bills the request to `claude-opus-5-5` (1M context, 128k max output), while 2.1.258 refuses it with "does not support this model; version 2.1.280 or newer is required". An older CLI returns that API 400 instead of degrading, so a pod on a stale image errors on the model rather than falling back — the same constraint already recorded for `claude-fable-5-1` (>= 2.1.251).
@@ -24,7 +24,10 @@ const CLAUDE_MODELS = Object.freeze([
24
24
  "claude-haiku-4-5-20251001",
25
25
  ]);
26
26
  const CLAUDE_EFFORT_VALUES = Object.freeze(["low", "medium", "high", "xhigh", "max"]);
27
- const CLAUDE_DEFAULT_MODEL = config.config.CLAUDE_MODEL || process.env.CLAUDE_MODEL || "claude-opus-4-8";
27
+ // The default governs MAIN turns only: utility work is pinned by tier below
28
+ // (low -> haiku, medium -> sonnet), so recall, pack review and the enforcer do
29
+ // not move with it. A room's own /model pin always wins over this.
30
+ const CLAUDE_DEFAULT_MODEL = config.config.CLAUDE_MODEL || process.env.CLAUDE_MODEL || "claude-opus-5-5";
28
31
  const REQUIRED_HELP_FLAGS = Object.freeze([
29
32
  "--append-system-prompt",
30
33
  "--output-format",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "3.4.19",
3
+ "version": "3.4.20",
4
4
  "description": "An always-on, provider-agnostic coding-agent harness for Claude Code and OpenAI Codex via chat",
5
5
  "main": "bot.js",
6
6
  "bin": {
@@ -6,7 +6,7 @@ const assert = require("assert");
6
6
  const fs = require("fs");
7
7
  const path = require("path");
8
8
  const { validateInvocation, validateProvider } = require("./core/providers/contract");
9
- const { createClaudeProvider } = require("./core/providers/claude");
9
+ const { createClaudeProvider, claudeProvider, CLAUDE_MODELS } = require("./core/providers/claude");
10
10
  const { getProvider } = require("./core/providers");
11
11
 
12
12
  function deepFreeze(value) {
@@ -49,6 +49,25 @@ assert.ok(provider.modelChoices().includes("claude-fable-5-1"));
49
49
  assert.ok(provider.modelChoices().includes("claude-opus-5-5"), "opus 5.5 is offered in the model picker");
50
50
  assert.ok(provider.modelChoices().includes("claude-fable-5"));
51
51
  assert.ok(provider.modelChoices().includes("claude-sonnet-4-6"));
52
+
53
+ // The SHIPPED default, asserted on the real module rather than the fixture above,
54
+ // so changing the constant cannot pass unnoticed. Read from source because the
55
+ // resolved value is deliberately overridable: loadEnv merges CLAUDE_MODEL from
56
+ // ~/.open-claudia/.env over process.env, and a machine that carries that pin
57
+ // (Sumeet's laptop does, set 2026-07-21) would otherwise mask a regression here.
58
+ const claudeSource = fs.readFileSync(path.join(__dirname, "core", "providers", "claude.js"), "utf8");
59
+ assert.match(
60
+ claudeSource,
61
+ /CLAUDE_DEFAULT_MODEL = config\.config\.CLAUDE_MODEL \|\| process\.env\.CLAUDE_MODEL \|\| "claude-opus-5-5";/,
62
+ "shipped Claude default is claude-opus-5-5",
63
+ );
64
+ // The default governs main turns only: utility tiers stay cheap. These are what
65
+ // stop a default bump from silently repricing recall, pack review and the enforcer.
66
+ assert.strictEqual(claudeProvider.tierModel("low"), "claude-haiku-4-5-20251001", "low-tier utility work stays on haiku");
67
+ assert.strictEqual(claudeProvider.tierModel("medium"), "claude-sonnet-4-6", "medium-tier utility work stays on sonnet");
68
+ if (!process.env.CLAUDE_MODEL && !claudeSource.includes("__fixture__")) {
69
+ assert.ok(CLAUDE_MODELS.includes(claudeProvider.defaultModel()), "the resolved default is a model the picker offers");
70
+ }
52
71
  assert.deepStrictEqual(provider.compatibilityStatus(), {
53
72
  state: "compatible",
54
73
  version: "2.1.150",
@@ -477,7 +477,17 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
477
477
  // unreleased Kazee fail-closed room gate, so a runtime behaviour change and an
478
478
  // additive picker entry can be rolled back independently. Local Claude Code went
479
479
  // 2.1.258 -> 2.1.280 first; the model is refused outright below that.
480
- assert.strictEqual(pkg.version, "3.4.19", "release version must remain unchanged without explicit approval");
480
+ // 3.4.20 approved by Sumeet 2026-09-23 ("If not please make it the default and
481
+ // push them roll out to the whole fleet", answering whether 3.4.19 had already
482
+ // made opus 5.5 the default — it had not, it only added the picker entry):
483
+ // claude-opus-5-5 becomes CLAUDE_DEFAULT_MODEL. It governs MAIN turns only —
484
+ // utility work is tier-pinned (low -> haiku, medium -> sonnet) and a room's own
485
+ // /model pin still wins — so the cost moves with conversation turns, not recall.
486
+ // Safe on the fleet because the pod env carries no CLAUDE_MODEL and the
487
+ // entrypoint never writes one, so the constant is what pods resolve; the pod
488
+ // image installs Claude Code unpinned, which must be >= 2.1.280 or the model is
489
+ // refused with an API 400 rather than degrading.
490
+ assert.strictEqual(pkg.version, "3.4.20", "release version must remain unchanged without explicit approval");
481
491
  for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
482
492
  assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
483
493
  }