@ashlr/hub 3.7.0 → 3.9.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.
Files changed (155) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/dist/build-identity.json +2 -2
  3. package/dist/cli/resource-profile.js +95 -21
  4. package/dist/cli/resource-profile.js.map +1 -1
  5. package/dist/core/policy/local-only.d.ts +142 -2
  6. package/dist/core/policy/local-only.js +204 -15
  7. package/dist/core/policy/local-only.js.map +1 -1
  8. package/dist/core/resources/native-profile.d.ts +56 -0
  9. package/dist/core/resources/native-profile.js +368 -6
  10. package/dist/core/resources/native-profile.js.map +1 -1
  11. package/dist/core/run/budget.d.ts +22 -8
  12. package/dist/core/run/budget.js +80 -12
  13. package/dist/core/run/budget.js.map +1 -1
  14. package/dist/core/run/model-catalog.js +8 -1
  15. package/dist/core/run/model-catalog.js.map +1 -1
  16. package/dist/core/run/sandboxed-engine.js +3 -3
  17. package/dist/core/run/sandboxed-engine.js.map +1 -1
  18. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  19. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +69 -10
  20. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +68 -9
  21. package/dist/core/verse/adapters/claude.d.ts +49 -2
  22. package/dist/core/verse/adapters/claude.js +317 -56
  23. package/dist/core/verse/adapters/claude.js.map +1 -1
  24. package/dist/core/verse/adapters/codex.d.ts +81 -5
  25. package/dist/core/verse/adapters/codex.js +409 -47
  26. package/dist/core/verse/adapters/codex.js.map +1 -1
  27. package/dist/core/verse/adapters/grok.d.ts +13 -1
  28. package/dist/core/verse/adapters/grok.js +28 -2
  29. package/dist/core/verse/adapters/grok.js.map +1 -1
  30. package/dist/core/verse/adapters/index.d.ts +32 -0
  31. package/dist/core/verse/adapters/index.js +2 -0
  32. package/dist/core/verse/adapters/index.js.map +1 -1
  33. package/dist/core/verse/codex-rollout.d.ts +284 -0
  34. package/dist/core/verse/codex-rollout.js +786 -0
  35. package/dist/core/verse/codex-rollout.js.map +1 -0
  36. package/dist/core/verse/context-fit.d.ts +63 -0
  37. package/dist/core/verse/context-fit.js +355 -0
  38. package/dist/core/verse/context-fit.js.map +1 -0
  39. package/dist/core/verse/context-math.d.ts +215 -0
  40. package/dist/core/verse/context-math.js +365 -0
  41. package/dist/core/verse/context-math.js.map +1 -0
  42. package/dist/core/verse/local-models.d.ts +137 -1
  43. package/dist/core/verse/local-models.js +209 -5
  44. package/dist/core/verse/local-models.js.map +1 -1
  45. package/dist/core/verse/model-windows.d.ts +217 -0
  46. package/dist/core/verse/model-windows.js +616 -0
  47. package/dist/core/verse/model-windows.js.map +1 -0
  48. package/dist/core/verse/preferences.d.ts +123 -0
  49. package/dist/core/verse/preferences.js +403 -0
  50. package/dist/core/verse/preferences.js.map +1 -0
  51. package/dist/core/verse/project-memory.d.ts +112 -0
  52. package/dist/core/verse/project-memory.js +295 -0
  53. package/dist/core/verse/project-memory.js.map +1 -0
  54. package/dist/core/verse/seats.d.ts +106 -4
  55. package/dist/core/verse/seats.js +291 -89
  56. package/dist/core/verse/seats.js.map +1 -1
  57. package/dist/core/verse/session-engine.d.ts +117 -2
  58. package/dist/core/verse/session-engine.js +763 -65
  59. package/dist/core/verse/session-engine.js.map +1 -1
  60. package/dist/core/verse/session-handoff.d.ts +94 -0
  61. package/dist/core/verse/session-handoff.js +551 -0
  62. package/dist/core/verse/session-handoff.js.map +1 -0
  63. package/dist/core/verse/session-search.d.ts +63 -0
  64. package/dist/core/verse/session-search.js +213 -0
  65. package/dist/core/verse/session-search.js.map +1 -0
  66. package/dist/core/verse/session-store.d.ts +16 -2
  67. package/dist/core/verse/session-store.js +80 -6
  68. package/dist/core/verse/session-store.js.map +1 -1
  69. package/dist/core/verse/types.d.ts +333 -1
  70. package/dist/core/verse/types.js +54 -2
  71. package/dist/core/verse/types.js.map +1 -1
  72. package/dist/core/verse/verse-api.d.ts +40 -5
  73. package/dist/core/verse/verse-api.js +724 -25
  74. package/dist/core/verse/verse-api.js.map +1 -1
  75. package/dist/core/web/api.d.ts +14 -4
  76. package/dist/core/web/api.js +26 -11
  77. package/dist/core/web/api.js.map +1 -1
  78. package/dist/core/web/public/next/assets/{App-vtaHB9mp.js → App-XURmiAAp.js} +5 -5
  79. package/dist/core/web/public/next/assets/{App-vtaHB9mp.js.map → App-XURmiAAp.js.map} +1 -1
  80. package/dist/core/web/public/next/assets/{ApprovalsSection-B-bFJ0I9.js → ApprovalsSection-BriUzoZc.js} +2 -2
  81. package/dist/core/web/public/next/assets/{ApprovalsSection-B-bFJ0I9.js.map → ApprovalsSection-BriUzoZc.js.map} +1 -1
  82. package/dist/core/web/public/next/assets/AutonomySection-C4GBsQVc.js +2 -0
  83. package/dist/core/web/public/next/assets/{AutonomySection-DoqmsCjw.js.map → AutonomySection-C4GBsQVc.js.map} +1 -1
  84. package/dist/core/web/public/next/assets/ChatSection-BpOBOUvg.css +1 -0
  85. package/dist/core/web/public/next/assets/ChatSection-hlgPBRco.js +84 -0
  86. package/dist/core/web/public/next/assets/ChatSection-hlgPBRco.js.map +1 -0
  87. package/dist/core/web/public/next/assets/ConfirmDialog-BdQYI-Ng.js +2 -0
  88. package/dist/core/web/public/next/assets/ConfirmDialog-BdQYI-Ng.js.map +1 -0
  89. package/dist/core/web/public/next/assets/{Dialog-CPM9JxBc.js → Dialog-BxdIfmFH.js} +2 -2
  90. package/dist/core/web/public/next/assets/{Dialog-CPM9JxBc.js.map → Dialog-BxdIfmFH.js.map} +1 -1
  91. package/dist/core/web/public/next/assets/{DiffViewer-B84qVef9.js → DiffViewer-DmeRWuc4.js} +2 -2
  92. package/dist/core/web/public/next/assets/{DiffViewer-B84qVef9.js.map → DiffViewer-DmeRWuc4.js.map} +1 -1
  93. package/dist/core/web/public/next/assets/{McpSection-CEUpV_5X.js → McpSection-q34T7Tho.js} +2 -2
  94. package/dist/core/web/public/next/assets/{McpSection-CEUpV_5X.js.map → McpSection-q34T7Tho.js.map} +1 -1
  95. package/dist/core/web/public/next/assets/{MutationTokenDialog-DA8t97XT.js → MutationTokenDialog-CFAkwOEt.js} +2 -2
  96. package/dist/core/web/public/next/assets/{MutationTokenDialog-DA8t97XT.js.map → MutationTokenDialog-CFAkwOEt.js.map} +1 -1
  97. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-Bq7Vyud0.js → ResourcePoolConsoleApp-DHc8GFOY.js} +4 -4
  98. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-Bq7Vyud0.js.map → ResourcePoolConsoleApp-DHc8GFOY.js.map} +1 -1
  99. package/dist/core/web/public/next/assets/{RouteErrorBoundary-Badio_uO.js → RouteErrorBoundary-ZL9F4qUn.js} +2 -2
  100. package/dist/core/web/public/next/assets/{RouteErrorBoundary-Badio_uO.js.map → RouteErrorBoundary-ZL9F4qUn.js.map} +1 -1
  101. package/dist/core/web/public/next/assets/{Meter-CLcr-4wS.css → Segmented-8cf0Fypn.css} +1 -1
  102. package/dist/core/web/public/next/assets/{Meter--h3MmZS-.js → Segmented-DbRjVye3.js} +2 -2
  103. package/dist/core/web/public/next/assets/Segmented-DbRjVye3.js.map +1 -0
  104. package/dist/core/web/public/next/assets/SettingsSection-nJGGGYqv.js +2 -0
  105. package/dist/core/web/public/next/assets/{SettingsSection-BwrpQlpP.js.map → SettingsSection-nJGGGYqv.js.map} +1 -1
  106. package/dist/core/web/public/next/assets/UniverseConsoleApp-6GJydgo4.js +2 -0
  107. package/dist/core/web/public/next/assets/{UniverseConsoleApp-_FSohAdN.js.map → UniverseConsoleApp-6GJydgo4.js.map} +1 -1
  108. package/dist/core/web/public/next/assets/{UniverseView-DqcXbed4.js → UniverseView-DLDtNYL8.js} +2 -2
  109. package/dist/core/web/public/next/assets/{UniverseView-DqcXbed4.js.map → UniverseView-DLDtNYL8.js.map} +1 -1
  110. package/dist/core/web/public/next/assets/UsageSection-Cf9d9iFH.js +2 -0
  111. package/dist/core/web/public/next/assets/UsageSection-Cf9d9iFH.js.map +1 -0
  112. package/dist/core/web/public/next/assets/VerseConsoleApp-DsdKQoTH.css +1 -0
  113. package/dist/core/web/public/next/assets/VerseConsoleApp-y0uOHixd.js +3 -0
  114. package/dist/core/web/public/next/assets/VerseConsoleApp-y0uOHixd.js.map +1 -0
  115. package/dist/core/web/public/next/assets/{charts-CTZJ-JrH.js → charts-CVooqJWN.js} +2 -2
  116. package/dist/core/web/public/next/assets/{charts-CTZJ-JrH.js.map → charts-CVooqJWN.js.map} +1 -1
  117. package/dist/core/web/public/next/assets/context-model-Bqv8DVuH.js +2 -0
  118. package/dist/core/web/public/next/assets/context-model-Bqv8DVuH.js.map +1 -0
  119. package/dist/core/web/public/next/assets/global-eaY9GyX3.js +2 -0
  120. package/dist/core/web/public/next/assets/global-eaY9GyX3.js.map +1 -0
  121. package/dist/core/web/public/next/assets/{icons-D9vlf85u.js → icons-vex8rclC.js} +2 -2
  122. package/dist/core/web/public/next/assets/{icons-D9vlf85u.js.map → icons-vex8rclC.js.map} +1 -1
  123. package/dist/core/web/public/next/assets/{index-CZamKRUg.js → index-D2Eik-zt.js} +3 -3
  124. package/dist/core/web/public/next/assets/{index-CZamKRUg.js.map → index-D2Eik-zt.js.map} +1 -1
  125. package/dist/core/web/public/next/assets/{queries-B8eBnFox.js → queries-bAYU0VNy.js} +2 -2
  126. package/dist/core/web/public/next/assets/{queries-B8eBnFox.js.map → queries-bAYU0VNy.js.map} +1 -1
  127. package/dist/core/web/public/next/assets/use-guarded-action-C7QrP7Yp.js +2 -0
  128. package/dist/core/web/public/next/assets/{use-guarded-action-bzrVVAYq.js.map → use-guarded-action-C7QrP7Yp.js.map} +1 -1
  129. package/dist/core/web/public/next/assets/verse-model-TfDk9cky.js +2 -0
  130. package/dist/core/web/public/next/assets/verse-model-TfDk9cky.js.map +1 -0
  131. package/dist/core/web/public/next/assets/{workspace-model-v0a1gl-C.js → workspace-model-CHol5RVp.js} +2 -2
  132. package/dist/core/web/public/next/assets/{workspace-model-v0a1gl-C.js.map → workspace-model-CHol5RVp.js.map} +1 -1
  133. package/dist/core/web/public/next/index.html +1 -1
  134. package/dist/release-dependency-inventory.json +1 -1
  135. package/docs/README.md +1 -0
  136. package/package.json +1 -1
  137. package/dist/core/web/public/next/assets/AutonomySection-DoqmsCjw.js +0 -2
  138. package/dist/core/web/public/next/assets/ChatSection-BfnLe5dT.css +0 -1
  139. package/dist/core/web/public/next/assets/ChatSection-vNPIJffd.js +0 -80
  140. package/dist/core/web/public/next/assets/ChatSection-vNPIJffd.js.map +0 -1
  141. package/dist/core/web/public/next/assets/ConfirmDialog-Dd2APQhB.js +0 -2
  142. package/dist/core/web/public/next/assets/ConfirmDialog-Dd2APQhB.js.map +0 -1
  143. package/dist/core/web/public/next/assets/Meter--h3MmZS-.js.map +0 -1
  144. package/dist/core/web/public/next/assets/SettingsSection-BwrpQlpP.js +0 -2
  145. package/dist/core/web/public/next/assets/UniverseConsoleApp-_FSohAdN.js +0 -2
  146. package/dist/core/web/public/next/assets/UsageSection-Bq6Daaby.js +0 -2
  147. package/dist/core/web/public/next/assets/UsageSection-Bq6Daaby.js.map +0 -1
  148. package/dist/core/web/public/next/assets/VerseConsoleApp-CMkCizvL.css +0 -1
  149. package/dist/core/web/public/next/assets/VerseConsoleApp-CsIQv9id.js +0 -3
  150. package/dist/core/web/public/next/assets/VerseConsoleApp-CsIQv9id.js.map +0 -1
  151. package/dist/core/web/public/next/assets/global-D6bTxIRn.js +0 -2
  152. package/dist/core/web/public/next/assets/global-D6bTxIRn.js.map +0 -1
  153. package/dist/core/web/public/next/assets/use-guarded-action-bzrVVAYq.js +0 -2
  154. package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js +0 -2
  155. package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js.map +0 -1
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Ashlr Verse — context arithmetic shared by the server and the browser.
3
+ *
4
+ * PURE and BROWSER-SAFE: no node imports, no I/O. The seat catalog, the
5
+ * session engine, the adapters and the UI all compute thresholds through this
6
+ * one module, so "compacts at 367k" can never mean two different numbers in
7
+ * two places. docs/VERSE-CONTEXT.md is the prose authority for every constant.
8
+ *
9
+ * Where each formula comes from (all read from the CLIs themselves, 2026-09-23):
10
+ *
11
+ * Claude Code (2.1.257 and 2.1.280 binaries): the auto-compaction window is
12
+ * `min(--autocompact | autoCompactWindow | auto, model window)`. From it the
13
+ * CLI reserves `min(max output, 20_000)` for the reply and compacts a
14
+ * further 13_000 below that. On a 1M model at `auto` that is 967_000 — the
15
+ * `pre_tokens` observed on real compactions (967_391).
16
+ * Codex (0.136 – 0.155 rollouts): the window the CLI measures against is
17
+ * `context_window × effective_context_window_percent / 100` = 258_400 for
18
+ * every 272k model; auto-compaction triggers at 90% of the RAW window
19
+ * (244_800). The largest uncompacted call across 62,104 was 243_204.
20
+ * Grok (0.2.118 catalog): compacts at `auto_compact_threshold_percent` (80)
21
+ * of `context_window` (500_000) = 400_000.
22
+ * Local seats run the Claude Code binary against Ollama, so they compact by
23
+ * the Claude formula over the window Verse passes in
24
+ * `CLAUDE_CODE_MAX_CONTEXT_TOKENS`.
25
+ */
26
+ import type { VerseContextBudget, VerseContextMode, VerseEngine, VerseFitVerdict, VerseModelOption, VerseSession, VerseUsage } from './types.js';
27
+ /**
28
+ * Standard-mode compaction window for 1M-context Claude models.
29
+ *
30
+ * WHY 400k and not the CLI's ~967k: every turn re-sends the whole prefix, so a
31
+ * session held near 900k costs ~2.3× per call what one held under 400k does,
32
+ * and long-context recall degrades with length on every published benchmark
33
+ * (docs/VERSE-CONTEXT.md §2). 400k keeps a large working set — far above the
34
+ * 150k Anthropic's own API compacts at by default — while leaving the full
35
+ * window one click away in `expansive` mode. Grok's native budget is also
36
+ * 400k, so the two frontier engines share one standard ceiling.
37
+ */
38
+ export declare const CLAUDE_STANDARD_AUTOCOMPACT_WINDOW = 400000;
39
+ /** Claude Code reserves min(max output, this) of the window for the reply. */
40
+ export declare const CLAUDE_OUTPUT_RESERVE_CAP = 20000;
41
+ /** …and compacts this many tokens below the reserved window. */
42
+ export declare const CLAUDE_COMPACT_BUFFER = 13000;
43
+ /** Claude Code clamps `--autocompact` to [100k, 1M]. */
44
+ export declare const CLAUDE_AUTOCOMPACT_MIN = 100000;
45
+ export declare const CLAUDE_AUTOCOMPACT_MAX = 1000000;
46
+ /** Codex: default `effective_context_window_percent` in every catalog entry. */
47
+ export declare const CODEX_EFFECTIVE_WINDOW_PERCENT = 95;
48
+ /** Codex: auto-compaction fires at this fraction of the RAW window. */
49
+ export declare const CODEX_AUTO_COMPACT_FRACTION = 0.9;
50
+ /** Grok: `auto_compact_threshold_percent` in the 0.2.118 catalog. */
51
+ export declare const GROK_AUTO_COMPACT_PERCENT = 80;
52
+ /**
53
+ * How long a provider keeps a conversation's prompt cache warm while idle.
54
+ * Claude Code on a subscription: 1h (5 min without it). Past this, the next
55
+ * turn re-reads the whole context at full price — the single most expensive
56
+ * thing an idle long session can do.
57
+ */
58
+ export declare const CACHE_IDLE_TTL_MS: number;
59
+ /**
60
+ * Fixed prompt overhead (system prompt + tool definitions) a FRESH session
61
+ * already occupies before any work, per engine.
62
+ *
63
+ * local 15k — measured: two real turns through Claude Code 2.1.280 against
64
+ * Ollama with `--exclude-dynamic-system-prompt-sections`
65
+ * reported 14,695 and 14,942 context tokens for a one-word reply.
66
+ * claude 25k — the same CLI without that flag measured 17.8k–23.3k on local
67
+ * seats; rounded up. An ESTIMATE, never shown as a measurement.
68
+ * codex 15k / grok 20k — estimates; neither CLI reports its base prompt.
69
+ *
70
+ * Only used by the fit verdicts, which are labelled as estimates in the UI.
71
+ */
72
+ export declare const SESSION_BASE_OVERHEAD_BY_ENGINE: Readonly<Record<VerseEngine, number>>;
73
+ /** Fallback overhead when the engine is unknown (the largest estimate). */
74
+ export declare const SESSION_BASE_OVERHEAD_TOKENS = 25000;
75
+ export declare function sessionOverheadTokens(engine: VerseEngine | null | undefined): number;
76
+ /**
77
+ * Smallest local window worth offering as a seat. Local turns run Claude Code
78
+ * with `CLAUDE_CODE_MAX_CONTEXT_TOKENS=<window>`, which compacts at
79
+ * `window − 20k − 13k`; below this the compaction point leaves under 8k of
80
+ * working room above the ~15k base prompt, so every turn would compact.
81
+ */
82
+ export declare const LOCAL_MIN_WORKING_TOKENS = 8000;
83
+ export declare const LOCAL_MIN_USABLE_WINDOW: number;
84
+ /** True when a local window leaves real working room under Claude Code's compaction rule. */
85
+ export declare function localWindowUsable(window: number | null | undefined): boolean;
86
+ /** chars → tokens estimator used everywhere a count is estimated rather than measured. */
87
+ export declare const CHARS_PER_TOKEN = 4;
88
+ /**
89
+ * Claude Code's auto-compaction point.
90
+ *
91
+ * @param modelWindow the model's context window (1_000_000, 200_000, or
92
+ * the local num_ctx passed in CLAUDE_CODE_MAX_CONTEXT_TOKENS)
93
+ * @param maxOutputTokens the model's default max output; null → assume the cap
94
+ * @param autocompactWindow the `--autocompact` value in force; null → `auto`
95
+ * (the full model window)
96
+ */
97
+ export declare function claudeAutoCompactAt(modelWindow: number, maxOutputTokens: number | null, autocompactWindow?: number | null): number;
98
+ /** Codex: the window the CLI measures occupancy against. */
99
+ export declare function codexEffectiveWindow(rawWindow: number, percent?: number | null): number;
100
+ /** Codex: where auto-compaction fires for a given RAW window. */
101
+ export declare function codexAutoCompactAt(rawWindow: number): number;
102
+ /** Grok: where auto-compaction fires. */
103
+ export declare function grokAutoCompactAt(window: number, percent?: number | null): number;
104
+ /**
105
+ * Ids Verse once shipped that the CLI does NOT resolve to the model the label
106
+ * promised. `claude-opus-5.5` is parsed by Claude Code as a fuzzy match for
107
+ * `claude-opus-5` (its normaliser rejects the `.5` suffix and falls back to
108
+ * `includes('claude-opus-5')`), so every "Opus 5.5" turn actually ran Opus 5.
109
+ * Old session records keep their stored id; adapters send the canonical one.
110
+ */
111
+ export declare const VERSE_MODEL_ID_ALIASES: Readonly<Record<string, string>>;
112
+ export declare function canonicalModelId(id: string): string;
113
+ /** The budget a model runs with in a mode, or null when that mode does not exist for it. */
114
+ export declare function budgetFor(option: VerseModelOption | null | undefined, mode: VerseContextMode): VerseContextBudget | null;
115
+ /** True when this model has a genuine expansive budget larger than its standard one. */
116
+ export declare function hasExpansiveMode(option: VerseModelOption | null | undefined): boolean;
117
+ /**
118
+ * The `--autocompact` value Verse passes to Claude Code for a model in a mode,
119
+ * or null for "let the CLI use `auto`". Only 1M-native models are capped in
120
+ * standard mode; a 200k model already compacts near 167k natively.
121
+ */
122
+ export declare function claudeAutocompactFlag(option: VerseModelOption | null | undefined, mode: VerseContextMode): number | null;
123
+ /**
124
+ * Recompute the compaction point when the CLI reports a window at runtime
125
+ * that differs from the catalog budget (Claude Code clamps a 1M model to 200k
126
+ * when long-context credit runs out; grok can upgrade a window by header).
127
+ *
128
+ * claude/local — fixed-buffer formula over min(runtime window, --autocompact).
129
+ * codex — the runtime figure is the EFFECTIVE window; the compaction
130
+ * point stays 90% of the raw window it implies.
131
+ * grok/other — keep the budget's compaction RATIO.
132
+ */
133
+ export declare function reconcileAutoCompactAt(input: {
134
+ engine: VerseEngine;
135
+ runtimeWindow: number;
136
+ budget: VerseContextBudget | null;
137
+ /** The `--autocompact` value in force for claude/local; null = auto. */
138
+ autocompactWindow?: number | null;
139
+ maxOutputTokens?: number | null;
140
+ }): number | null;
141
+ export type VerseOccupancyTone = 'unknown' | 'ok' | 'warn' | 'danger' | 'over';
142
+ export interface VerseOccupancy {
143
+ tokens: number;
144
+ window: number | null;
145
+ autoCompactAt: number | null;
146
+ /** tokens / window, unclamped; null when the window is unknown. */
147
+ ofWindow: number | null;
148
+ /** tokens / autoCompactAt, unclamped; null when the compaction point is unknown. */
149
+ ofCompaction: number | null;
150
+ /** Tokens left before auto-compaction (≥ 0), null when unknown. */
151
+ untilCompaction: number | null;
152
+ tone: VerseOccupancyTone;
153
+ /** False when `tokens` is an upper bound (codex before its rollout is readable). */
154
+ exact: boolean;
155
+ }
156
+ /** Warn at 80% of the compaction point, danger from 95% — BEFORE the CLI compacts, not after. */
157
+ export declare const OCCUPANCY_WARN = 0.8;
158
+ export declare const OCCUPANCY_DANGER = 0.95;
159
+ export declare function occupancy(usage: Pick<VerseUsage, 'contextTokens' | 'contextWindow' | 'autoCompactAt' | 'contextTokensExact'>): VerseOccupancy;
160
+ /**
161
+ * Share of prompt tokens served from cache: cacheRead / (input + cacheRead +
162
+ * cacheCreation). Adapters already report `inputTokens` EXCLUDING cached
163
+ * tokens (codex's turn total is split by its adapter), so the buckets are
164
+ * disjoint. Null when nothing has been read yet.
165
+ */
166
+ export declare function cacheHitRatio(usage: Pick<VerseUsage, 'inputTokens' | 'cacheReadTokens' | 'cacheCreationTokens'>): number | null;
167
+ export declare function estimateTokensFromChars(chars: number): number;
168
+ /**
169
+ * Would this working set fit one context on this model?
170
+ *
171
+ * fits — working set + fixed overhead ≤ 60% of the standard compaction point
172
+ * tight — ≤ 100% of it: it fits, but the session will compact soon
173
+ * expansive — only the expansive budget holds it
174
+ * split — no single context holds it; fan the work out instead
175
+ *
176
+ * Null when the model's budget is unknown (never guessed). Pass the engine's
177
+ * `sessionOverheadTokens(engine)`; the default is the largest estimate.
178
+ */
179
+ export declare function fitVerdict(workingSetTokens: number, option: VerseModelOption | null | undefined, overheadTokens?: number): VerseFitVerdict | null;
180
+ export type VerseAdviceLevel = 'none' | 'suggest' | 'urge';
181
+ export interface VerseHandoffAdvice {
182
+ level: VerseAdviceLevel;
183
+ /** Plain sentences, most important first. Empty when level is 'none'. */
184
+ reasons: string[];
185
+ }
186
+ /** Compactions after which early-turn detail is mostly summaries. */
187
+ export declare const HANDOFF_COMPACTION_THRESHOLD = 2;
188
+ /** Below this, an expired cache is cheap to re-read and not worth a handoff. */
189
+ export declare const HANDOFF_IDLE_MIN_TOKENS = 100000;
190
+ /**
191
+ * Should the operator continue in a fresh session? Pure: `now` and
192
+ * `lastActivityAt` are passed in, so the verdict is reproducible in tests.
193
+ */
194
+ export declare function handoffAdvice(input: {
195
+ usage: VerseUsage;
196
+ compactionCount?: number;
197
+ lastActivityAt?: string | null;
198
+ now: number;
199
+ }): VerseHandoffAdvice;
200
+ export interface VerseExpansiveAdvice {
201
+ suggest: boolean;
202
+ reason: string | null;
203
+ }
204
+ /**
205
+ * Suggest — never switch on — expansive mode. Only for a session in standard
206
+ * mode whose model has a real expansive budget, and only on evidence: it has
207
+ * already compacted repeatedly, or its working set only fits expansive.
208
+ */
209
+ export declare function expansiveAdvice(input: {
210
+ session: Pick<VerseSession, 'contextMode' | 'compactionCount'>;
211
+ option: VerseModelOption | null | undefined;
212
+ workingSetTokens?: number | null;
213
+ }): VerseExpansiveAdvice;
214
+ /** Engines whose CLIs can be told a compaction budget per invocation. */
215
+ export declare function engineSupportsModes(engine: VerseEngine): boolean;
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Ashlr Verse — context arithmetic shared by the server and the browser.
3
+ *
4
+ * PURE and BROWSER-SAFE: no node imports, no I/O. The seat catalog, the
5
+ * session engine, the adapters and the UI all compute thresholds through this
6
+ * one module, so "compacts at 367k" can never mean two different numbers in
7
+ * two places. docs/VERSE-CONTEXT.md is the prose authority for every constant.
8
+ *
9
+ * Where each formula comes from (all read from the CLIs themselves, 2026-09-23):
10
+ *
11
+ * Claude Code (2.1.257 and 2.1.280 binaries): the auto-compaction window is
12
+ * `min(--autocompact | autoCompactWindow | auto, model window)`. From it the
13
+ * CLI reserves `min(max output, 20_000)` for the reply and compacts a
14
+ * further 13_000 below that. On a 1M model at `auto` that is 967_000 — the
15
+ * `pre_tokens` observed on real compactions (967_391).
16
+ * Codex (0.136 – 0.155 rollouts): the window the CLI measures against is
17
+ * `context_window × effective_context_window_percent / 100` = 258_400 for
18
+ * every 272k model; auto-compaction triggers at 90% of the RAW window
19
+ * (244_800). The largest uncompacted call across 62,104 was 243_204.
20
+ * Grok (0.2.118 catalog): compacts at `auto_compact_threshold_percent` (80)
21
+ * of `context_window` (500_000) = 400_000.
22
+ * Local seats run the Claude Code binary against Ollama, so they compact by
23
+ * the Claude formula over the window Verse passes in
24
+ * `CLAUDE_CODE_MAX_CONTEXT_TOKENS`.
25
+ */
26
+ // ---------------------------------------------------------------------------
27
+ // Constants
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * Standard-mode compaction window for 1M-context Claude models.
31
+ *
32
+ * WHY 400k and not the CLI's ~967k: every turn re-sends the whole prefix, so a
33
+ * session held near 900k costs ~2.3× per call what one held under 400k does,
34
+ * and long-context recall degrades with length on every published benchmark
35
+ * (docs/VERSE-CONTEXT.md §2). 400k keeps a large working set — far above the
36
+ * 150k Anthropic's own API compacts at by default — while leaving the full
37
+ * window one click away in `expansive` mode. Grok's native budget is also
38
+ * 400k, so the two frontier engines share one standard ceiling.
39
+ */
40
+ export const CLAUDE_STANDARD_AUTOCOMPACT_WINDOW = 400_000;
41
+ /** Claude Code reserves min(max output, this) of the window for the reply. */
42
+ export const CLAUDE_OUTPUT_RESERVE_CAP = 20_000;
43
+ /** …and compacts this many tokens below the reserved window. */
44
+ export const CLAUDE_COMPACT_BUFFER = 13_000;
45
+ /** Claude Code clamps `--autocompact` to [100k, 1M]. */
46
+ export const CLAUDE_AUTOCOMPACT_MIN = 100_000;
47
+ export const CLAUDE_AUTOCOMPACT_MAX = 1_000_000;
48
+ /** Codex: default `effective_context_window_percent` in every catalog entry. */
49
+ export const CODEX_EFFECTIVE_WINDOW_PERCENT = 95;
50
+ /** Codex: auto-compaction fires at this fraction of the RAW window. */
51
+ export const CODEX_AUTO_COMPACT_FRACTION = 0.9;
52
+ /** Grok: `auto_compact_threshold_percent` in the 0.2.118 catalog. */
53
+ export const GROK_AUTO_COMPACT_PERCENT = 80;
54
+ /**
55
+ * How long a provider keeps a conversation's prompt cache warm while idle.
56
+ * Claude Code on a subscription: 1h (5 min without it). Past this, the next
57
+ * turn re-reads the whole context at full price — the single most expensive
58
+ * thing an idle long session can do.
59
+ */
60
+ export const CACHE_IDLE_TTL_MS = 60 * 60 * 1000;
61
+ /**
62
+ * Fixed prompt overhead (system prompt + tool definitions) a FRESH session
63
+ * already occupies before any work, per engine.
64
+ *
65
+ * local 15k — measured: two real turns through Claude Code 2.1.280 against
66
+ * Ollama with `--exclude-dynamic-system-prompt-sections`
67
+ * reported 14,695 and 14,942 context tokens for a one-word reply.
68
+ * claude 25k — the same CLI without that flag measured 17.8k–23.3k on local
69
+ * seats; rounded up. An ESTIMATE, never shown as a measurement.
70
+ * codex 15k / grok 20k — estimates; neither CLI reports its base prompt.
71
+ *
72
+ * Only used by the fit verdicts, which are labelled as estimates in the UI.
73
+ */
74
+ export const SESSION_BASE_OVERHEAD_BY_ENGINE = {
75
+ claude: 25_000,
76
+ codex: 15_000,
77
+ grok: 20_000,
78
+ local: 15_000,
79
+ };
80
+ /** Fallback overhead when the engine is unknown (the largest estimate). */
81
+ export const SESSION_BASE_OVERHEAD_TOKENS = 25_000;
82
+ export function sessionOverheadTokens(engine) {
83
+ return engine ? SESSION_BASE_OVERHEAD_BY_ENGINE[engine] ?? SESSION_BASE_OVERHEAD_TOKENS : SESSION_BASE_OVERHEAD_TOKENS;
84
+ }
85
+ /**
86
+ * Smallest local window worth offering as a seat. Local turns run Claude Code
87
+ * with `CLAUDE_CODE_MAX_CONTEXT_TOKENS=<window>`, which compacts at
88
+ * `window − 20k − 13k`; below this the compaction point leaves under 8k of
89
+ * working room above the ~15k base prompt, so every turn would compact.
90
+ */
91
+ export const LOCAL_MIN_WORKING_TOKENS = 8_000;
92
+ export const LOCAL_MIN_USABLE_WINDOW = SESSION_BASE_OVERHEAD_BY_ENGINE.local + LOCAL_MIN_WORKING_TOKENS + CLAUDE_OUTPUT_RESERVE_CAP + CLAUDE_COMPACT_BUFFER;
93
+ /** True when a local window leaves real working room under Claude Code's compaction rule. */
94
+ export function localWindowUsable(window) {
95
+ return typeof window === 'number' && Number.isFinite(window) && window >= LOCAL_MIN_USABLE_WINDOW;
96
+ }
97
+ /** chars → tokens estimator used everywhere a count is estimated rather than measured. */
98
+ export const CHARS_PER_TOKEN = 4;
99
+ // ---------------------------------------------------------------------------
100
+ // Per-engine formulas
101
+ // ---------------------------------------------------------------------------
102
+ function positiveInt(value) {
103
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.floor(value) : null;
104
+ }
105
+ /**
106
+ * Claude Code's auto-compaction point.
107
+ *
108
+ * @param modelWindow the model's context window (1_000_000, 200_000, or
109
+ * the local num_ctx passed in CLAUDE_CODE_MAX_CONTEXT_TOKENS)
110
+ * @param maxOutputTokens the model's default max output; null → assume the cap
111
+ * @param autocompactWindow the `--autocompact` value in force; null → `auto`
112
+ * (the full model window)
113
+ */
114
+ export function claudeAutoCompactAt(modelWindow, maxOutputTokens, autocompactWindow = null) {
115
+ const window = Math.min(modelWindow, positiveInt(autocompactWindow) ?? modelWindow);
116
+ const reserve = Math.min(positiveInt(maxOutputTokens) ?? CLAUDE_OUTPUT_RESERVE_CAP, CLAUDE_OUTPUT_RESERVE_CAP);
117
+ return Math.max(0, window - reserve - CLAUDE_COMPACT_BUFFER);
118
+ }
119
+ /** Codex: the window the CLI measures occupancy against. */
120
+ export function codexEffectiveWindow(rawWindow, percent = null) {
121
+ const pct = positiveInt(percent) !== null && percent <= 100 ? percent : CODEX_EFFECTIVE_WINDOW_PERCENT;
122
+ return Math.floor((rawWindow * pct) / 100);
123
+ }
124
+ /** Codex: where auto-compaction fires for a given RAW window. */
125
+ export function codexAutoCompactAt(rawWindow) {
126
+ return Math.floor(rawWindow * CODEX_AUTO_COMPACT_FRACTION);
127
+ }
128
+ /** Grok: where auto-compaction fires. */
129
+ export function grokAutoCompactAt(window, percent = null) {
130
+ const pct = positiveInt(percent) !== null && percent <= 100 ? percent : GROK_AUTO_COMPACT_PERCENT;
131
+ return Math.floor((window * pct) / 100);
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Model ids
135
+ // ---------------------------------------------------------------------------
136
+ /**
137
+ * Ids Verse once shipped that the CLI does NOT resolve to the model the label
138
+ * promised. `claude-opus-5.5` is parsed by Claude Code as a fuzzy match for
139
+ * `claude-opus-5` (its normaliser rejects the `.5` suffix and falls back to
140
+ * `includes('claude-opus-5')`), so every "Opus 5.5" turn actually ran Opus 5.
141
+ * Old session records keep their stored id; adapters send the canonical one.
142
+ */
143
+ export const VERSE_MODEL_ID_ALIASES = {
144
+ 'claude-opus-5.5': 'claude-opus-5-5',
145
+ };
146
+ export function canonicalModelId(id) {
147
+ return VERSE_MODEL_ID_ALIASES[id] ?? id;
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Budgets and occupancy
151
+ // ---------------------------------------------------------------------------
152
+ /** The budget a model runs with in a mode, or null when that mode does not exist for it. */
153
+ export function budgetFor(option, mode) {
154
+ if (!option)
155
+ return null;
156
+ if (mode === 'expansive')
157
+ return option.expansive ?? null;
158
+ const window = positiveInt(option.contextWindow);
159
+ if (window === null)
160
+ return null;
161
+ return { contextWindow: window, autoCompactAt: positiveInt(option.autoCompactAt ?? null) };
162
+ }
163
+ /** True when this model has a genuine expansive budget larger than its standard one. */
164
+ export function hasExpansiveMode(option) {
165
+ const standard = budgetFor(option, 'standard');
166
+ const expansive = budgetFor(option, 'expansive');
167
+ if (!expansive)
168
+ return false;
169
+ if (!standard)
170
+ return true;
171
+ return (expansive.autoCompactAt ?? expansive.contextWindow) > (standard.autoCompactAt ?? standard.contextWindow);
172
+ }
173
+ /**
174
+ * The `--autocompact` value Verse passes to Claude Code for a model in a mode,
175
+ * or null for "let the CLI use `auto`". Only 1M-native models are capped in
176
+ * standard mode; a 200k model already compacts near 167k natively.
177
+ */
178
+ export function claudeAutocompactFlag(option, mode) {
179
+ if (mode === 'expansive')
180
+ return null;
181
+ const window = positiveInt(option?.contextWindow ?? null);
182
+ return window !== null && window > CLAUDE_STANDARD_AUTOCOMPACT_WINDOW && hasExpansiveMode(option)
183
+ ? CLAUDE_STANDARD_AUTOCOMPACT_WINDOW
184
+ : null;
185
+ }
186
+ /**
187
+ * Recompute the compaction point when the CLI reports a window at runtime
188
+ * that differs from the catalog budget (Claude Code clamps a 1M model to 200k
189
+ * when long-context credit runs out; grok can upgrade a window by header).
190
+ *
191
+ * claude/local — fixed-buffer formula over min(runtime window, --autocompact).
192
+ * codex — the runtime figure is the EFFECTIVE window; the compaction
193
+ * point stays 90% of the raw window it implies.
194
+ * grok/other — keep the budget's compaction RATIO.
195
+ */
196
+ export function reconcileAutoCompactAt(input) {
197
+ const runtime = positiveInt(input.runtimeWindow);
198
+ if (runtime === null)
199
+ return input.budget?.autoCompactAt ?? null;
200
+ if (input.budget && input.budget.contextWindow === runtime)
201
+ return input.budget.autoCompactAt;
202
+ switch (input.engine) {
203
+ case 'claude':
204
+ case 'local':
205
+ return claudeAutoCompactAt(runtime, input.maxOutputTokens ?? null, input.autocompactWindow ?? null);
206
+ case 'codex':
207
+ return codexAutoCompactAt(Math.round((runtime * 100) / CODEX_EFFECTIVE_WINDOW_PERCENT));
208
+ default: {
209
+ const b = input.budget;
210
+ if (!b || b.autoCompactAt === null || b.contextWindow <= 0)
211
+ return null;
212
+ return Math.floor(runtime * (b.autoCompactAt / b.contextWindow));
213
+ }
214
+ }
215
+ }
216
+ /** Warn at 80% of the compaction point, danger from 95% — BEFORE the CLI compacts, not after. */
217
+ export const OCCUPANCY_WARN = 0.8;
218
+ export const OCCUPANCY_DANGER = 0.95;
219
+ export function occupancy(usage) {
220
+ const tokens = Math.max(0, Math.floor(usage.contextTokens || 0));
221
+ const window = positiveInt(usage.contextWindow);
222
+ const compactAt = positiveInt(usage.autoCompactAt ?? null);
223
+ const ofWindow = window !== null ? tokens / window : null;
224
+ const ofCompaction = compactAt !== null ? tokens / compactAt : null;
225
+ const gauge = ofCompaction ?? ofWindow;
226
+ const exact = usage.contextTokensExact !== false;
227
+ let tone = 'unknown';
228
+ if (!exact && gauge !== null && gauge >= 1) {
229
+ // An UPPER BOUND past the compaction point says nothing about the real
230
+ // prompt: codex's turn total sums every model call (median 29× the last
231
+ // one). Claiming "over the window" from it would be invented precision.
232
+ tone = 'unknown';
233
+ }
234
+ else if (window !== null && tokens > window)
235
+ tone = 'over';
236
+ else if (gauge !== null)
237
+ tone = gauge >= OCCUPANCY_DANGER ? 'danger' : gauge >= OCCUPANCY_WARN ? 'warn' : 'ok';
238
+ return {
239
+ tokens,
240
+ window,
241
+ autoCompactAt: compactAt,
242
+ ofWindow,
243
+ ofCompaction,
244
+ untilCompaction: compactAt !== null ? Math.max(0, compactAt - tokens) : null,
245
+ tone,
246
+ exact,
247
+ };
248
+ }
249
+ // ---------------------------------------------------------------------------
250
+ // Efficiency
251
+ // ---------------------------------------------------------------------------
252
+ /**
253
+ * Share of prompt tokens served from cache: cacheRead / (input + cacheRead +
254
+ * cacheCreation). Adapters already report `inputTokens` EXCLUDING cached
255
+ * tokens (codex's turn total is split by its adapter), so the buckets are
256
+ * disjoint. Null when nothing has been read yet.
257
+ */
258
+ export function cacheHitRatio(usage) {
259
+ const denominator = usage.inputTokens + usage.cacheReadTokens + usage.cacheCreationTokens;
260
+ return denominator > 0 ? usage.cacheReadTokens / denominator : null;
261
+ }
262
+ export function estimateTokensFromChars(chars) {
263
+ return Math.ceil(Math.max(0, chars) / CHARS_PER_TOKEN);
264
+ }
265
+ // ---------------------------------------------------------------------------
266
+ // Advice (pure; the UI decides how to show it, nothing here spends)
267
+ // ---------------------------------------------------------------------------
268
+ /**
269
+ * Would this working set fit one context on this model?
270
+ *
271
+ * fits — working set + fixed overhead ≤ 60% of the standard compaction point
272
+ * tight — ≤ 100% of it: it fits, but the session will compact soon
273
+ * expansive — only the expansive budget holds it
274
+ * split — no single context holds it; fan the work out instead
275
+ *
276
+ * Null when the model's budget is unknown (never guessed). Pass the engine's
277
+ * `sessionOverheadTokens(engine)`; the default is the largest estimate.
278
+ */
279
+ export function fitVerdict(workingSetTokens, option, overheadTokens = SESSION_BASE_OVERHEAD_TOKENS) {
280
+ const standard = budgetFor(option, 'standard');
281
+ if (!standard)
282
+ return null;
283
+ const need = Math.max(0, workingSetTokens) + Math.max(0, overheadTokens);
284
+ const standardCap = standard.autoCompactAt ?? standard.contextWindow;
285
+ if (need <= standardCap * 0.6)
286
+ return 'fits';
287
+ if (need <= standardCap)
288
+ return 'tight';
289
+ const expansive = budgetFor(option, 'expansive');
290
+ if (expansive && need <= (expansive.autoCompactAt ?? expansive.contextWindow))
291
+ return 'expansive';
292
+ return 'split';
293
+ }
294
+ /** Compactions after which early-turn detail is mostly summaries. */
295
+ export const HANDOFF_COMPACTION_THRESHOLD = 2;
296
+ /** Below this, an expired cache is cheap to re-read and not worth a handoff. */
297
+ export const HANDOFF_IDLE_MIN_TOKENS = 100_000;
298
+ function compactTokens(n) {
299
+ if (n >= 1_000_000)
300
+ return `${(n / 1_000_000).toFixed(n % 1_000_000 === 0 ? 0 : 1)}M`;
301
+ if (n >= 1_000)
302
+ return `${Math.round(n / 1_000)}k`;
303
+ return String(n);
304
+ }
305
+ /**
306
+ * Should the operator continue in a fresh session? Pure: `now` and
307
+ * `lastActivityAt` are passed in, so the verdict is reproducible in tests.
308
+ */
309
+ export function handoffAdvice(input) {
310
+ const occ = occupancy(input.usage);
311
+ const reasons = [];
312
+ let level = 'none';
313
+ const bump = (to) => {
314
+ // (level only ever rises)
315
+ if (to === 'urge' || (to === 'suggest' && level === 'none'))
316
+ level = to;
317
+ };
318
+ if (!occ.exact) {
319
+ // An upper bound cannot justify "you are near compaction"; wait for a reading.
320
+ }
321
+ else if (occ.tone === 'over') {
322
+ bump('urge');
323
+ reasons.push(`Context (${compactTokens(occ.tokens)}) is past the ${compactTokens(occ.window ?? 0)} window.`);
324
+ }
325
+ else if (occ.ofCompaction !== null && occ.ofCompaction >= OCCUPANCY_WARN) {
326
+ bump('suggest');
327
+ reasons.push(`About ${compactTokens(occ.untilCompaction ?? 0)} tokens left before the CLI auto-compacts.`);
328
+ }
329
+ const compactions = input.compactionCount ?? 0;
330
+ if (compactions >= HANDOFF_COMPACTION_THRESHOLD) {
331
+ bump('suggest');
332
+ reasons.push(`Compacted ${compactions} times — early turns now survive only as summaries.`);
333
+ }
334
+ if (input.lastActivityAt) {
335
+ const idle = input.now - Date.parse(input.lastActivityAt);
336
+ if (occ.exact && Number.isFinite(idle) && idle >= CACHE_IDLE_TTL_MS && occ.tokens >= HANDOFF_IDLE_MIN_TOKENS) {
337
+ bump('suggest');
338
+ reasons.push(`Idle over an hour: the prompt cache has likely expired, so the next turn re-reads ~${compactTokens(occ.tokens)} tokens at full cost.`);
339
+ }
340
+ }
341
+ return { level, reasons };
342
+ }
343
+ /**
344
+ * Suggest — never switch on — expansive mode. Only for a session in standard
345
+ * mode whose model has a real expansive budget, and only on evidence: it has
346
+ * already compacted repeatedly, or its working set only fits expansive.
347
+ */
348
+ export function expansiveAdvice(input) {
349
+ if ((input.session.contextMode ?? 'standard') !== 'standard' || !hasExpansiveMode(input.option)) {
350
+ return { suggest: false, reason: null };
351
+ }
352
+ const compactions = input.session.compactionCount ?? 0;
353
+ if (compactions >= HANDOFF_COMPACTION_THRESHOLD) {
354
+ return { suggest: true, reason: `This session has compacted ${compactions} times; expansive mode keeps more of it in view.` };
355
+ }
356
+ if (typeof input.workingSetTokens === 'number' && fitVerdict(input.workingSetTokens, input.option) === 'expansive') {
357
+ return { suggest: true, reason: `The reachable code (~${compactTokens(input.workingSetTokens)} tokens) only fits the expansive budget.` };
358
+ }
359
+ return { suggest: false, reason: null };
360
+ }
361
+ /** Engines whose CLIs can be told a compaction budget per invocation. */
362
+ export function engineSupportsModes(engine) {
363
+ return engine === 'claude' || engine === 'codex';
364
+ }
365
+ //# sourceMappingURL=context-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-math.js","sourceRoot":"","sources":["../../../src/core/verse/context-math.ts"],"names":[],"mappings":"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"}