johns-harness 2026.9.33 → 2026.9.35
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 +13 -0
- package/README.md +1 -1
- package/dist/auth-profiles-5CHn7vq1.js +11 -0
- package/dist/channels/plugins/actions/telegram.js +5 -0
- package/dist/config-koj5M_EO.js +11 -0
- package/dist/daemon-cli.js +11 -0
- package/dist/entry.js +20 -1
- package/dist/model-selection-BGlGpPgM.js +11 -0
- package/dist/model-selection-BU6wl1le.js +11 -0
- package/dist/model-selection-L7RMwsG-.js +11 -0
- package/dist/pi-embedded-helpers-CkWXaNFn.js +76 -8
- package/dist/pi-embedded-helpers-DLLQ3MsR.js +76 -8
- package/dist/plugin-sdk/config-4Fgm-yEH.js +11 -0
- package/dist/plugin-sdk/config-Di-lyCdh.js +11 -0
- package/dist/plugin-sdk/discord.js +11 -0
- package/dist/plugin-sdk/mattermost.js +5 -0
- package/dist/plugin-sdk/model-auth-CX9cPHdC.js +11 -0
- package/dist/plugin-sdk/model-auth-Ciehz0x5.js +11 -0
- package/dist/plugin-sdk/model-auth-DVyo6JSX.js +11 -0
- package/dist/plugin-sdk/model-auth-kiHYHGrs.js +11 -0
- package/dist/plugin-sdk/model-selection-Dbj4jDYM.js +11 -0
- package/dist/plugin-sdk/pi-embedded-helpers-B89Z8pGU.js +76 -8
- package/dist/plugin-sdk/pi-embedded-helpers-BDFUaaiY.js +76 -8
- package/dist/plugin-sdk/pi-embedded-helpers-BnFhV3or.js +76 -8
- package/dist/plugin-sdk/pi-embedded-helpers-CRUVFL1T.js +76 -8
- package/dist/plugin-sdk/pi-embedded-helpers-CY7PsNpl.js +76 -8
- package/dist/plugin-sdk/pi-embedded-helpers-Dira0ZRW.js +76 -8
- package/dist/plugin-sdk/thinking-B-rIrY_n.js +5 -0
- package/dist/plugin-sdk/thinking-CopbP_Cn.js +5 -0
- package/dist/plugin-sdk/thinking-WQ4Zq8Nl.js +5 -0
- package/dist/plugin-sdk/thinking-WXqkGljb.js +5 -0
- package/dist/plugin-sdk/thinking-_uXqFaFO.js +5 -0
- package/dist/plugin-sdk/thinking-pTdxk2dr.js +5 -0
- package/dist/sessions-Cqv9FKMF.js +76 -8
- package/dist/sessions-DVRA-cO-.js +76 -8
- package/dist/thinking-B5B36ffe.js +5 -0
- package/dist/thinking-BYwvlJ3S.js +5 -0
- package/dist/thinking-CAzdgmNV.js +5 -0
- package/dist/thinking-DykY2Fzj.js +5 -0
- package/docs/PATCHES.md +32 -1
- package/docs/PROVIDER-CATALOG.md +27 -6
- package/node_modules/@mariozechner/pi-ai/dist/models.generated.js +108 -0
- package/node_modules/@mariozechner/pi-ai/dist/models.js +9 -0
- package/node_modules/@mariozechner/pi-ai/dist/providers/openai-codex-responses.js +3 -0
- package/node_modules/@mariozechner/pi-ai/dist/providers/openai-responses.js +3 -0
- package/package.json +1 -1
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/models.generated.js +108 -0
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/models.js +9 -0
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/providers/openai-codex-responses.js +3 -0
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/providers/openai-responses.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.9.35
|
|
4
|
+
|
|
5
|
+
- Family 81 (session store memory, 2026-09-28): the gateway no longer runs out of memory every few days. `sessions.json` stops storing `skillsSnapshot` and `systemPromptReport` in every entry (they are rebuilt in memory on demand); existing stores shrink on the first write after the update (the live main store: 27 MB to 0.3 MB). Writes are compact JSON with one fewer full clone per load: 347 ms to 5 ms per session update on the live store copy.
|
|
6
|
+
- Session maintenance now defaults to `enforce` (prune after 30 days, 500 entries, rotate at 10 MB) and never removes the active session, main sessions, or anything updated in the last 24 hours. Set `session.maintenance.mode: "warn"` to keep the old behavior.
|
|
7
|
+
- The gateway starts with `--max-old-space-size=min(8192, RAM/2)` MB (only when that raises the limit); override with `JOHNNESS_GATEWAY_MAX_OLD_SPACE_MB=<MB>` or disable with `off`. Existing service installs pick it up on the next restart.
|
|
8
|
+
- Exact replay `scripts/patch-session-store-memory-81.py` (11 files); verifier checks 81.1-81.7. Roll back with `npm i -g johns-harness@2026.9.34`.
|
|
9
|
+
|
|
10
|
+
## 2026.9.34
|
|
11
|
+
|
|
12
|
+
- Family 80 (daily model integration, 2026-09-24): GPT-6 Sol (`gpt-6-sol`) and GPT-6 Luna (`gpt-6-luna`) ship on `openai` and `openai-codex`, and xAI Grok 4.7 (`grok-4.7`) on `xai`. Card data from the official model pages checked 2026-09-24: GPT-6 Sol $2/$10 per MTok, Luna $0.10/$0.50, both 1.05M native context and 128K max output (272K harness window, like every GPT entry), efforts none through max; Grok 4.7 $2/$6, 500K native context (200K harness window and 64K max output, like Grok 4.6), efforts low through xhigh. All three allow `/think xhigh`. GPT-6 Sol/Luna drop `temperature` unless reasoning effort is `none` (the API rejects it otherwise, verified live).
|
|
13
|
+
- Aliases: `sol` and `gpt` now resolve to `openai-codex/gpt-6-sol`, `luna` to `openai-codex/gpt-6-luna`; `sol56` and `luna56` keep the GPT-5.6 models. `grok` joins the shipped aliases on Grok 4.7; `grok46` keeps Grok 4.6. Everything else is unchanged. User aliases that pin the older models under these shorthands move forward on the next config load (family 79) and keep the versioned alias.
|
|
14
|
+
- Exact replay `scripts/patch-daily-models-80.py` (31 files); verifier checks 80.1-80.17. Roll back with `npm i -g johns-harness@2026.9.33`.
|
|
15
|
+
|
|
3
16
|
## 2026.9.33
|
|
4
17
|
|
|
5
18
|
- Claude Opus 5.5 context window cap raised from 300K to 500K (`contextWindow: 500000` in the shipped catalog and in both owner-cap paths). Opus 4.8 and Opus 5 stay at 300K. The single 300K set is now a per-model cap map (`JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL`); compaction and preflight follow the resolved window automatically. Verifier 78.4-78.7. Roll back with `npm i -g johns-harness@2026.9.32`.
|
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Expired ChatGPT credentials trigger an owner notice with the `/login` recovery c
|
|
|
55
55
|
|
|
56
56
|
<!-- JOHNNESS_PATCH_DEFAULTS_61 -->
|
|
57
57
|
### Batteries included
|
|
58
|
-
The harness ships the current model catalog and the short aliases `opus`, `sonnet`, `fable`, `astra`, `sol`, `luna`, `terra`, `gpt`, `flash`, `banana`, `image`, `deepseek`, `deepseek-pro`, `muse`, and `gemini-lite`, so `/model opus` works on a fresh install with no `models.providers` block. Channels you configure load without a `plugins.allow` list; only an explicit `enabled: false` or `plugins.deny` turns one off. Updating the harness updates the catalog and aliases for every agent. Any `openai-codex/<model>` primary that hits its ChatGPT usage limit fails over to `openai/<model>` on the API key first, then to your configured fallbacks, with no config (the sibling is skipped when no OpenAI API key is present). Image generation and editing use GPT Image 2 through the `image_generate` tool: `openai-codex/gpt-image-2` on the ChatGPT subscription first, `openai/gpt-image-2` on the API key second (`agents.defaults.imageGenerationModel`). Nano Banana Pro (`google/gemini-3-pro-image-preview`) ships in the catalog as a selectable image model, reachable with `model: "nano-banana"` and its own `aspectRatio` option; the default stays GPT Image 2 because the subscription path costs nothing.
|
|
58
|
+
The harness ships the current model catalog and the short aliases `opus`, `sonnet`, `fable`, `astra`, `sol`, `luna`, `terra`, `gpt`, `grok`, `flash`, `banana`, `image`, `deepseek`, `deepseek-pro`, `muse`, and `gemini-lite`, so `/model opus` works on a fresh install with no `models.providers` block. Channels you configure load without a `plugins.allow` list; only an explicit `enabled: false` or `plugins.deny` turns one off. Updating the harness updates the catalog and aliases for every agent. Any `openai-codex/<model>` primary that hits its ChatGPT usage limit fails over to `openai/<model>` on the API key first, then to your configured fallbacks, with no config (the sibling is skipped when no OpenAI API key is present). Image generation and editing use GPT Image 2 through the `image_generate` tool: `openai-codex/gpt-image-2` on the ChatGPT subscription first, `openai/gpt-image-2` on the API key second (`agents.defaults.imageGenerationModel`). Nano Banana Pro (`google/gemini-3-pro-image-preview`) ships in the catalog as a selectable image model, reachable with `model: "nano-banana"` and its own `aspectRatio` option; the default stays GPT Image 2 because the subscription path costs nothing.
|
|
59
59
|
|
|
60
60
|
**The alias contract.** Every shipped alias points at the newest model in its line, so an install or an `/update` moves every agent forward with zero per-instance config. Your own `agents.defaults.models[*].alias` entries are still consulted first and still win. Every catalog bump must move the matching alias; the verifier fails the release if it does not. `/model deepseek` always selects the newest DeepSeek model (currently V4.1 Flash); `deepseek-pro` the newest Pro.
|
|
61
61
|
|
|
@@ -5139,6 +5139,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
5139
5139
|
opus: "anthropic/claude-opus-5-5",
|
|
5140
5140
|
opus5: "anthropic/claude-opus-5"
|
|
5141
5141
|
});
|
|
5142
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
5143
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
5144
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
5145
|
+
sol: "openai-codex/gpt-6-sol",
|
|
5146
|
+
luna: "openai-codex/gpt-6-luna",
|
|
5147
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
5148
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
5149
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
5150
|
+
grok: "xai/grok-4.7",
|
|
5151
|
+
grok46: "xai/grok-4.6"
|
|
5152
|
+
});
|
|
5142
5153
|
const DEFAULT_MODEL_COST = {
|
|
5143
5154
|
input: 0,
|
|
5144
5155
|
output: 0,
|
|
@@ -2111,6 +2111,11 @@ const XHIGH_MODEL_REFS = [
|
|
|
2111
2111
|
"meta/muse-spark-1.3", // JOHNNESS_PATCH_MUSE_SPARK
|
|
2112
2112
|
"meta/muse-spark-1.2",
|
|
2113
2113
|
"anthropic/claude-opus-5-5", // JOHNNESS_PATCH_OPUS_55_MODEL
|
|
2114
|
+
"xai/grok-4.7", // JOHNNESS_PATCH_DAILY_MODELS_80
|
|
2115
|
+
"openai/gpt-6-sol",
|
|
2116
|
+
"openai-codex/gpt-6-sol",
|
|
2117
|
+
"openai/gpt-6-luna",
|
|
2118
|
+
"openai-codex/gpt-6-luna",
|
|
2114
2119
|
"xai/grok-4.6",
|
|
2115
2120
|
"openai/gpt-6-astra",
|
|
2116
2121
|
"openai-codex/gpt-6-astra",
|
package/dist/config-koj5M_EO.js
CHANGED
|
@@ -1834,6 +1834,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
1834
1834
|
opus: "anthropic/claude-opus-5-5",
|
|
1835
1835
|
opus5: "anthropic/claude-opus-5"
|
|
1836
1836
|
});
|
|
1837
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
1838
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
1839
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
1840
|
+
sol: "openai-codex/gpt-6-sol",
|
|
1841
|
+
luna: "openai-codex/gpt-6-luna",
|
|
1842
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
1843
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
1844
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
1845
|
+
grok: "xai/grok-4.7",
|
|
1846
|
+
grok46: "xai/grok-4.6"
|
|
1847
|
+
});
|
|
1837
1848
|
const DEFAULT_MODEL_COST = {
|
|
1838
1849
|
input: 0,
|
|
1839
1850
|
output: 0,
|
package/dist/daemon-cli.js
CHANGED
|
@@ -4986,6 +4986,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
4986
4986
|
opus: "anthropic/claude-opus-5-5",
|
|
4987
4987
|
opus5: "anthropic/claude-opus-5"
|
|
4988
4988
|
});
|
|
4989
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
4990
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
4991
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
4992
|
+
sol: "openai-codex/gpt-6-sol",
|
|
4993
|
+
luna: "openai-codex/gpt-6-luna",
|
|
4994
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
4995
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
4996
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
4997
|
+
grok: "xai/grok-4.7",
|
|
4998
|
+
grok46: "xai/grok-4.6"
|
|
4999
|
+
});
|
|
4989
5000
|
const DEFAULT_MODEL_COST = {
|
|
4990
5001
|
input: 0,
|
|
4991
5002
|
output: 0,
|
package/dist/entry.js
CHANGED
|
@@ -104,6 +104,7 @@ function applyCliProfileEnv(params) {
|
|
|
104
104
|
if (profile === "dev" && !env.JOHNNESS_GATEWAY_PORT?.trim()) env.JOHNNESS_GATEWAY_PORT = "19001";
|
|
105
105
|
}
|
|
106
106
|
//#endregion
|
|
107
|
+
import v8 from "node:v8"; // JOHNNESS_PATCH_SESSION_STORE_MEMORY_81
|
|
107
108
|
//#region src/cli/respawn-policy.ts
|
|
108
109
|
function shouldSkipRespawnForArgv(argv) {
|
|
109
110
|
return hasHelpOrVersion(argv);
|
|
@@ -326,14 +327,32 @@ if (!isMainModule({
|
|
|
326
327
|
for (const arg of process$1.execArgv) if (arg === EXPERIMENTAL_WARNING_FLAG || arg === "--no-warnings") return true;
|
|
327
328
|
return false;
|
|
328
329
|
}
|
|
330
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: gateway heap. Node's default old-space limit (~4 GB) was the OOM ceiling. The
|
|
331
|
+
// gateway runs with --max-old-space-size=min(8192, RAM/2) MB, only when that raises the limit.
|
|
332
|
+
// JOHNNESS_GATEWAY_MAX_OLD_SPACE_MB=<MB> sets it explicitly; 0/off disables. A heap flag already
|
|
333
|
+
// in NODE_OPTIONS or execArgv wins. Applied at launch, so existing service installs get it.
|
|
334
|
+
function resolveGatewayHeapArgs() {
|
|
335
|
+
if (!process$1.argv.slice(2).includes("gateway")) return [];
|
|
336
|
+
const nodeOptions = process$1.env.NODE_OPTIONS ?? "";
|
|
337
|
+
if (nodeOptions.includes("--max-old-space-size") || process$1.execArgv.some((arg) => arg.startsWith("--max-old-space-size"))) return [];
|
|
338
|
+
const raw = (process$1.env.JOHNNESS_GATEWAY_MAX_OLD_SPACE_MB ?? "").trim();
|
|
339
|
+
if (/^(0|off|false|no|none)$/i.test(raw)) return [];
|
|
340
|
+
const explicit = /^[1-9][0-9]*$/.test(raw) ? Number(raw) : void 0;
|
|
341
|
+
const mb = explicit ?? Math.min(8192, Math.floor(os.totalmem() / 1048576 / 2));
|
|
342
|
+
const currentMb = v8.getHeapStatistics().heap_size_limit / 1048576;
|
|
343
|
+
if (explicit === void 0 && !(mb > currentMb)) return [];
|
|
344
|
+
return [`--max-old-space-size=${mb}`];
|
|
345
|
+
}
|
|
329
346
|
function ensureExperimentalWarningSuppressed() {
|
|
330
347
|
if (shouldSkipRespawnForArgv(process$1.argv)) return false;
|
|
331
348
|
if (isTruthyEnvValue(process$1.env.JOHNNESS_NO_RESPAWN)) return false;
|
|
332
349
|
if (isTruthyEnvValue(process$1.env.JOHNNESS_NODE_OPTIONS_READY)) return false;
|
|
333
|
-
|
|
350
|
+
const gatewayHeapArgs = resolveGatewayHeapArgs();
|
|
351
|
+
if (hasExperimentalWarningSuppressed() && gatewayHeapArgs.length === 0) return false;
|
|
334
352
|
process$1.env.JOHNNESS_NODE_OPTIONS_READY = "1";
|
|
335
353
|
const child = spawn(process$1.execPath, [
|
|
336
354
|
EXPERIMENTAL_WARNING_FLAG,
|
|
355
|
+
...gatewayHeapArgs,
|
|
337
356
|
...process$1.execArgv,
|
|
338
357
|
...process$1.argv.slice(1)
|
|
339
358
|
], {
|
|
@@ -1691,6 +1691,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
1691
1691
|
opus: "anthropic/claude-opus-5-5",
|
|
1692
1692
|
opus5: "anthropic/claude-opus-5"
|
|
1693
1693
|
});
|
|
1694
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
1695
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
1696
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
1697
|
+
sol: "openai-codex/gpt-6-sol",
|
|
1698
|
+
luna: "openai-codex/gpt-6-luna",
|
|
1699
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
1700
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
1701
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
1702
|
+
grok: "xai/grok-4.7",
|
|
1703
|
+
grok46: "xai/grok-4.6"
|
|
1704
|
+
});
|
|
1694
1705
|
const DEFAULT_MODEL_COST = {
|
|
1695
1706
|
input: 0,
|
|
1696
1707
|
output: 0,
|
|
@@ -1666,6 +1666,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
1666
1666
|
opus: "anthropic/claude-opus-5-5",
|
|
1667
1667
|
opus5: "anthropic/claude-opus-5"
|
|
1668
1668
|
});
|
|
1669
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
1670
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
1671
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
1672
|
+
sol: "openai-codex/gpt-6-sol",
|
|
1673
|
+
luna: "openai-codex/gpt-6-luna",
|
|
1674
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
1675
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
1676
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
1677
|
+
grok: "xai/grok-4.7",
|
|
1678
|
+
grok46: "xai/grok-4.6"
|
|
1679
|
+
});
|
|
1669
1680
|
const DEFAULT_MODEL_COST = {
|
|
1670
1681
|
input: 0,
|
|
1671
1682
|
output: 0,
|
|
@@ -1597,6 +1597,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
1597
1597
|
opus: "anthropic/claude-opus-5-5",
|
|
1598
1598
|
opus5: "anthropic/claude-opus-5"
|
|
1599
1599
|
});
|
|
1600
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
1601
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
1602
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
1603
|
+
sol: "openai-codex/gpt-6-sol",
|
|
1604
|
+
luna: "openai-codex/gpt-6-luna",
|
|
1605
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
1606
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
1607
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
1608
|
+
grok: "xai/grok-4.7",
|
|
1609
|
+
grok46: "xai/grok-4.6"
|
|
1610
|
+
});
|
|
1600
1611
|
const DEFAULT_MODEL_COST = {
|
|
1601
1612
|
input: 0,
|
|
1602
1613
|
output: 0,
|
|
@@ -7467,7 +7467,15 @@ const log$2 = createSubsystemLogger("sessions/store");
|
|
|
7467
7467
|
const DEFAULT_SESSION_PRUNE_AFTER_MS = 720 * 60 * 60 * 1e3;
|
|
7468
7468
|
const DEFAULT_SESSION_MAX_ENTRIES = 500;
|
|
7469
7469
|
const DEFAULT_SESSION_ROTATE_BYTES = 10485760;
|
|
7470
|
-
const DEFAULT_SESSION_MAINTENANCE_MODE = "warn"
|
|
7470
|
+
const DEFAULT_SESSION_MAINTENANCE_MODE = "enforce"; // JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: was "warn" (never pruned)
|
|
7471
|
+
const SESSION_MAINTENANCE_PROTECT_RECENT_MS = 24 * 60 * 60 * 1e3;
|
|
7472
|
+
function isProtectedSessionEntry(key, entry, opts = {}) {
|
|
7473
|
+
const active = typeof opts.activeSessionKey === "string" ? opts.activeSessionKey.trim() : "";
|
|
7474
|
+
if (active && key === active) return true;
|
|
7475
|
+
if (key === "main" || key === "global" || key.endsWith(":main")) return true;
|
|
7476
|
+
const updatedAt = entry?.updatedAt;
|
|
7477
|
+
return typeof updatedAt === "number" && Date.now() - updatedAt < SESSION_MAINTENANCE_PROTECT_RECENT_MS;
|
|
7478
|
+
}
|
|
7471
7479
|
const DEFAULT_SESSION_DISK_BUDGET_HIGH_WATER_RATIO = .8;
|
|
7472
7480
|
function resolvePruneAfterMs(maintenance) {
|
|
7473
7481
|
const raw = maintenance?.pruneAfter ?? maintenance?.pruneDays;
|
|
@@ -7552,7 +7560,7 @@ function pruneStaleEntries(store, overrideMaxAgeMs, opts = {}) {
|
|
|
7552
7560
|
const maxAgeMs = overrideMaxAgeMs ?? resolveMaintenanceConfig().pruneAfterMs;
|
|
7553
7561
|
const cutoffMs = Date.now() - maxAgeMs;
|
|
7554
7562
|
let pruned = 0;
|
|
7555
|
-
for (const [key, entry] of Object.entries(store)) if (entry?.updatedAt != null && entry.updatedAt < cutoffMs) {
|
|
7563
|
+
for (const [key, entry] of Object.entries(store)) if (entry?.updatedAt != null && entry.updatedAt < cutoffMs && !isProtectedSessionEntry(key, entry, opts)) {
|
|
7556
7564
|
opts.onPruned?.({
|
|
7557
7565
|
key,
|
|
7558
7566
|
entry
|
|
@@ -7601,7 +7609,7 @@ function capEntryCount(store, overrideMax, opts = {}) {
|
|
|
7601
7609
|
const toRemove = keys.toSorted((a, b) => {
|
|
7602
7610
|
const aTime = getEntryUpdatedAt(store[a]);
|
|
7603
7611
|
return getEntryUpdatedAt(store[b]) - aTime;
|
|
7604
|
-
}).slice(maxEntries);
|
|
7612
|
+
}).slice(maxEntries).filter((key) => !isProtectedSessionEntry(key, store[key], opts));
|
|
7605
7613
|
for (const key of toRemove) {
|
|
7606
7614
|
const entry = store[key];
|
|
7607
7615
|
if (entry) opts.onCapped?.({
|
|
@@ -7753,6 +7761,59 @@ function normalizeSessionStore(store) {
|
|
|
7753
7761
|
if (normalized !== entry) store[key] = normalized;
|
|
7754
7762
|
}
|
|
7755
7763
|
}
|
|
7764
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: skillsSnapshot and systemPromptReport are rebuilt per process
|
|
7765
|
+
// (ensureSkillSnapshot, resolveCronSkillsSnapshot, resolveContextReport) and were 80%+ of
|
|
7766
|
+
// sessions.json. They live here, keyed by store path + session key + sessionId, never on disk.
|
|
7767
|
+
const SESSION_RUNTIME_FIELD_NAMES = ["skillsSnapshot", "systemPromptReport"];
|
|
7768
|
+
const SESSION_RUNTIME_FIELDS_KEEP_MS = 24 * 60 * 60 * 1e3;
|
|
7769
|
+
const SESSION_RUNTIME_FIELDS = /* @__PURE__ */ new Map();
|
|
7770
|
+
function stripSessionRuntimeFields(store) {
|
|
7771
|
+
let stripped = 0;
|
|
7772
|
+
for (const entry of Object.values(store)) {
|
|
7773
|
+
if (!entry || typeof entry !== "object") continue;
|
|
7774
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) if (field in entry) {
|
|
7775
|
+
delete entry[field];
|
|
7776
|
+
stripped++;
|
|
7777
|
+
}
|
|
7778
|
+
}
|
|
7779
|
+
return stripped;
|
|
7780
|
+
}
|
|
7781
|
+
function attachSessionRuntimeFields(storePath, store) {
|
|
7782
|
+
const side = SESSION_RUNTIME_FIELDS.get(storePath);
|
|
7783
|
+
if (!side || side.size === 0) return store;
|
|
7784
|
+
for (const [key, kept] of side) {
|
|
7785
|
+
const entry = store[key];
|
|
7786
|
+
if (!entry || typeof entry !== "object" || entry.sessionId !== kept.sessionId) continue;
|
|
7787
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) if (kept[field] !== void 0 && entry[field] === void 0) entry[field] = kept[field];
|
|
7788
|
+
}
|
|
7789
|
+
return store;
|
|
7790
|
+
}
|
|
7791
|
+
function persistableSessionStore(storePath, store) {
|
|
7792
|
+
const side = SESSION_RUNTIME_FIELDS.get(storePath) ?? /* @__PURE__ */ new Map();
|
|
7793
|
+
const cutoff = Date.now() - SESSION_RUNTIME_FIELDS_KEEP_MS;
|
|
7794
|
+
let out = store;
|
|
7795
|
+
for (const [key, entry] of Object.entries(store)) {
|
|
7796
|
+
if (!entry || typeof entry !== "object") continue;
|
|
7797
|
+
if (!SESSION_RUNTIME_FIELD_NAMES.some((field) => entry[field] !== void 0)) {
|
|
7798
|
+
side.delete(key);
|
|
7799
|
+
continue;
|
|
7800
|
+
}
|
|
7801
|
+
if (out === store) out = { ...store };
|
|
7802
|
+
const copy = { ...entry };
|
|
7803
|
+
const kept = { sessionId: entry.sessionId };
|
|
7804
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) {
|
|
7805
|
+
if (copy[field] !== void 0) kept[field] = copy[field];
|
|
7806
|
+
delete copy[field];
|
|
7807
|
+
}
|
|
7808
|
+
out[key] = copy;
|
|
7809
|
+
if (typeof entry.updatedAt === "number" && entry.updatedAt < cutoff) side.delete(key);
|
|
7810
|
+
else side.set(key, kept);
|
|
7811
|
+
}
|
|
7812
|
+
for (const key of side.keys()) if (!store[key]) side.delete(key);
|
|
7813
|
+
if (side.size > 0) SESSION_RUNTIME_FIELDS.set(storePath, side);
|
|
7814
|
+
else SESSION_RUNTIME_FIELDS.delete(storePath);
|
|
7815
|
+
return out;
|
|
7816
|
+
}
|
|
7756
7817
|
function loadSessionStore(storePath, opts = {}) {
|
|
7757
7818
|
if (!opts.skipCache && isSessionStoreCacheEnabled()) {
|
|
7758
7819
|
const currentFileStat = getFileStatSnapshot(storePath);
|
|
@@ -7762,7 +7823,7 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7762
7823
|
mtimeMs: currentFileStat?.mtimeMs,
|
|
7763
7824
|
sizeBytes: currentFileStat?.sizeBytes
|
|
7764
7825
|
});
|
|
7765
|
-
if (cached) return cached;
|
|
7826
|
+
if (cached) return attachSessionRuntimeFields(storePath, cached);
|
|
7766
7827
|
}
|
|
7767
7828
|
let store = {};
|
|
7768
7829
|
let fileStat = getFileStatSnapshot(storePath);
|
|
@@ -7793,6 +7854,7 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7793
7854
|
if (serializedFromDisk !== void 0) setSerializedSessionStore(storePath, serializedFromDisk);
|
|
7794
7855
|
else setSerializedSessionStore(storePath, void 0);
|
|
7795
7856
|
applySessionStoreMigrations(store);
|
|
7857
|
+
stripSessionRuntimeFields(store);
|
|
7796
7858
|
if (!opts.skipCache && isSessionStoreCacheEnabled()) writeSessionStoreCache({
|
|
7797
7859
|
storePath,
|
|
7798
7860
|
store,
|
|
@@ -7800,7 +7862,8 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7800
7862
|
sizeBytes: fileStat?.sizeBytes,
|
|
7801
7863
|
serialized: serializedFromDisk
|
|
7802
7864
|
});
|
|
7803
|
-
|
|
7865
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: `store` was parsed just now and the cache holds its own clone.
|
|
7866
|
+
return attachSessionRuntimeFields(storePath, store);
|
|
7804
7867
|
}
|
|
7805
7868
|
function readSessionUpdatedAt(params) {
|
|
7806
7869
|
try {
|
|
@@ -7874,10 +7937,10 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
|
|
|
7874
7937
|
});
|
|
7875
7938
|
} else {
|
|
7876
7939
|
const removedSessionFiles = /* @__PURE__ */ new Map();
|
|
7877
|
-
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, { onPruned: ({ entry }) => {
|
|
7940
|
+
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, { activeSessionKey: opts?.activeSessionKey, onPruned: ({ entry }) => {
|
|
7878
7941
|
rememberRemovedSessionFile(removedSessionFiles, entry);
|
|
7879
7942
|
} });
|
|
7880
|
-
const capped = capEntryCount(store, maintenance.maxEntries, { onCapped: ({ entry }) => {
|
|
7943
|
+
const capped = capEntryCount(store, maintenance.maxEntries, { activeSessionKey: opts?.activeSessionKey, onCapped: ({ entry }) => {
|
|
7881
7944
|
rememberRemovedSessionFile(removedSessionFiles, entry);
|
|
7882
7945
|
} });
|
|
7883
7946
|
const archivedDirs = /* @__PURE__ */ new Set();
|
|
@@ -7922,7 +7985,9 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
|
|
|
7922
7985
|
}
|
|
7923
7986
|
}
|
|
7924
7987
|
await fs$1.promises.mkdir(path.dirname(storePath), { recursive: true });
|
|
7925
|
-
|
|
7988
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: persist without runtime fields, compact (was 2-space indent).
|
|
7989
|
+
store = persistableSessionStore(storePath, store);
|
|
7990
|
+
const json = JSON.stringify(store);
|
|
7926
7991
|
if (getSerializedSessionStore(storePath) === json) {
|
|
7927
7992
|
updateSessionStoreWriteCaches({
|
|
7928
7993
|
storePath,
|
|
@@ -7974,6 +8039,9 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
|
|
|
7974
8039
|
}
|
|
7975
8040
|
async function updateSessionStore(storePath, mutator, opts) {
|
|
7976
8041
|
return await withSessionStoreLock(storePath, async () => {
|
|
8042
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: skipCache stays. This runs under the cross-process file lock and the cache is
|
|
8043
|
+
// validated only by mtime + size, so a same-size write by another process could be missed.
|
|
8044
|
+
// The re-read is ~3 MB now that runtime fields are not persisted.
|
|
7977
8045
|
const store = loadSessionStore(storePath, { skipCache: true });
|
|
7978
8046
|
const result = await mutator(store);
|
|
7979
8047
|
await saveSessionStoreUnlocked(storePath, store, opts);
|
|
@@ -7464,7 +7464,15 @@ const log$2 = createSubsystemLogger("sessions/store");
|
|
|
7464
7464
|
const DEFAULT_SESSION_PRUNE_AFTER_MS = 720 * 60 * 60 * 1e3;
|
|
7465
7465
|
const DEFAULT_SESSION_MAX_ENTRIES = 500;
|
|
7466
7466
|
const DEFAULT_SESSION_ROTATE_BYTES = 10485760;
|
|
7467
|
-
const DEFAULT_SESSION_MAINTENANCE_MODE = "warn"
|
|
7467
|
+
const DEFAULT_SESSION_MAINTENANCE_MODE = "enforce"; // JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: was "warn" (never pruned)
|
|
7468
|
+
const SESSION_MAINTENANCE_PROTECT_RECENT_MS = 24 * 60 * 60 * 1e3;
|
|
7469
|
+
function isProtectedSessionEntry(key, entry, opts = {}) {
|
|
7470
|
+
const active = typeof opts.activeSessionKey === "string" ? opts.activeSessionKey.trim() : "";
|
|
7471
|
+
if (active && key === active) return true;
|
|
7472
|
+
if (key === "main" || key === "global" || key.endsWith(":main")) return true;
|
|
7473
|
+
const updatedAt = entry?.updatedAt;
|
|
7474
|
+
return typeof updatedAt === "number" && Date.now() - updatedAt < SESSION_MAINTENANCE_PROTECT_RECENT_MS;
|
|
7475
|
+
}
|
|
7468
7476
|
const DEFAULT_SESSION_DISK_BUDGET_HIGH_WATER_RATIO = .8;
|
|
7469
7477
|
function resolvePruneAfterMs(maintenance) {
|
|
7470
7478
|
const raw = maintenance?.pruneAfter ?? maintenance?.pruneDays;
|
|
@@ -7549,7 +7557,7 @@ function pruneStaleEntries(store, overrideMaxAgeMs, opts = {}) {
|
|
|
7549
7557
|
const maxAgeMs = overrideMaxAgeMs ?? resolveMaintenanceConfig().pruneAfterMs;
|
|
7550
7558
|
const cutoffMs = Date.now() - maxAgeMs;
|
|
7551
7559
|
let pruned = 0;
|
|
7552
|
-
for (const [key, entry] of Object.entries(store)) if (entry?.updatedAt != null && entry.updatedAt < cutoffMs) {
|
|
7560
|
+
for (const [key, entry] of Object.entries(store)) if (entry?.updatedAt != null && entry.updatedAt < cutoffMs && !isProtectedSessionEntry(key, entry, opts)) {
|
|
7553
7561
|
opts.onPruned?.({
|
|
7554
7562
|
key,
|
|
7555
7563
|
entry
|
|
@@ -7598,7 +7606,7 @@ function capEntryCount(store, overrideMax, opts = {}) {
|
|
|
7598
7606
|
const toRemove = keys.toSorted((a, b) => {
|
|
7599
7607
|
const aTime = getEntryUpdatedAt(store[a]);
|
|
7600
7608
|
return getEntryUpdatedAt(store[b]) - aTime;
|
|
7601
|
-
}).slice(maxEntries);
|
|
7609
|
+
}).slice(maxEntries).filter((key) => !isProtectedSessionEntry(key, store[key], opts));
|
|
7602
7610
|
for (const key of toRemove) {
|
|
7603
7611
|
const entry = store[key];
|
|
7604
7612
|
if (entry) opts.onCapped?.({
|
|
@@ -7750,6 +7758,59 @@ function normalizeSessionStore(store) {
|
|
|
7750
7758
|
if (normalized !== entry) store[key] = normalized;
|
|
7751
7759
|
}
|
|
7752
7760
|
}
|
|
7761
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: skillsSnapshot and systemPromptReport are rebuilt per process
|
|
7762
|
+
// (ensureSkillSnapshot, resolveCronSkillsSnapshot, resolveContextReport) and were 80%+ of
|
|
7763
|
+
// sessions.json. They live here, keyed by store path + session key + sessionId, never on disk.
|
|
7764
|
+
const SESSION_RUNTIME_FIELD_NAMES = ["skillsSnapshot", "systemPromptReport"];
|
|
7765
|
+
const SESSION_RUNTIME_FIELDS_KEEP_MS = 24 * 60 * 60 * 1e3;
|
|
7766
|
+
const SESSION_RUNTIME_FIELDS = /* @__PURE__ */ new Map();
|
|
7767
|
+
function stripSessionRuntimeFields(store) {
|
|
7768
|
+
let stripped = 0;
|
|
7769
|
+
for (const entry of Object.values(store)) {
|
|
7770
|
+
if (!entry || typeof entry !== "object") continue;
|
|
7771
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) if (field in entry) {
|
|
7772
|
+
delete entry[field];
|
|
7773
|
+
stripped++;
|
|
7774
|
+
}
|
|
7775
|
+
}
|
|
7776
|
+
return stripped;
|
|
7777
|
+
}
|
|
7778
|
+
function attachSessionRuntimeFields(storePath, store) {
|
|
7779
|
+
const side = SESSION_RUNTIME_FIELDS.get(storePath);
|
|
7780
|
+
if (!side || side.size === 0) return store;
|
|
7781
|
+
for (const [key, kept] of side) {
|
|
7782
|
+
const entry = store[key];
|
|
7783
|
+
if (!entry || typeof entry !== "object" || entry.sessionId !== kept.sessionId) continue;
|
|
7784
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) if (kept[field] !== void 0 && entry[field] === void 0) entry[field] = kept[field];
|
|
7785
|
+
}
|
|
7786
|
+
return store;
|
|
7787
|
+
}
|
|
7788
|
+
function persistableSessionStore(storePath, store) {
|
|
7789
|
+
const side = SESSION_RUNTIME_FIELDS.get(storePath) ?? /* @__PURE__ */ new Map();
|
|
7790
|
+
const cutoff = Date.now() - SESSION_RUNTIME_FIELDS_KEEP_MS;
|
|
7791
|
+
let out = store;
|
|
7792
|
+
for (const [key, entry] of Object.entries(store)) {
|
|
7793
|
+
if (!entry || typeof entry !== "object") continue;
|
|
7794
|
+
if (!SESSION_RUNTIME_FIELD_NAMES.some((field) => entry[field] !== void 0)) {
|
|
7795
|
+
side.delete(key);
|
|
7796
|
+
continue;
|
|
7797
|
+
}
|
|
7798
|
+
if (out === store) out = { ...store };
|
|
7799
|
+
const copy = { ...entry };
|
|
7800
|
+
const kept = { sessionId: entry.sessionId };
|
|
7801
|
+
for (const field of SESSION_RUNTIME_FIELD_NAMES) {
|
|
7802
|
+
if (copy[field] !== void 0) kept[field] = copy[field];
|
|
7803
|
+
delete copy[field];
|
|
7804
|
+
}
|
|
7805
|
+
out[key] = copy;
|
|
7806
|
+
if (typeof entry.updatedAt === "number" && entry.updatedAt < cutoff) side.delete(key);
|
|
7807
|
+
else side.set(key, kept);
|
|
7808
|
+
}
|
|
7809
|
+
for (const key of side.keys()) if (!store[key]) side.delete(key);
|
|
7810
|
+
if (side.size > 0) SESSION_RUNTIME_FIELDS.set(storePath, side);
|
|
7811
|
+
else SESSION_RUNTIME_FIELDS.delete(storePath);
|
|
7812
|
+
return out;
|
|
7813
|
+
}
|
|
7753
7814
|
function loadSessionStore(storePath, opts = {}) {
|
|
7754
7815
|
if (!opts.skipCache && isSessionStoreCacheEnabled()) {
|
|
7755
7816
|
const currentFileStat = getFileStatSnapshot(storePath);
|
|
@@ -7759,7 +7820,7 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7759
7820
|
mtimeMs: currentFileStat?.mtimeMs,
|
|
7760
7821
|
sizeBytes: currentFileStat?.sizeBytes
|
|
7761
7822
|
});
|
|
7762
|
-
if (cached) return cached;
|
|
7823
|
+
if (cached) return attachSessionRuntimeFields(storePath, cached);
|
|
7763
7824
|
}
|
|
7764
7825
|
let store = {};
|
|
7765
7826
|
let fileStat = getFileStatSnapshot(storePath);
|
|
@@ -7790,6 +7851,7 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7790
7851
|
if (serializedFromDisk !== void 0) setSerializedSessionStore(storePath, serializedFromDisk);
|
|
7791
7852
|
else setSerializedSessionStore(storePath, void 0);
|
|
7792
7853
|
applySessionStoreMigrations(store);
|
|
7854
|
+
stripSessionRuntimeFields(store);
|
|
7793
7855
|
if (!opts.skipCache && isSessionStoreCacheEnabled()) writeSessionStoreCache({
|
|
7794
7856
|
storePath,
|
|
7795
7857
|
store,
|
|
@@ -7797,7 +7859,8 @@ function loadSessionStore(storePath, opts = {}) {
|
|
|
7797
7859
|
sizeBytes: fileStat?.sizeBytes,
|
|
7798
7860
|
serialized: serializedFromDisk
|
|
7799
7861
|
});
|
|
7800
|
-
|
|
7862
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: `store` was parsed just now and the cache holds its own clone.
|
|
7863
|
+
return attachSessionRuntimeFields(storePath, store);
|
|
7801
7864
|
}
|
|
7802
7865
|
function readSessionUpdatedAt(params) {
|
|
7803
7866
|
try {
|
|
@@ -7871,10 +7934,10 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
|
|
|
7871
7934
|
});
|
|
7872
7935
|
} else {
|
|
7873
7936
|
const removedSessionFiles = /* @__PURE__ */ new Map();
|
|
7874
|
-
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, { onPruned: ({ entry }) => {
|
|
7937
|
+
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, { activeSessionKey: opts?.activeSessionKey, onPruned: ({ entry }) => {
|
|
7875
7938
|
rememberRemovedSessionFile(removedSessionFiles, entry);
|
|
7876
7939
|
} });
|
|
7877
|
-
const capped = capEntryCount(store, maintenance.maxEntries, { onCapped: ({ entry }) => {
|
|
7940
|
+
const capped = capEntryCount(store, maintenance.maxEntries, { activeSessionKey: opts?.activeSessionKey, onCapped: ({ entry }) => {
|
|
7878
7941
|
rememberRemovedSessionFile(removedSessionFiles, entry);
|
|
7879
7942
|
} });
|
|
7880
7943
|
const archivedDirs = /* @__PURE__ */ new Set();
|
|
@@ -7919,7 +7982,9 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
|
|
|
7919
7982
|
}
|
|
7920
7983
|
}
|
|
7921
7984
|
await syncFs.promises.mkdir(path.dirname(storePath), { recursive: true });
|
|
7922
|
-
|
|
7985
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: persist without runtime fields, compact (was 2-space indent).
|
|
7986
|
+
store = persistableSessionStore(storePath, store);
|
|
7987
|
+
const json = JSON.stringify(store);
|
|
7923
7988
|
if (getSerializedSessionStore(storePath) === json) {
|
|
7924
7989
|
updateSessionStoreWriteCaches({
|
|
7925
7990
|
storePath,
|
|
@@ -7976,6 +8041,9 @@ async function saveSessionStore(storePath, store, opts) {
|
|
|
7976
8041
|
}
|
|
7977
8042
|
async function updateSessionStore(storePath, mutator, opts) {
|
|
7978
8043
|
return await withSessionStoreLock(storePath, async () => {
|
|
8044
|
+
// JOHNNESS_PATCH_SESSION_STORE_MEMORY_81: skipCache stays. This runs under the cross-process file lock and the cache is
|
|
8045
|
+
// validated only by mtime + size, so a same-size write by another process could be missed.
|
|
8046
|
+
// The re-read is ~3 MB now that runtime fields are not persisted.
|
|
7979
8047
|
const store = loadSessionStore(storePath, { skipCache: true });
|
|
7980
8048
|
const result = await mutator(store);
|
|
7981
8049
|
await saveSessionStoreUnlocked(storePath, store, opts);
|
|
@@ -7084,6 +7084,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
7084
7084
|
opus: "anthropic/claude-opus-5-5",
|
|
7085
7085
|
opus5: "anthropic/claude-opus-5"
|
|
7086
7086
|
});
|
|
7087
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
7088
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
7089
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
7090
|
+
sol: "openai-codex/gpt-6-sol",
|
|
7091
|
+
luna: "openai-codex/gpt-6-luna",
|
|
7092
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
7093
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
7094
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
7095
|
+
grok: "xai/grok-4.7",
|
|
7096
|
+
grok46: "xai/grok-4.6"
|
|
7097
|
+
});
|
|
7087
7098
|
const DEFAULT_MODEL_COST = {
|
|
7088
7099
|
input: 0,
|
|
7089
7100
|
output: 0,
|
|
@@ -8085,6 +8085,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
8085
8085
|
opus: "anthropic/claude-opus-5-5",
|
|
8086
8086
|
opus5: "anthropic/claude-opus-5"
|
|
8087
8087
|
});
|
|
8088
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
8089
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
8090
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
8091
|
+
sol: "openai-codex/gpt-6-sol",
|
|
8092
|
+
luna: "openai-codex/gpt-6-luna",
|
|
8093
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
8094
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
8095
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
8096
|
+
grok: "xai/grok-4.7",
|
|
8097
|
+
grok46: "xai/grok-4.6"
|
|
8098
|
+
});
|
|
8088
8099
|
const DEFAULT_MODEL_COST = {
|
|
8089
8100
|
input: 0,
|
|
8090
8101
|
output: 0,
|
|
@@ -5214,6 +5214,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
5214
5214
|
opus: "anthropic/claude-opus-5-5",
|
|
5215
5215
|
opus5: "anthropic/claude-opus-5"
|
|
5216
5216
|
});
|
|
5217
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
5218
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
5219
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
5220
|
+
sol: "openai-codex/gpt-6-sol",
|
|
5221
|
+
luna: "openai-codex/gpt-6-luna",
|
|
5222
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
5223
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
5224
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
5225
|
+
grok: "xai/grok-4.7",
|
|
5226
|
+
grok46: "xai/grok-4.6"
|
|
5227
|
+
});
|
|
5217
5228
|
const DEFAULT_MODEL_COST = {
|
|
5218
5229
|
input: 0,
|
|
5219
5230
|
output: 0,
|
|
@@ -3136,6 +3136,11 @@ const XHIGH_MODEL_REFS = [
|
|
|
3136
3136
|
"meta/muse-spark-1.3", // JOHNNESS_PATCH_MUSE_SPARK
|
|
3137
3137
|
"meta/muse-spark-1.2",
|
|
3138
3138
|
"anthropic/claude-opus-5-5", // JOHNNESS_PATCH_OPUS_55_MODEL
|
|
3139
|
+
"xai/grok-4.7", // JOHNNESS_PATCH_DAILY_MODELS_80
|
|
3140
|
+
"openai/gpt-6-sol",
|
|
3141
|
+
"openai-codex/gpt-6-sol",
|
|
3142
|
+
"openai/gpt-6-luna",
|
|
3143
|
+
"openai-codex/gpt-6-luna",
|
|
3139
3144
|
"xai/grok-4.6",
|
|
3140
3145
|
"openai/gpt-6-astra",
|
|
3141
3146
|
"openai-codex/gpt-6-astra",
|
|
@@ -6005,6 +6005,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
6005
6005
|
opus: "anthropic/claude-opus-5-5",
|
|
6006
6006
|
opus5: "anthropic/claude-opus-5"
|
|
6007
6007
|
});
|
|
6008
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
6009
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
6010
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
6011
|
+
sol: "openai-codex/gpt-6-sol",
|
|
6012
|
+
luna: "openai-codex/gpt-6-luna",
|
|
6013
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
6014
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
6015
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
6016
|
+
grok: "xai/grok-4.7",
|
|
6017
|
+
grok46: "xai/grok-4.6"
|
|
6018
|
+
});
|
|
6008
6019
|
const DEFAULT_MODEL_COST = {
|
|
6009
6020
|
input: 0,
|
|
6010
6021
|
output: 0,
|
|
@@ -4974,6 +4974,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
4974
4974
|
opus: "anthropic/claude-opus-5-5",
|
|
4975
4975
|
opus5: "anthropic/claude-opus-5"
|
|
4976
4976
|
});
|
|
4977
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
4978
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
4979
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
4980
|
+
sol: "openai-codex/gpt-6-sol",
|
|
4981
|
+
luna: "openai-codex/gpt-6-luna",
|
|
4982
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
4983
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
4984
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
4985
|
+
grok: "xai/grok-4.7",
|
|
4986
|
+
grok46: "xai/grok-4.6"
|
|
4987
|
+
});
|
|
4977
4988
|
const DEFAULT_MODEL_COST = {
|
|
4978
4989
|
input: 0,
|
|
4979
4990
|
output: 0,
|
|
@@ -4978,6 +4978,17 @@ Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
|
4978
4978
|
opus: "anthropic/claude-opus-5-5",
|
|
4979
4979
|
opus5: "anthropic/claude-opus-5"
|
|
4980
4980
|
});
|
|
4981
|
+
// JOHNNESS_PATCH_DAILY_MODELS_80: GPT-6 Sol/Luna are the newest Sol/Luna; `sol`, `luna` and `gpt` move to them and
|
|
4982
|
+
// the GPT-5.6 models keep sol56/luna56. `grok` names the newest Grok; grok46 keeps Grok 4.6.
|
|
4983
|
+
Object.assign(DEFAULT_MODEL_ALIASES, {
|
|
4984
|
+
sol: "openai-codex/gpt-6-sol",
|
|
4985
|
+
luna: "openai-codex/gpt-6-luna",
|
|
4986
|
+
gpt: "openai-codex/gpt-6-sol",
|
|
4987
|
+
sol56: "openai-codex/gpt-5.6-sol",
|
|
4988
|
+
luna56: "openai-codex/gpt-5.6-luna",
|
|
4989
|
+
grok: "xai/grok-4.7",
|
|
4990
|
+
grok46: "xai/grok-4.6"
|
|
4991
|
+
});
|
|
4981
4992
|
const DEFAULT_MODEL_COST = {
|
|
4982
4993
|
input: 0,
|
|
4983
4994
|
output: 0,
|