sidekick-shared 0.27.6 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +58 -18
- package/dist/browser.d.ts +13 -2
- package/dist/browser.js +30 -2
- package/dist/claudePaths.d.ts +11 -0
- package/dist/claudePaths.js +61 -0
- package/dist/claudeProfiles.d.ts +2 -9
- package/dist/claudeProfiles.js +10 -25
- package/dist/codexPaths.d.ts +22 -0
- package/dist/codexPaths.js +67 -0
- package/dist/codexProfiles.d.ts +1 -4
- package/dist/codexProfiles.js +5 -43
- package/dist/doctor.js +2 -2
- package/dist/esm/accountChangeSignal.js +15 -0
- package/dist/esm/accountChanges.js +152 -0
- package/dist/esm/accountHealth.js +288 -0
- package/dist/esm/accountLaunch.js +145 -0
- package/dist/esm/accountLease.js +60 -0
- package/dist/esm/accountManager.js +606 -0
- package/dist/esm/accountRegistry.js +214 -0
- package/dist/esm/accountStatus.js +51 -0
- package/dist/esm/accountSwitch.js +74 -0
- package/dist/esm/accountSync.js +156 -0
- package/dist/esm/accountSyncTypes.js +4 -0
- package/dist/esm/accounts.js +1291 -0
- package/dist/esm/aggregation/EventAggregator.js +2034 -0
- package/dist/esm/aggregation/FrequencyTracker.js +69 -0
- package/dist/esm/aggregation/HeatmapTracker.js +89 -0
- package/dist/esm/aggregation/PatternExtractor.js +168 -0
- package/dist/esm/aggregation/costProvenance.js +31 -0
- package/dist/esm/aggregation/snapshot.js +161 -0
- package/dist/esm/aggregation/types.js +5 -0
- package/dist/esm/analytics/codeImpact.js +18 -0
- package/dist/esm/analytics/compactionLedger.js +37 -0
- package/dist/esm/analytics/qualityScore.js +112 -0
- package/dist/esm/autoSwitch.js +185 -0
- package/dist/esm/browser.js +34 -0
- package/dist/esm/claudeCredentialDoctor.js +239 -0
- package/dist/esm/claudeCredentialLedger.js +91 -0
- package/dist/esm/claudeCredentials.js +111 -0
- package/dist/esm/claudeLiveGuard.js +43 -0
- package/dist/esm/claudePaths.js +22 -0
- package/dist/esm/claudeProfiles.js +142 -0
- package/dist/esm/claudeRefreshLock.js +106 -0
- package/dist/esm/codexAuth.js +101 -0
- package/dist/esm/codexCredentialDoctor.js +265 -0
- package/dist/esm/codexCredentialStore.js +164 -0
- package/dist/esm/codexKeepAlive.js +112 -0
- package/dist/esm/codexPaths.js +172 -0
- package/dist/esm/codexProfiles.js +1251 -0
- package/dist/esm/codexQuota.js +564 -0
- package/dist/esm/codexQuotaWatcher.js +363 -0
- package/dist/esm/context/composer.js +71 -0
- package/dist/esm/context/sessionContext.js +546 -0
- package/dist/esm/credentialIO.js +283 -0
- package/dist/esm/credentials.js +49 -0
- package/dist/esm/doctor.js +305 -0
- package/dist/esm/ensureDefaultAccounts.js +62 -0
- package/dist/esm/errorHistory.js +56 -0
- package/dist/esm/extractors/errorTaxonomy.js +43 -0
- package/dist/esm/extractors/gatherAssets.js +32 -0
- package/dist/esm/extractors/sessionAssets.js +176 -0
- package/dist/esm/extractors/sources/claudeAssets.js +158 -0
- package/dist/esm/extractors/sources/codexAssets.js +234 -0
- package/dist/esm/extractors/tokenUsage.js +41 -0
- package/dist/esm/extractors/toolCall.js +142 -0
- package/dist/esm/failingTools.js +65 -0
- package/dist/esm/fileHead.js +27 -0
- package/dist/esm/formatters/eventHighlighter.js +332 -0
- package/dist/esm/formatters/noiseClassifier.js +209 -0
- package/dist/esm/formatters/sessionDump.js +328 -0
- package/dist/esm/formatters/toolSummary.js +226 -0
- package/dist/esm/formatting.js +82 -0
- package/dist/esm/handoffUrl.js +23 -0
- package/dist/esm/historicalStore.js +305 -0
- package/dist/esm/humanPrompt.js +88 -0
- package/dist/esm/index.js +213 -0
- package/dist/esm/keepAlive.js +189 -0
- package/dist/esm/liveCredentialGuard.js +33 -0
- package/dist/esm/modelAliases.js +51 -0
- package/dist/esm/modelCatalog.js +139 -0
- package/dist/esm/modelContext.js +280 -0
- package/dist/esm/modelInfo.js +832 -0
- package/dist/esm/multiProviderQuotaService.js +450 -0
- package/dist/esm/node.js +46 -0
- package/dist/esm/observedContextWindows.js +165 -0
- package/dist/esm/observedSessionCollector.js +939 -0
- package/dist/esm/parsers/changelogParser.js +71 -0
- package/dist/esm/parsers/codexHistory.js +89 -0
- package/dist/esm/parsers/codexParser.js +906 -0
- package/dist/esm/parsers/debugLogParser.js +126 -0
- package/dist/esm/parsers/jsonl.js +66 -0
- package/dist/esm/parsers/mcpToolName.js +28 -0
- package/dist/esm/parsers/openCodeParser.js +625 -0
- package/dist/esm/parsers/planExtractor.js +335 -0
- package/dist/esm/parsers/sessionActivityDetector.js +246 -0
- package/dist/esm/parsers/sessionPathResolver.js +713 -0
- package/dist/esm/parsers/subagentScanner.js +360 -0
- package/dist/esm/parsers/subagentStatsCache.js +45 -0
- package/dist/esm/parsers/subagentTraceParser.js +325 -0
- package/dist/esm/paths.js +134 -0
- package/dist/esm/peakHours.js +194 -0
- package/dist/esm/phrases.js +1330 -0
- package/dist/esm/pricingCatalog.js +247 -0
- package/dist/esm/processDetection.js +200 -0
- package/dist/esm/projectMigration.js +59 -0
- package/dist/esm/promptHistory.js +1221 -0
- package/dist/esm/providerFailure.js +362 -0
- package/dist/esm/providerIds.js +6 -0
- package/dist/esm/providerQuota.js +1 -0
- package/dist/esm/providerServiceStatus.js +145 -0
- package/dist/esm/providerServiceStatusTypes.js +1 -0
- package/dist/esm/providerStatus.js +117 -0
- package/dist/esm/providers/claudeCode.js +575 -0
- package/dist/esm/providers/claudeListing.js +121 -0
- package/dist/esm/providers/codex.js +1034 -0
- package/dist/esm/providers/codexDatabase.js +297 -0
- package/dist/esm/providers/codexRollouts.js +215 -0
- package/dist/esm/providers/detect.js +185 -0
- package/dist/esm/providers/diagnostics.js +83 -0
- package/dist/esm/providers/directoryListingCache.js +206 -0
- package/dist/esm/providers/factory.js +54 -0
- package/dist/esm/providers/openCode.js +2008 -0
- package/dist/esm/providers/openCodeDatabase.js +419 -0
- package/dist/esm/providers/rolloutWalker.js +252 -0
- package/dist/esm/providers/types.js +12 -0
- package/dist/esm/quota.js +182 -0
- package/dist/esm/quotaHistory.js +364 -0
- package/dist/esm/quotaPoller.js +230 -0
- package/dist/esm/quotaPresentation.js +97 -0
- package/dist/esm/quotaResolver.js +231 -0
- package/dist/esm/quotaSnapshots.js +130 -0
- package/dist/esm/quotaThresholds.js +85 -0
- package/dist/esm/readers/decisions.js +24 -0
- package/dist/esm/readers/handoff.js +20 -0
- package/dist/esm/readers/helpers.js +27 -0
- package/dist/esm/readers/history.js +9 -0
- package/dist/esm/readers/notes.js +48 -0
- package/dist/esm/readers/plans.js +225 -0
- package/dist/esm/readers/tasks.js +19 -0
- package/dist/esm/report/htmlHelpers.js +280 -0
- package/dist/esm/report/htmlReportGenerator.js +704 -0
- package/dist/esm/report/index.js +7 -0
- package/dist/esm/report/logo.js +2 -0
- package/dist/esm/report/openBrowser.js +19 -0
- package/dist/esm/report/sessionReportInputs.js +33 -0
- package/dist/esm/report/transcriptParser.js +83 -0
- package/dist/esm/report/types.js +4 -0
- package/dist/esm/schemas/accountManager.js +204 -0
- package/dist/esm/schemas/accountStatus.js +25 -0
- package/dist/esm/schemas/assistantTurn.js +74 -0
- package/dist/esm/schemas/index.js +25 -0
- package/dist/esm/schemas/observedSessionV1.js +77 -0
- package/dist/esm/schemas/providerFailure.js +37 -0
- package/dist/esm/schemas/quota.js +132 -0
- package/dist/esm/schemas/quotaHistory.js +40 -0
- package/dist/esm/schemas/sessionEvent.js +216 -0
- package/dist/esm/schemas/stateFile.js +75 -0
- package/dist/esm/schemas/tokenEstimation.js +7 -0
- package/dist/esm/schemas/transcript.js +86 -0
- package/dist/esm/schemas/usageNormalization.js +38 -0
- package/dist/esm/search/advancedFilter.js +197 -0
- package/dist/esm/search/sessionSearch.js +66 -0
- package/dist/esm/sessionFingerprint.js +40 -0
- package/dist/esm/sessionMonitor.js +198 -0
- package/dist/esm/sessionPreviews.js +522 -0
- package/dist/esm/sessionPromptHistory.js +254 -0
- package/dist/esm/sessionPromptSignals.js +364 -0
- package/dist/esm/sessionStats.js +160 -0
- package/dist/esm/sessionTokenTotals.js +98 -0
- package/dist/esm/sessionTranscripts.js +49 -0
- package/dist/esm/stateFile.js +119 -0
- package/dist/esm/statusline/BurnRateCalculator.js +40 -0
- package/dist/esm/statusline/claudeStatuslinePayload.js +148 -0
- package/dist/esm/statusline/formatter.js +122 -0
- package/dist/esm/statusline/index.js +8 -0
- package/dist/esm/terminalSync.js +95 -0
- package/dist/esm/testing/credentialGuard.js +197 -0
- package/dist/esm/testing/index.js +12 -0
- package/dist/esm/testing/sessionLogFixtures.js +128 -0
- package/dist/esm/tokenEstimation.js +67 -0
- package/dist/esm/tokenSummary.js +113 -0
- package/dist/esm/toolCategory.js +82 -0
- package/dist/esm/transcript.js +257 -0
- package/dist/esm/turns/assistantTurn.js +373 -0
- package/dist/esm/types/codex.js +23 -0
- package/dist/esm/types/decisionLog.js +5 -0
- package/dist/esm/types/historicalData.js +47 -0
- package/dist/esm/types/knowledgeNote.js +15 -0
- package/dist/esm/types/observedSessionV1.js +257 -0
- package/dist/esm/types/opencode.js +12 -0
- package/dist/esm/types/plan.js +7 -0
- package/dist/esm/types/sessionEvent.js +10 -0
- package/dist/esm/types/taskPersistence.js +12 -0
- package/dist/esm/usage/billingBlocks.js +148 -0
- package/dist/esm/usage/claudeUsageDedupe.js +189 -0
- package/dist/esm/usage/importSessionHistory.js +84 -0
- package/dist/esm/usage/subagentUsage.js +18 -0
- package/dist/esm/usage/usageEvents.js +402 -0
- package/dist/esm/usage/usageReports.js +202 -0
- package/dist/esm/usageNormalization.js +95 -0
- package/dist/esm/watchers/eventBridge.js +219 -0
- package/dist/esm/watchers/factory.js +63 -0
- package/dist/esm/watchers/jsonlTail.js +289 -0
- package/dist/esm/watchers/jsonlWatcher.js +435 -0
- package/dist/esm/watchers/providerReaderWatcher.js +118 -0
- package/dist/esm/watchers/sqliteWatcher.js +285 -0
- package/dist/esm/watchers/types.js +4 -0
- package/dist/esm/workspaceRoots.js +56 -0
- package/dist/esm/writers/atomic.js +375 -0
- package/dist/esm/writers/decisions.js +51 -0
- package/dist/esm/writers/notes.js +46 -0
- package/dist/esm/writers/tasks.js +63 -0
- package/dist/esm/zaiQuota.js +323 -0
- package/dist/esm/zaiQuotaApi.js +271 -0
- package/dist/esm/zaiQuotaWatcher.js +265 -0
- package/dist/fileHead.d.ts +22 -0
- package/dist/fileHead.js +33 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.js +49 -15
- package/dist/node.d.ts +13 -1
- package/dist/node.js +43 -2
- package/dist/parsers/codexHistory.js +2 -2
- package/dist/parsers/codexParser.d.ts +12 -0
- package/dist/parsers/codexParser.js +34 -12
- package/dist/parsers/debugLogParser.js +2 -2
- package/dist/parsers/sessionPathResolver.js +5 -4
- package/dist/promptHistory.d.ts +32 -0
- package/dist/promptHistory.js +115 -59
- package/dist/providerFailure.d.ts +12 -6
- package/dist/providerFailure.js +45 -0
- package/dist/providers/claudeCode.js +7 -99
- package/dist/providers/claudeListing.d.ts +22 -0
- package/dist/providers/claudeListing.js +158 -0
- package/dist/providers/codex.d.ts +3 -1
- package/dist/providers/codex.js +26 -227
- package/dist/providers/codexRollouts.d.ts +44 -0
- package/dist/providers/codexRollouts.js +261 -0
- package/dist/providers/detect.js +4 -4
- package/dist/readers/plans.js +3 -3
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/providerFailure.d.ts +154 -0
- package/dist/schemas/providerFailure.js +40 -0
- package/dist/sessionPromptHistory.d.ts +12 -7
- package/dist/sessionPromptHistory.js +15 -3
- package/dist/sessionPromptSignals.d.ts +9 -0
- package/dist/sessionPromptSignals.js +13 -0
- package/dist/testing/credentialGuard.d.ts +23 -0
- package/dist/testing/credentialGuard.js +233 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/sessionLogFixtures.d.ts +28 -0
- package/dist/testing/sessionLogFixtures.js +169 -0
- package/dist/tokenEstimation.d.ts +2 -0
- package/dist/tokenEstimation.js +21 -11
- package/dist/toolCategory.d.ts +18 -0
- package/dist/toolCategory.js +86 -0
- package/dist/types/codex.d.ts +4 -0
- package/dist/usage/usageEvents.d.ts +16 -0
- package/dist/usage/usageEvents.js +53 -9
- package/dist/watchers/jsonlTail.d.ts +26 -1
- package/dist/watchers/jsonlTail.js +136 -28
- package/dist/watchers/jsonlWatcher.js +7 -0
- package/dist/watchers/providerReaderWatcher.js +1 -0
- package/dist/watchers/types.d.ts +6 -0
- package/dist/workspaceRoots.d.ts +23 -0
- package/dist/workspaceRoots.js +93 -0
- package/package.json +22 -2
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized model ID → context window size lookup.
|
|
3
|
+
* Single source of truth used by all providers and the CLI dashboard.
|
|
4
|
+
*
|
|
5
|
+
* Resolution is layered, most-trusted first:
|
|
6
|
+
* 1. Runtime-reported — providers that self-report their window (Codex) apply
|
|
7
|
+
* it in `getContextWindowLimit`, ahead of this module.
|
|
8
|
+
* 2. Observed overrides — the last window a provider actually reported for a
|
|
9
|
+
* model, persisted across runs by `observedContextWindows.ts`. Reflects the
|
|
10
|
+
* effective window for this account/tier, which can be well below the
|
|
11
|
+
* model's published maximum.
|
|
12
|
+
* 3. Imported resolutions — exact entries hydrated from another realm via
|
|
13
|
+
* `importResolvedModelCatalog()`. Below local observed data (a window this
|
|
14
|
+
* realm saw first-hand is fresher than a transferred snapshot), above the
|
|
15
|
+
* catalog.
|
|
16
|
+
* 4. Catalog overrides — `max_input_tokens` from the LiteLLM catalog, hydrated
|
|
17
|
+
* by `pricingCatalog.ts`. Keeps new models correct without a code change.
|
|
18
|
+
* 5. The static table below — offline baseline of last resort.
|
|
19
|
+
*
|
|
20
|
+
* Within that order, match quality comes first: every layer is tried for an
|
|
21
|
+
* exact hit before any layer is tried for a prefix hit. See
|
|
22
|
+
* `getModelContextWindowSize`. The raw (alias) id is tried before its
|
|
23
|
+
* canonical target at every step, so registering an alias never orphans data
|
|
24
|
+
* recorded under the alias itself.
|
|
25
|
+
*
|
|
26
|
+
* Layers 2 and 3 are pushed in by Node-only modules through the `_set*` hooks,
|
|
27
|
+
* so this file stays browser-safe (no node:fs, no fetch) and can be bundled for
|
|
28
|
+
* webviews. Same pattern as `_setPricingOverrides` in `modelInfo.ts`.
|
|
29
|
+
*/
|
|
30
|
+
import { resolveModelAlias } from './modelAliases';
|
|
31
|
+
/** Known model context window sizes (in tokens); current models verified 2026-09-05. */
|
|
32
|
+
const MODEL_CONTEXT_SIZES = {
|
|
33
|
+
// Claude — native 1M context (Fable 5+, Opus 4.6+, Sonnet 4.6+)
|
|
34
|
+
'claude-fable-5-1': 1_000_000,
|
|
35
|
+
'claude-fable-5.1': 1_000_000,
|
|
36
|
+
'claude-fable-5': 1_000_000,
|
|
37
|
+
'claude-opus-5-5': 1_000_000,
|
|
38
|
+
'claude-opus-5.5': 1_000_000,
|
|
39
|
+
'claude-opus-5': 1_000_000,
|
|
40
|
+
'claude-opus-4-8': 1_000_000,
|
|
41
|
+
'claude-opus-4-7': 1_000_000,
|
|
42
|
+
'claude-opus-4-6': 1_000_000,
|
|
43
|
+
'claude-sonnet-5': 1_000_000,
|
|
44
|
+
'claude-sonnet-4-7': 1_000_000,
|
|
45
|
+
'claude-sonnet-4-6': 1_000_000,
|
|
46
|
+
// Claude 4 family
|
|
47
|
+
'claude-opus-4': 200_000,
|
|
48
|
+
'claude-sonnet-4': 200_000,
|
|
49
|
+
// Claude 3.5 family
|
|
50
|
+
'claude-3-5-sonnet': 200_000,
|
|
51
|
+
'claude-3-5-haiku': 200_000,
|
|
52
|
+
// Claude 4.5 / Haiku
|
|
53
|
+
'claude-haiku-4-5': 200_000,
|
|
54
|
+
// Claude 3 family
|
|
55
|
+
'claude-3-opus': 200_000,
|
|
56
|
+
'claude-3-sonnet': 200_000,
|
|
57
|
+
'claude-3-haiku': 200_000,
|
|
58
|
+
// OpenAI GPT-4.1 series (1M context)
|
|
59
|
+
'gpt-4.1': 1_048_576,
|
|
60
|
+
// OpenAI GPT-5/6 series (keys sorted longest-first below; explicit entries
|
|
61
|
+
// for every variant so prefix matching can't misclassify a new one).
|
|
62
|
+
// These are published model maxima. Codex reports a smaller *effective*
|
|
63
|
+
// window per account tier via token_count; that value wins through the
|
|
64
|
+
// observed-override layer.
|
|
65
|
+
'gpt-6-astra': 1_050_000,
|
|
66
|
+
'gpt-6-sol': 1_050_000,
|
|
67
|
+
'gpt-6-luna': 1_050_000,
|
|
68
|
+
'gpt-5.6-sol': 1_050_000,
|
|
69
|
+
'gpt-5.6-terra': 1_050_000,
|
|
70
|
+
'gpt-5.6-luna': 1_050_000,
|
|
71
|
+
'gpt-5.6': 1_050_000,
|
|
72
|
+
'gpt-5.5': 1_050_000,
|
|
73
|
+
'gpt-5.4-mini': 400_000,
|
|
74
|
+
'gpt-5.4-nano': 400_000,
|
|
75
|
+
'gpt-5.4': 1_050_000,
|
|
76
|
+
'gpt-5.3-codex-spark': 128_000,
|
|
77
|
+
'gpt-5.3-codex': 400_000,
|
|
78
|
+
'gpt-5': 400_000,
|
|
79
|
+
// OpenAI reasoning
|
|
80
|
+
o1: 200_000,
|
|
81
|
+
o3: 200_000,
|
|
82
|
+
o4: 200_000,
|
|
83
|
+
// OpenAI GPT-4 series
|
|
84
|
+
'gpt-4o': 128_000,
|
|
85
|
+
'gpt-4-turbo': 128_000,
|
|
86
|
+
'gpt-4': 8_192,
|
|
87
|
+
// Gemini
|
|
88
|
+
gemini: 1_000_000,
|
|
89
|
+
// DeepSeek
|
|
90
|
+
deepseek: 128_000,
|
|
91
|
+
};
|
|
92
|
+
/** Prefix keys sorted longest-first for correct prefix matching. */
|
|
93
|
+
const SORTED_KEYS = sortKeysLongestFirst(MODEL_CONTEXT_SIZES);
|
|
94
|
+
/** Default context window size when model is unknown. */
|
|
95
|
+
export const DEFAULT_CONTEXT_WINDOW = 200_000;
|
|
96
|
+
// ── Override Tables (populated at runtime by Node-only modules) ──
|
|
97
|
+
let observedTable = {};
|
|
98
|
+
let observedSortedKeys = [];
|
|
99
|
+
let catalogTable = {};
|
|
100
|
+
let catalogSortedKeys = [];
|
|
101
|
+
let importedTable = {};
|
|
102
|
+
function sortKeysLongestFirst(table) {
|
|
103
|
+
return Object.keys(table).sort((a, b) => b.length - a.length);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Lowercase keys so lookups match regardless of how the source spelled them.
|
|
107
|
+
* The LiteLLM catalog publishes some IDs mixed-case; the static table and the
|
|
108
|
+
* lookup path are both lowercase. Drops non-positive and non-finite values.
|
|
109
|
+
*/
|
|
110
|
+
function normalizeOverrides(overrides) {
|
|
111
|
+
const out = {};
|
|
112
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
113
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
114
|
+
continue;
|
|
115
|
+
out[key.trim().toLowerCase()] = value;
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Internal: replace the observed-context-window map. Called by
|
|
121
|
+
* `observedContextWindows.ts` on load and on each newly observed value.
|
|
122
|
+
* Not part of the stable public API.
|
|
123
|
+
*/
|
|
124
|
+
export function _setObservedContextWindows(overrides) {
|
|
125
|
+
observedTable = normalizeOverrides(overrides);
|
|
126
|
+
observedSortedKeys = sortKeysLongestFirst(observedTable);
|
|
127
|
+
}
|
|
128
|
+
/** Internal: snapshot observed overrides (test + diagnostics). */
|
|
129
|
+
export function _getObservedContextWindows() {
|
|
130
|
+
return { ...observedTable };
|
|
131
|
+
}
|
|
132
|
+
/** Internal: clear observed overrides (used by tests). */
|
|
133
|
+
export function _clearObservedContextWindows() {
|
|
134
|
+
observedTable = {};
|
|
135
|
+
observedSortedKeys = [];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Internal: replace the catalog-context-window map. Called by
|
|
139
|
+
* `pricingCatalog.ts` after a successful LiteLLM hydration.
|
|
140
|
+
* Not part of the stable public API.
|
|
141
|
+
*/
|
|
142
|
+
export function _setCatalogContextWindows(overrides) {
|
|
143
|
+
catalogTable = normalizeOverrides(overrides);
|
|
144
|
+
catalogSortedKeys = sortKeysLongestFirst(catalogTable);
|
|
145
|
+
}
|
|
146
|
+
/** Internal: snapshot catalog overrides (test + diagnostics). */
|
|
147
|
+
export function _getCatalogContextWindows() {
|
|
148
|
+
return { ...catalogTable };
|
|
149
|
+
}
|
|
150
|
+
/** Internal: clear catalog overrides (used by tests and when disabling hydration). */
|
|
151
|
+
export function _clearCatalogContextWindows() {
|
|
152
|
+
catalogTable = {};
|
|
153
|
+
catalogSortedKeys = [];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Internal: hydrate exact, already-resolved context data from another realm.
|
|
157
|
+
* Merges so successive partial imports accumulate (aliases already merge);
|
|
158
|
+
* use `_clearImportedResolvedContextWindows` to reset.
|
|
159
|
+
*/
|
|
160
|
+
export function _setImportedResolvedContextWindows(values) {
|
|
161
|
+
importedTable = { ...importedTable, ...values };
|
|
162
|
+
}
|
|
163
|
+
/** Internal test hook. */
|
|
164
|
+
export function _clearImportedResolvedContextWindows() {
|
|
165
|
+
importedTable = {};
|
|
166
|
+
}
|
|
167
|
+
/** Internal: list every ID known to the context resolver. */
|
|
168
|
+
export function _getModelContextIds() {
|
|
169
|
+
return Array.from(new Set([
|
|
170
|
+
...Object.keys(MODEL_CONTEXT_SIZES),
|
|
171
|
+
...Object.keys(catalogTable),
|
|
172
|
+
...Object.keys(observedTable),
|
|
173
|
+
...Object.keys(importedTable),
|
|
174
|
+
]));
|
|
175
|
+
}
|
|
176
|
+
// ── Lookup ──
|
|
177
|
+
/** Exact match against one table. */
|
|
178
|
+
function exactWindow(table, modelId) {
|
|
179
|
+
const hit = table[modelId];
|
|
180
|
+
return hit === undefined ? null : hit;
|
|
181
|
+
}
|
|
182
|
+
function exactWindowMatch(table, modelId) {
|
|
183
|
+
const exact = exactWindow(table, modelId);
|
|
184
|
+
return exact === null ? null : { value: exact, match: 'exact', matchedModelId: modelId };
|
|
185
|
+
}
|
|
186
|
+
function prefixWindowMatch(table, sortedKeys, modelId) {
|
|
187
|
+
for (const key of sortedKeys) {
|
|
188
|
+
if (modelId !== key && modelId.startsWith(key)) {
|
|
189
|
+
return { value: table[key], match: 'prefix', matchedModelId: key };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
/** Resolve published, observed, and tier-effective context windows with provenance. */
|
|
195
|
+
export function resolveModelContextWindow(modelId) {
|
|
196
|
+
const rawModelId = modelId ?? '';
|
|
197
|
+
const stripped = rawModelId
|
|
198
|
+
.replace(/\[1m\]/gi, '')
|
|
199
|
+
.trim()
|
|
200
|
+
.toLowerCase();
|
|
201
|
+
const canonicalModelId = resolveModelAlias(stripped);
|
|
202
|
+
if (/\[1m\]/i.test(rawModelId) || /\[1m\]/i.test(canonicalModelId)) {
|
|
203
|
+
return {
|
|
204
|
+
modelId: rawModelId,
|
|
205
|
+
canonicalModelId: canonicalModelId.replace(/\[1m\]/gi, ''),
|
|
206
|
+
published: 1_000_000,
|
|
207
|
+
observed: null,
|
|
208
|
+
tierEffective: 1_000_000,
|
|
209
|
+
provenance: { source: 'explicit-1m', match: 'exact', matchedModelId: canonicalModelId },
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// The raw id is tried before its alias target at every step: data recorded
|
|
213
|
+
// for the alias id itself is more specific than the canonical fallback.
|
|
214
|
+
const candidateIds = stripped === canonicalModelId ? [canonicalModelId] : [stripped, canonicalModelId];
|
|
215
|
+
const firstMatch = (lookup) => {
|
|
216
|
+
for (const id of candidateIds) {
|
|
217
|
+
const hit = lookup(id);
|
|
218
|
+
if (hit)
|
|
219
|
+
return hit;
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
};
|
|
223
|
+
const observedExact = firstMatch((id) => exactWindowMatch(observedTable, id));
|
|
224
|
+
// Imported resolutions rank below local observed data: a window this realm
|
|
225
|
+
// saw first-hand is fresher than a snapshot transferred from another realm.
|
|
226
|
+
if (!observedExact) {
|
|
227
|
+
const imported = importedTable[stripped] ?? importedTable[canonicalModelId];
|
|
228
|
+
if (imported) {
|
|
229
|
+
return { ...imported, modelId: rawModelId, canonicalModelId };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const catalogExact = firstMatch((id) => exactWindowMatch(catalogTable, id));
|
|
233
|
+
const staticExact = firstMatch((id) => exactWindowMatch(MODEL_CONTEXT_SIZES, id));
|
|
234
|
+
const observedPrefix = firstMatch((id) => prefixWindowMatch(observedTable, observedSortedKeys, id));
|
|
235
|
+
const catalogPrefix = firstMatch((id) => prefixWindowMatch(catalogTable, catalogSortedKeys, id));
|
|
236
|
+
const staticPrefix = firstMatch((id) => prefixWindowMatch(MODEL_CONTEXT_SIZES, SORTED_KEYS, id));
|
|
237
|
+
const published = catalogExact ?? staticExact ?? catalogPrefix ?? staticPrefix;
|
|
238
|
+
const effective = observedExact ?? catalogExact ?? staticExact ?? observedPrefix ?? catalogPrefix ?? staticPrefix;
|
|
239
|
+
return {
|
|
240
|
+
modelId: rawModelId,
|
|
241
|
+
canonicalModelId,
|
|
242
|
+
published: published?.value ?? null,
|
|
243
|
+
observed: (observedExact ?? observedPrefix)?.value ?? null,
|
|
244
|
+
tierEffective: effective?.value ?? DEFAULT_CONTEXT_WINDOW,
|
|
245
|
+
provenance: effective
|
|
246
|
+
? {
|
|
247
|
+
source: effective === observedExact || effective === observedPrefix
|
|
248
|
+
? 'observed'
|
|
249
|
+
: effective === catalogExact || effective === catalogPrefix
|
|
250
|
+
? 'catalog'
|
|
251
|
+
: 'static',
|
|
252
|
+
match: effective.match,
|
|
253
|
+
matchedModelId: effective.matchedModelId,
|
|
254
|
+
}
|
|
255
|
+
: { source: 'default', match: 'default' },
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Returns the context window size for a model ID.
|
|
260
|
+
*
|
|
261
|
+
* Input is trimmed and lowercased before lookup, so padded or mixed-case
|
|
262
|
+
* IDs (e.g. "Claude-Opus-5 ") resolve without caller-side normalization.
|
|
263
|
+
*
|
|
264
|
+
* Lookup order:
|
|
265
|
+
* 1. Explicit "[1m]" suffix (Claude Code's 1M-variant marker) → 1_000_000
|
|
266
|
+
* 2. Exact match, most-trusted layer first: observed → catalog → static
|
|
267
|
+
* 3. Longest-prefix match, same layer order
|
|
268
|
+
* (e.g. "claude-opus-4-6-20250414" → "claude-opus-4-6")
|
|
269
|
+
* 4. DEFAULT_CONTEXT_WINDOW
|
|
270
|
+
*
|
|
271
|
+
* Match quality outranks layer trust: an exact hit in *any* layer beats a
|
|
272
|
+
* prefix guess in *every* layer. Resolving each layer fully before moving on
|
|
273
|
+
* would let a catalog key that merely happens to be a prefix shadow a curated
|
|
274
|
+
* static entry — e.g. the catalog has no "claude-sonnet-4-7", and prefix-first
|
|
275
|
+
* would hand it "claude-sonnet-4" (128K, a GitHub Copilot deployment) instead
|
|
276
|
+
* of the static table's exact 1M.
|
|
277
|
+
*/
|
|
278
|
+
export function getModelContextWindowSize(modelId) {
|
|
279
|
+
return resolveModelContextWindow(modelId).tierEffective;
|
|
280
|
+
}
|