sidekick-shared 0.28.2 → 0.29.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 +83 -0
- package/README.md +176 -30
- package/dist/authStatus.d.ts +54 -0
- package/dist/authStatus.js +91 -0
- package/dist/browser.d.ts +14 -6
- package/dist/browser.js +26 -1
- package/dist/codex.d.ts +23 -0
- package/dist/codex.js +44 -0
- package/dist/codexProfiles.d.ts +1 -0
- package/dist/codexProfiles.js +8 -11
- package/dist/codexQuota.js +17 -4
- package/dist/esm/authStatus.js +87 -0
- package/dist/esm/browser.js +6 -2
- package/dist/esm/codex.js +18 -0
- package/dist/esm/codexProfiles.js +8 -11
- package/dist/esm/codexQuota.js +18 -5
- package/dist/esm/formatting.js +10 -1
- package/dist/esm/index.js +12 -9
- package/dist/esm/modelCatalog.js +2 -1
- package/dist/esm/modelInfo.js +422 -45
- package/dist/esm/multiProviderQuotaService.js +1 -1
- package/dist/esm/node.js +9 -3
- package/dist/esm/parsers/codexParser.js +175 -54
- package/dist/esm/parsers/codexRolloutOrigin.js +107 -0
- package/dist/esm/parsers/openCodeParser.js +83 -21
- package/dist/esm/pricing.js +18 -0
- package/dist/esm/pricingCatalog.js +14 -7
- package/dist/esm/promptHistory.js +66 -4
- package/dist/esm/providerFailure.js +124 -3
- package/dist/esm/providers/codex.js +2 -24
- package/dist/esm/providers/codexDatabase.js +3 -19
- package/dist/esm/providers/codexRollouts.js +24 -1
- package/dist/esm/providers/openCode.js +9 -17
- package/dist/esm/quota.js +356 -24
- package/dist/esm/quotaHistory.js +33 -8
- package/dist/esm/quotaPoller.js +5 -2
- package/dist/esm/quotaResolver.js +31 -6
- package/dist/esm/quotaSnapshots.js +65 -10
- package/dist/esm/quotaThresholds.js +7 -2
- package/dist/esm/report/htmlReportGenerator.js +42 -5
- package/dist/esm/report/transcriptParser.js +13 -11
- package/dist/esm/schemas/index.js +2 -2
- package/dist/esm/schemas/providerFailure.js +3 -1
- package/dist/esm/schemas/quota.js +30 -0
- package/dist/esm/schemas/quotaHistory.js +10 -2
- package/dist/esm/schemas/stateFile.js +9 -0
- package/dist/esm/schemas/transcript.js +4 -0
- package/dist/esm/sessionPromptHistory.js +2 -2
- package/dist/esm/stateFile.js +18 -3
- package/dist/esm/statusline/claudeStatuslinePayload.js +16 -4
- package/dist/esm/statusline/formatter.js +57 -18
- package/dist/esm/statusline/index.js +2 -2
- package/dist/esm/statusline/payload.js +9 -0
- package/dist/esm/testing/credentialGuard.js +87 -5
- package/dist/esm/toolCallOrigins.js +310 -0
- package/dist/esm/transcript.js +42 -3
- package/dist/esm/usage/usageEvents.js +146 -17
- package/dist/esm/usage/usageReports.js +39 -6
- package/dist/esm/watchers/jsonlTail.js +378 -59
- package/dist/esm/zaiQuotaApi.js +4 -2
- package/dist/formatting.d.ts +26 -1
- package/dist/formatting.js +11 -1
- package/dist/index.d.ts +22 -16
- package/dist/index.js +48 -12
- package/dist/modelCatalog.js +2 -1
- package/dist/modelInfo.d.ts +185 -16
- package/dist/modelInfo.js +431 -47
- package/dist/multiProviderQuotaService.js +1 -1
- package/dist/node.d.ts +16 -5
- package/dist/node.js +31 -2
- package/dist/parsers/codexParser.d.ts +55 -0
- package/dist/parsers/codexParser.js +175 -54
- package/dist/parsers/codexRolloutOrigin.d.ts +49 -0
- package/dist/parsers/codexRolloutOrigin.js +111 -0
- package/dist/parsers/openCodeParser.d.ts +38 -0
- package/dist/parsers/openCodeParser.js +86 -21
- package/dist/pricing.d.ts +22 -0
- package/dist/pricing.js +50 -0
- package/dist/pricingCatalog.d.ts +10 -0
- package/dist/pricingCatalog.js +13 -6
- package/dist/promptHistory.d.ts +65 -4
- package/dist/promptHistory.js +68 -5
- package/dist/providerFailure.d.ts +44 -0
- package/dist/providerFailure.js +126 -4
- package/dist/providers/codex.d.ts +3 -22
- package/dist/providers/codex.js +3 -26
- package/dist/providers/codexDatabase.d.ts +3 -2
- package/dist/providers/codexDatabase.js +4 -22
- package/dist/providers/codexRollouts.d.ts +22 -0
- package/dist/providers/codexRollouts.js +24 -0
- package/dist/providers/openCode.js +8 -16
- package/dist/quota.d.ts +131 -1
- package/dist/quota.js +366 -24
- package/dist/quotaHistory.d.ts +10 -0
- package/dist/quotaHistory.js +34 -8
- package/dist/quotaPoller.d.ts +11 -3
- package/dist/quotaPoller.js +5 -2
- package/dist/quotaResolver.js +30 -5
- package/dist/quotaSnapshots.js +64 -9
- package/dist/quotaThresholds.js +7 -2
- package/dist/report/htmlReportGenerator.js +42 -5
- package/dist/report/transcriptParser.d.ts +10 -1
- package/dist/report/transcriptParser.js +13 -11
- package/dist/schemas/index.d.ts +3 -3
- package/dist/schemas/index.js +5 -2
- package/dist/schemas/providerFailure.d.ts +39 -0
- package/dist/schemas/providerFailure.js +2 -0
- package/dist/schemas/quota.d.ts +258 -0
- package/dist/schemas/quota.js +31 -1
- package/dist/schemas/quotaHistory.d.ts +2 -0
- package/dist/schemas/quotaHistory.js +10 -2
- package/dist/schemas/stateFile.d.ts +34 -0
- package/dist/schemas/stateFile.js +10 -1
- package/dist/schemas/transcript.d.ts +2 -0
- package/dist/schemas/transcript.js +4 -0
- package/dist/sessionPromptHistory.d.ts +7 -1
- package/dist/sessionPromptHistory.js +1 -1
- package/dist/stateFile.d.ts +18 -0
- package/dist/stateFile.js +17 -2
- package/dist/statusline/claudeStatuslinePayload.d.ts +4 -3
- package/dist/statusline/claudeStatuslinePayload.js +16 -4
- package/dist/statusline/formatter.d.ts +5 -0
- package/dist/statusline/formatter.js +56 -17
- package/dist/statusline/index.d.ts +4 -4
- package/dist/statusline/index.js +5 -1
- package/dist/statusline/payload.d.ts +10 -0
- package/dist/statusline/payload.js +14 -0
- package/dist/testing/credentialGuard.d.ts +14 -0
- package/dist/testing/credentialGuard.js +87 -5
- package/dist/toolCallOrigins.d.ts +70 -0
- package/dist/toolCallOrigins.js +346 -0
- package/dist/transcript.d.ts +12 -0
- package/dist/transcript.js +42 -3
- package/dist/types/opencode.d.ts +2 -0
- package/dist/usage/usageEvents.d.ts +54 -6
- package/dist/usage/usageEvents.js +146 -17
- package/dist/usage/usageReports.d.ts +35 -4
- package/dist/usage/usageReports.js +39 -6
- package/dist/watchers/jsonlTail.d.ts +101 -4
- package/dist/watchers/jsonlTail.js +380 -60
- package/dist/zaiQuotaApi.js +3 -1
- package/package.json +41 -1
package/dist/esm/modelInfo.js
CHANGED
|
@@ -14,12 +14,17 @@
|
|
|
14
14
|
* baseline without requiring a redeploy when vendor prices change.
|
|
15
15
|
* - Longest-prefix matching handles variants like `claude-opus-4.5-20250514`
|
|
16
16
|
* against a key like `claude-opus-4.5`. Same pattern used in modelContext.ts.
|
|
17
|
+
* - A consumer layer (`registerModelPricing`) sits beside the catalog and
|
|
18
|
+
* imported layers and survives their resets.
|
|
19
|
+
* - Every table-derived value is computed lazily, so a tree-shaken bundle that
|
|
20
|
+
* only uses the parsing/display helpers does not retain the pricing table.
|
|
17
21
|
*
|
|
18
22
|
* @module modelInfo
|
|
19
23
|
*/
|
|
20
24
|
import { getModelContextWindowSize } from './modelContext';
|
|
21
25
|
import { resolveModelAlias } from './modelAliases';
|
|
22
26
|
export { MODEL_PROVIDER_IDS } from './providerIds';
|
|
27
|
+
export { formatCost } from './formatting';
|
|
23
28
|
// ── Static Pricing Table ──
|
|
24
29
|
/**
|
|
25
30
|
* Static baseline pricing. Keys are model-ID prefixes; lookup uses
|
|
@@ -621,21 +626,38 @@ const PRICING_TABLE = {
|
|
|
621
626
|
cacheReadCostPerMillion: 7.5,
|
|
622
627
|
},
|
|
623
628
|
};
|
|
624
|
-
/**
|
|
625
|
-
|
|
629
|
+
/**
|
|
630
|
+
* Static-table keys sorted longest-first so longest-prefix wins. Computed on
|
|
631
|
+
* first lookup rather than at module load: a top-level call would keep the
|
|
632
|
+
* whole table alive in tree-shaken bundles that never price anything.
|
|
633
|
+
*/
|
|
634
|
+
let staticSortedKeys = null;
|
|
635
|
+
function getStaticSortedKeys() {
|
|
636
|
+
if (!staticSortedKeys) {
|
|
637
|
+
staticSortedKeys = Object.keys(PRICING_TABLE).sort((a, b) => b.length - a.length);
|
|
638
|
+
}
|
|
639
|
+
return staticSortedKeys;
|
|
640
|
+
}
|
|
626
641
|
// ── Override Table (populated at runtime by pricingCatalog) ──
|
|
627
642
|
let overrideTable = {};
|
|
628
643
|
let overrideSortedKeys = [];
|
|
644
|
+
let overrideBasis = null;
|
|
629
645
|
let importedTable = {};
|
|
630
646
|
/**
|
|
631
647
|
* Internal: replace the runtime override map. Called by `pricingCatalog.ts`
|
|
632
648
|
* after a successful LiteLLM hydration. Not part of the stable public API,
|
|
633
649
|
* but exported so the Node-only catalog module can wire itself in without
|
|
634
650
|
* creating a circular import.
|
|
651
|
+
*
|
|
652
|
+
* `basis` records how the map was obtained for `getPricingCatalogInfo()`;
|
|
653
|
+
* omitted, a non-empty map reports as `litellm` with no `fetchedAt`. Every
|
|
654
|
+
* call replaces the previous basis.
|
|
635
655
|
*/
|
|
636
|
-
export function _setPricingOverrides(overrides) {
|
|
656
|
+
export function _setPricingOverrides(overrides, basis) {
|
|
637
657
|
overrideTable = Object.fromEntries(Object.entries(overrides).map(([key, value]) => [key.trim().toLowerCase(), { ...value }]));
|
|
638
658
|
overrideSortedKeys = Object.keys(overrideTable).sort((a, b) => b.length - a.length);
|
|
659
|
+
overrideBasis = basis ? { ...basis } : null;
|
|
660
|
+
invalidatePricingDigest();
|
|
639
661
|
}
|
|
640
662
|
/** Internal: snapshot current overrides (test + diagnostics). */
|
|
641
663
|
export function _getPricingOverrides() {
|
|
@@ -645,6 +667,8 @@ export function _getPricingOverrides() {
|
|
|
645
667
|
export function _clearPricingOverrides() {
|
|
646
668
|
overrideTable = {};
|
|
647
669
|
overrideSortedKeys = [];
|
|
670
|
+
overrideBasis = null;
|
|
671
|
+
invalidatePricingDigest();
|
|
648
672
|
}
|
|
649
673
|
/**
|
|
650
674
|
* Internal: hydrate exact pricing resolutions exported by another realm.
|
|
@@ -653,10 +677,210 @@ export function _clearPricingOverrides() {
|
|
|
653
677
|
*/
|
|
654
678
|
export function _setImportedResolvedPricing(values) {
|
|
655
679
|
importedTable = { ...importedTable, ...values };
|
|
680
|
+
invalidatePricingDigest();
|
|
656
681
|
}
|
|
657
682
|
/** Internal test hook. */
|
|
658
683
|
export function _clearImportedResolvedPricing() {
|
|
659
684
|
importedTable = {};
|
|
685
|
+
invalidatePricingDigest();
|
|
686
|
+
}
|
|
687
|
+
// A Map (created on first registration) so keys such as `__proto__` stay data.
|
|
688
|
+
let registeredTable = null;
|
|
689
|
+
function isValidModelPricing(value) {
|
|
690
|
+
if (!value || typeof value !== 'object')
|
|
691
|
+
return false;
|
|
692
|
+
const pricing = value;
|
|
693
|
+
return [
|
|
694
|
+
pricing.inputCostPerMillion,
|
|
695
|
+
pricing.outputCostPerMillion,
|
|
696
|
+
pricing.cacheWriteCostPerMillion,
|
|
697
|
+
pricing.cacheReadCostPerMillion,
|
|
698
|
+
].every((item) => typeof item === 'number' && Number.isFinite(item) && item >= 0);
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Register consumer pricing for model ids, e.g. negotiated or private-deployment
|
|
702
|
+
* rates. This layer is separate from the runtime catalog and imported layers:
|
|
703
|
+
* `_setPricingOverrides`, `hydratePricingCatalog`, and
|
|
704
|
+
* `importResolvedModelCatalog` never reset it; only
|
|
705
|
+
* `clearRegisteredModelPricing` does.
|
|
706
|
+
*
|
|
707
|
+
* Keys are trimmed, lowercased, and stripped of `[1m]`, like the other tables.
|
|
708
|
+
* Matching is exact, never by prefix, against the looked-up id, its registered
|
|
709
|
+
* alias target, and its `canonicalModelId()` form — so a `claude-opus-5-5`
|
|
710
|
+
* entry also answers `claude-opus-5-5-20261001` and
|
|
711
|
+
* `us.anthropic.claude-opus-5-5-20261001-v1:0`.
|
|
712
|
+
*
|
|
713
|
+
* Successive calls merge; re-registering a key replaces its price and mode.
|
|
714
|
+
* Entries whose four rates are not all finite, nonnegative numbers are
|
|
715
|
+
* skipped. Results carry `provenance.source: 'registered'`.
|
|
716
|
+
*
|
|
717
|
+
* Registered entries are realm-local configuration and are kept out of
|
|
718
|
+
* cross-realm snapshots: they are not listed by the catalog id enumeration,
|
|
719
|
+
* and `resolveModelPricing(id, { includeRegistered: false })` is the
|
|
720
|
+
* resolution a snapshot should carry. An exported price would otherwise be
|
|
721
|
+
* pinned as an exact import in the other realm and outlive
|
|
722
|
+
* `clearRegisteredModelPricing` there. Register in each realm instead.
|
|
723
|
+
*/
|
|
724
|
+
export function registerModelPricing(entries, options) {
|
|
725
|
+
const onlyIfMissing = options?.onlyIfMissing === true;
|
|
726
|
+
let changed = false;
|
|
727
|
+
for (const [key, value] of Object.entries(entries ?? {})) {
|
|
728
|
+
const id = key
|
|
729
|
+
.replace(/\[1m\]/gi, '')
|
|
730
|
+
.trim()
|
|
731
|
+
.toLowerCase();
|
|
732
|
+
if (!id || !isValidModelPricing(value))
|
|
733
|
+
continue;
|
|
734
|
+
registeredTable ??= new Map();
|
|
735
|
+
registeredTable.set(id, {
|
|
736
|
+
pricing: {
|
|
737
|
+
inputCostPerMillion: value.inputCostPerMillion,
|
|
738
|
+
outputCostPerMillion: value.outputCostPerMillion,
|
|
739
|
+
cacheWriteCostPerMillion: value.cacheWriteCostPerMillion,
|
|
740
|
+
cacheReadCostPerMillion: value.cacheReadCostPerMillion,
|
|
741
|
+
},
|
|
742
|
+
onlyIfMissing,
|
|
743
|
+
});
|
|
744
|
+
changed = true;
|
|
745
|
+
}
|
|
746
|
+
if (changed)
|
|
747
|
+
invalidatePricingDigest();
|
|
748
|
+
}
|
|
749
|
+
/** Remove every entry added by `registerModelPricing`. */
|
|
750
|
+
export function clearRegisteredModelPricing() {
|
|
751
|
+
if (registeredTable && registeredTable.size > 0)
|
|
752
|
+
invalidatePricingDigest();
|
|
753
|
+
registeredTable = null;
|
|
754
|
+
}
|
|
755
|
+
function findRegisteredPricing(rawId, aliasId) {
|
|
756
|
+
if (!registeredTable || registeredTable.size === 0)
|
|
757
|
+
return null;
|
|
758
|
+
const canonical = canonicalModelId(rawId);
|
|
759
|
+
for (const id of [rawId, aliasId, canonical, resolveModelAlias(canonical)]) {
|
|
760
|
+
const entry = registeredTable.get(id);
|
|
761
|
+
if (entry)
|
|
762
|
+
return { id, entry };
|
|
763
|
+
}
|
|
764
|
+
return null;
|
|
765
|
+
}
|
|
766
|
+
// ── Pricing Basis ──
|
|
767
|
+
let pricingDigestMemo = null;
|
|
768
|
+
function invalidatePricingDigest() {
|
|
769
|
+
pricingDigestMemo = null;
|
|
770
|
+
}
|
|
771
|
+
/** JSON with object keys sorted at every level; `undefined` members are dropped. */
|
|
772
|
+
function canonicalJson(value) {
|
|
773
|
+
if (value === null || typeof value !== 'object') {
|
|
774
|
+
return JSON.stringify(value) ?? 'null';
|
|
775
|
+
}
|
|
776
|
+
if (Array.isArray(value))
|
|
777
|
+
return `[${value.map(canonicalJson).join(',')}]`;
|
|
778
|
+
const record = value;
|
|
779
|
+
const keys = Object.keys(record)
|
|
780
|
+
.filter((key) => record[key] !== undefined)
|
|
781
|
+
.sort();
|
|
782
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(',')}}`;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* 64-bit FNV-1a over the UTF-8 bytes of `text`, as 16 lowercase hex digits.
|
|
786
|
+
* Uses four 16-bit limbs so it runs on plain numbers in every JS runtime.
|
|
787
|
+
*/
|
|
788
|
+
function fnv1a64Hex(text) {
|
|
789
|
+
// Offset basis 0xcbf29ce484222325, least significant limb first.
|
|
790
|
+
let h0 = 0x2325;
|
|
791
|
+
let h1 = 0x8422;
|
|
792
|
+
let h2 = 0x9ce4;
|
|
793
|
+
let h3 = 0xcbf2;
|
|
794
|
+
const mix = (byte) => {
|
|
795
|
+
h0 ^= byte;
|
|
796
|
+
// Multiply by the FNV prime 0x100000001b3 = 2^40 + 0x1b3, mod 2^64.
|
|
797
|
+
const t0 = h0 * 0x1b3;
|
|
798
|
+
const t1 = h1 * 0x1b3 + (t0 >>> 16);
|
|
799
|
+
const t2 = h2 * 0x1b3 + (h0 << 8) + (t1 >>> 16);
|
|
800
|
+
const t3 = h3 * 0x1b3 + (h1 << 8) + (t2 >>> 16);
|
|
801
|
+
h0 = t0 & 0xffff;
|
|
802
|
+
h1 = t1 & 0xffff;
|
|
803
|
+
h2 = t2 & 0xffff;
|
|
804
|
+
h3 = t3 & 0xffff;
|
|
805
|
+
};
|
|
806
|
+
for (let i = 0; i < text.length; i++) {
|
|
807
|
+
let code = text.charCodeAt(i);
|
|
808
|
+
if (code >= 0xd800 && code <= 0xdfff) {
|
|
809
|
+
const low = code <= 0xdbff && i + 1 < text.length ? text.charCodeAt(i + 1) : 0;
|
|
810
|
+
if (low >= 0xdc00 && low <= 0xdfff) {
|
|
811
|
+
code = 0x10000 + ((code - 0xd800) << 10) + (low - 0xdc00);
|
|
812
|
+
i++;
|
|
813
|
+
}
|
|
814
|
+
else {
|
|
815
|
+
// A lone surrogate encodes as U+FFFD, as TextEncoder does.
|
|
816
|
+
code = 0xfffd;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (code < 0x80) {
|
|
820
|
+
mix(code);
|
|
821
|
+
}
|
|
822
|
+
else if (code < 0x800) {
|
|
823
|
+
mix(0xc0 | (code >> 6));
|
|
824
|
+
mix(0x80 | (code & 0x3f));
|
|
825
|
+
}
|
|
826
|
+
else if (code < 0x10000) {
|
|
827
|
+
mix(0xe0 | (code >> 12));
|
|
828
|
+
mix(0x80 | ((code >> 6) & 0x3f));
|
|
829
|
+
mix(0x80 | (code & 0x3f));
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
mix(0xf0 | (code >> 18));
|
|
833
|
+
mix(0x80 | ((code >> 12) & 0x3f));
|
|
834
|
+
mix(0x80 | ((code >> 6) & 0x3f));
|
|
835
|
+
mix(0x80 | (code & 0x3f));
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return [h3, h2, h1, h0].map((limb) => limb.toString(16).padStart(4, '0')).join('');
|
|
839
|
+
}
|
|
840
|
+
function getPricingDigest() {
|
|
841
|
+
if (pricingDigestMemo === null) {
|
|
842
|
+
const imported = {};
|
|
843
|
+
for (const [id, entry] of Object.entries(importedTable)) {
|
|
844
|
+
imported[id] = { pricing: entry.pricing, provenance: entry.provenance };
|
|
845
|
+
}
|
|
846
|
+
const registered = {};
|
|
847
|
+
for (const [id, entry] of registeredTable ?? []) {
|
|
848
|
+
registered[id] = { pricing: entry.pricing, onlyIfMissing: entry.onlyIfMissing };
|
|
849
|
+
}
|
|
850
|
+
const payload = canonicalJson({
|
|
851
|
+
v: 1,
|
|
852
|
+
static: PRICING_TABLE,
|
|
853
|
+
catalog: overrideTable,
|
|
854
|
+
imported,
|
|
855
|
+
registered,
|
|
856
|
+
});
|
|
857
|
+
pricingDigestMemo = `fnv1a64:${fnv1a64Hex(payload)}`;
|
|
858
|
+
}
|
|
859
|
+
return pricingDigestMemo;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Describe the pricing basis behind current cost estimates: which layer the
|
|
863
|
+
* prices come from, when the catalog was fetched, and a digest that changes
|
|
864
|
+
* whenever any active price changes. Pure and cheap after the first call (the
|
|
865
|
+
* digest is memoized until a table changes).
|
|
866
|
+
*/
|
|
867
|
+
export function getPricingCatalogInfo() {
|
|
868
|
+
const catalogEntries = overrideSortedKeys.length;
|
|
869
|
+
let source = 'static';
|
|
870
|
+
if (catalogEntries > 0) {
|
|
871
|
+
source = overrideBasis?.source ?? 'litellm';
|
|
872
|
+
}
|
|
873
|
+
else if (Object.keys(importedTable).length > 0) {
|
|
874
|
+
source = 'imported';
|
|
875
|
+
}
|
|
876
|
+
const fetchedAt = catalogEntries > 0 ? overrideBasis?.fetchedAt : undefined;
|
|
877
|
+
return {
|
|
878
|
+
source,
|
|
879
|
+
...(fetchedAt ? { fetchedAt } : {}),
|
|
880
|
+
digest: getPricingDigest(),
|
|
881
|
+
catalogEntries,
|
|
882
|
+
registeredEntries: registeredTable?.size ?? 0,
|
|
883
|
+
};
|
|
660
884
|
}
|
|
661
885
|
/** Internal: list every ID known to the pricing resolver. */
|
|
662
886
|
export function _getModelPricingIds() {
|
|
@@ -666,6 +890,86 @@ export function _getModelPricingIds() {
|
|
|
666
890
|
...Object.keys(importedTable),
|
|
667
891
|
]));
|
|
668
892
|
}
|
|
893
|
+
// ── Model ID Canonicalization ──
|
|
894
|
+
// Bedrock: optional cross-region prefix (`us.`, `eu.`, `apac.`, `global.`, …)
|
|
895
|
+
// then the vendor segment, e.g. `us.anthropic.claude-opus-5-5-20261001-v1:0`.
|
|
896
|
+
const BEDROCK_ANTHROPIC_RE = /^(?:[a-z]{2,6}(?:-[a-z]{2,4})?\.)?anthropic\./;
|
|
897
|
+
// Bedrock revision tag (`-v1:0`, `-v1`), only after a version or date digit so
|
|
898
|
+
// legacy names such as `claude-v2:1` and `claude-instant-v1` keep theirs.
|
|
899
|
+
const BEDROCK_REVISION_RE = /([0-9])-v[0-9]+(?::[0-9]+)?$/;
|
|
900
|
+
const VERTEX_VERSION_RE = /@(?:[0-9]{8}|latest)$/;
|
|
901
|
+
const LATEST_SUFFIX_RE = /-latest$/;
|
|
902
|
+
const DASHED_DATE_SUFFIX_RE = /-[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
903
|
+
const COMPACT_DATE_SUFFIX_RE = /-[0-9]{8}$/;
|
|
904
|
+
/**
|
|
905
|
+
* Reduce a model id to the bare model name it denotes, for grouping and
|
|
906
|
+
* matching across hosts and snapshots.
|
|
907
|
+
*
|
|
908
|
+
* Trims and lowercases, then removes: `[1m]`; every leading `segment/`
|
|
909
|
+
* provider or region prefix (`azure/us/gpt-6.1-terra` → `gpt-6.1-terra`);
|
|
910
|
+
* Bedrock forms (`us.anthropic.claude-opus-5-5-20261001-v1:0` →
|
|
911
|
+
* `claude-opus-5-5`, also `eu.`/`apac.`/`global.` and bare `anthropic.`);
|
|
912
|
+
* Vertex `@YYYYMMDD`; trailing `-YYYYMMDD` and `-YYYY-MM-DD` dates; `-latest`.
|
|
913
|
+
* Meaningful suffixes (`-mini`, `-codex`, `-sol`, `-terra`, `-high`, …) stay.
|
|
914
|
+
*
|
|
915
|
+
* Pure and syntactic: registered aliases are not applied (see
|
|
916
|
+
* `resolveModelAlias`). Pricing lookups do not use this to reach other
|
|
917
|
+
* models' prices — dated snapshots and deployments can bill differently — only
|
|
918
|
+
* to match `registerModelPricing` entries.
|
|
919
|
+
*/
|
|
920
|
+
export function canonicalModelId(id) {
|
|
921
|
+
let value = String(id ?? '')
|
|
922
|
+
.trim()
|
|
923
|
+
.toLowerCase()
|
|
924
|
+
.replace(/\[1m\]/g, '')
|
|
925
|
+
.trim();
|
|
926
|
+
const slash = value.lastIndexOf('/');
|
|
927
|
+
if (slash >= 0 && slash < value.length - 1)
|
|
928
|
+
value = value.slice(slash + 1);
|
|
929
|
+
const bedrock = BEDROCK_ANTHROPIC_RE.exec(value);
|
|
930
|
+
if (bedrock && value.length > bedrock[0].length) {
|
|
931
|
+
value = value.slice(bedrock[0].length).replace(BEDROCK_REVISION_RE, '$1');
|
|
932
|
+
}
|
|
933
|
+
// Suffixes can stack (`-20250101-latest`), so strip until nothing changes.
|
|
934
|
+
for (;;) {
|
|
935
|
+
const next = value
|
|
936
|
+
.replace(VERTEX_VERSION_RE, '')
|
|
937
|
+
.replace(LATEST_SUFFIX_RE, '')
|
|
938
|
+
.replace(DASHED_DATE_SUFFIX_RE, '')
|
|
939
|
+
.replace(COMPACT_DATE_SUFFIX_RE, '');
|
|
940
|
+
if (next === value || !next)
|
|
941
|
+
break;
|
|
942
|
+
value = next;
|
|
943
|
+
}
|
|
944
|
+
return value;
|
|
945
|
+
}
|
|
946
|
+
// Names an agent CLI re-points at a different concrete model over time.
|
|
947
|
+
// An object literal rather than a Set keeps it free for tree-shaking.
|
|
948
|
+
const MOVING_MODEL_ALIASES = {
|
|
949
|
+
default: true,
|
|
950
|
+
auto: true,
|
|
951
|
+
latest: true,
|
|
952
|
+
sonnet: true,
|
|
953
|
+
opus: true,
|
|
954
|
+
haiku: true,
|
|
955
|
+
fable: true,
|
|
956
|
+
opusplan: true,
|
|
957
|
+
};
|
|
958
|
+
/**
|
|
959
|
+
* True for model names an agent CLI resolves to a different concrete model
|
|
960
|
+
* over time (`default`, `auto`, `latest`, `sonnet`, `opus`, `haiku`, `fable`,
|
|
961
|
+
* and Claude Code's `opusplan`), so a recorded value names a moving target
|
|
962
|
+
* rather than a model. Case-insensitive, trimmed, and `[1m]`-tolerant
|
|
963
|
+
* (`sonnet[1m]`). Dated or versioned ids are never moving aliases.
|
|
964
|
+
*/
|
|
965
|
+
export function isMovingModelAlias(id) {
|
|
966
|
+
const value = String(id ?? '')
|
|
967
|
+
.trim()
|
|
968
|
+
.toLowerCase()
|
|
969
|
+
.replace(/\[1m\]/g, '')
|
|
970
|
+
.trim();
|
|
971
|
+
return Object.prototype.hasOwnProperty.call(MOVING_MODEL_ALIASES, value);
|
|
972
|
+
}
|
|
669
973
|
// ── Model ID Parsing ──
|
|
670
974
|
// Anthropic writes the minor version with a hyphen in modern IDs
|
|
671
975
|
// (`claude-sonnet-4-6-20260321`) and a dot in older ones
|
|
@@ -677,6 +981,14 @@ const LEGACY_CLAUDE_RE = /^claude-([0-9]+(?:[-.][0-9]+)?)-(haiku|sonnet|opus)(?:
|
|
|
677
981
|
const GPT_RE = /^gpt-([0-9][0-9.A-Za-z-]*)/i;
|
|
678
982
|
const O_SERIES_RE = /^o([0-9]+)(-mini|-pro)?/i;
|
|
679
983
|
const GEMINI_RE = /^gemini-([0-9][0-9.A-Za-z-]*)/i;
|
|
984
|
+
// GPT tier names, read from the parsed version (`6.1-sol`, `6-luna-2026-01-01`).
|
|
985
|
+
const GPT_TIER_VARIANT_RE = /^[0-9]+(?:\.[0-9]+)*-(astra|sol|terra|luna)(?=-|$)/;
|
|
986
|
+
const GPT_TIER_VARIANT_RANK = {
|
|
987
|
+
astra: 0,
|
|
988
|
+
sol: 1,
|
|
989
|
+
terra: 2,
|
|
990
|
+
luna: 3,
|
|
991
|
+
};
|
|
680
992
|
/**
|
|
681
993
|
* Parses a model ID into {provider, family, version}.
|
|
682
994
|
*
|
|
@@ -708,7 +1020,13 @@ export function parseModelId(modelId) {
|
|
|
708
1020
|
}
|
|
709
1021
|
const gpt = normalized.match(GPT_RE);
|
|
710
1022
|
if (gpt) {
|
|
711
|
-
|
|
1023
|
+
const version = gpt[1];
|
|
1024
|
+
const variant = GPT_TIER_VARIANT_RE.exec(version)?.[1];
|
|
1025
|
+
// The key is only present when set, so untiered results stay deep-equal
|
|
1026
|
+
// to what earlier releases returned.
|
|
1027
|
+
return variant
|
|
1028
|
+
? { provider: 'openai', family: 'gpt', version, variant }
|
|
1029
|
+
: { provider: 'openai', family: 'gpt', version };
|
|
712
1030
|
}
|
|
713
1031
|
const oSeries = normalized.match(O_SERIES_RE);
|
|
714
1032
|
if (oSeries) {
|
|
@@ -730,24 +1048,45 @@ function findLongestPrefix(keys, modelId) {
|
|
|
730
1048
|
}
|
|
731
1049
|
return null;
|
|
732
1050
|
}
|
|
733
|
-
/**
|
|
734
|
-
|
|
1051
|
+
/**
|
|
1052
|
+
* Resolve pricing and disclose which layer answered and whether the result was
|
|
1053
|
+
* inherited by prefix.
|
|
1054
|
+
*
|
|
1055
|
+
* Order: registered entries (default mode); exact imported, catalog, and
|
|
1056
|
+
* static matches; registered `onlyIfMissing` entries; catalog then static
|
|
1057
|
+
* prefix matches; unpriced.
|
|
1058
|
+
*/
|
|
1059
|
+
export function resolveModelPricing(modelId, options) {
|
|
735
1060
|
const stripped = modelId.replace(/\[1m\]/gi, '');
|
|
736
1061
|
const rawId = stripped.trim().toLowerCase();
|
|
737
|
-
const
|
|
1062
|
+
const aliasId = resolveModelAlias(stripped);
|
|
738
1063
|
// The raw id is tried before its alias target at every step: pricing
|
|
739
1064
|
// recorded for the alias id itself is more specific than the canonical
|
|
740
1065
|
// fallback, so registering an alias never orphans it.
|
|
741
|
-
const candidateIds = rawId ===
|
|
742
|
-
const
|
|
1066
|
+
const candidateIds = rawId === aliasId ? [aliasId] : [rawId, aliasId];
|
|
1067
|
+
const registered = options?.includeRegistered === false ? null : findRegisteredPricing(rawId, aliasId);
|
|
1068
|
+
const registeredResult = (match) => ({
|
|
1069
|
+
modelId,
|
|
1070
|
+
canonicalModelId: aliasId,
|
|
1071
|
+
pricing: { ...match.entry.pricing },
|
|
1072
|
+
provenance: {
|
|
1073
|
+
source: 'registered',
|
|
1074
|
+
match: 'exact',
|
|
1075
|
+
matchedModelId: match.id,
|
|
1076
|
+
inheritedByPrefix: false,
|
|
1077
|
+
},
|
|
1078
|
+
});
|
|
1079
|
+
if (registered && !registered.entry.onlyIfMissing)
|
|
1080
|
+
return registeredResult(registered);
|
|
1081
|
+
const imported = importedTable[rawId] ?? importedTable[aliasId];
|
|
743
1082
|
if (imported)
|
|
744
|
-
return { ...imported, modelId, canonicalModelId };
|
|
1083
|
+
return { ...imported, modelId, canonicalModelId: aliasId };
|
|
745
1084
|
for (const id of candidateIds) {
|
|
746
1085
|
const exactOverride = overrideTable[id];
|
|
747
1086
|
if (exactOverride) {
|
|
748
1087
|
return {
|
|
749
1088
|
modelId,
|
|
750
|
-
canonicalModelId,
|
|
1089
|
+
canonicalModelId: aliasId,
|
|
751
1090
|
pricing: exactOverride,
|
|
752
1091
|
provenance: {
|
|
753
1092
|
source: 'catalog',
|
|
@@ -763,7 +1102,7 @@ export function resolveModelPricing(modelId) {
|
|
|
763
1102
|
if (exactStatic) {
|
|
764
1103
|
return {
|
|
765
1104
|
modelId,
|
|
766
|
-
canonicalModelId,
|
|
1105
|
+
canonicalModelId: aliasId,
|
|
767
1106
|
pricing: exactStatic,
|
|
768
1107
|
provenance: {
|
|
769
1108
|
source: 'static',
|
|
@@ -774,12 +1113,15 @@ export function resolveModelPricing(modelId) {
|
|
|
774
1113
|
};
|
|
775
1114
|
}
|
|
776
1115
|
}
|
|
1116
|
+
// A gap-filling registration answers once no layer has an exact price.
|
|
1117
|
+
if (registered)
|
|
1118
|
+
return registeredResult(registered);
|
|
777
1119
|
for (const id of candidateIds) {
|
|
778
1120
|
const overridePrefix = findLongestPrefix(overrideSortedKeys, id);
|
|
779
1121
|
if (overridePrefix) {
|
|
780
1122
|
return {
|
|
781
1123
|
modelId,
|
|
782
|
-
canonicalModelId,
|
|
1124
|
+
canonicalModelId: aliasId,
|
|
783
1125
|
pricing: overrideTable[overridePrefix],
|
|
784
1126
|
provenance: {
|
|
785
1127
|
source: 'catalog',
|
|
@@ -791,11 +1133,11 @@ export function resolveModelPricing(modelId) {
|
|
|
791
1133
|
}
|
|
792
1134
|
}
|
|
793
1135
|
for (const id of candidateIds) {
|
|
794
|
-
const staticPrefix = findLongestPrefix(
|
|
1136
|
+
const staticPrefix = findLongestPrefix(getStaticSortedKeys(), id);
|
|
795
1137
|
if (staticPrefix) {
|
|
796
1138
|
return {
|
|
797
1139
|
modelId,
|
|
798
|
-
canonicalModelId,
|
|
1140
|
+
canonicalModelId: aliasId,
|
|
799
1141
|
pricing: PRICING_TABLE[staticPrefix],
|
|
800
1142
|
provenance: {
|
|
801
1143
|
source: 'static',
|
|
@@ -808,7 +1150,7 @@ export function resolveModelPricing(modelId) {
|
|
|
808
1150
|
}
|
|
809
1151
|
return {
|
|
810
1152
|
modelId,
|
|
811
|
-
canonicalModelId,
|
|
1153
|
+
canonicalModelId: aliasId,
|
|
812
1154
|
pricing: null,
|
|
813
1155
|
provenance: { source: 'none', match: 'none', inheritedByPrefix: false },
|
|
814
1156
|
};
|
|
@@ -816,9 +1158,11 @@ export function resolveModelPricing(modelId) {
|
|
|
816
1158
|
/**
|
|
817
1159
|
* Gets pricing for a model ID.
|
|
818
1160
|
*
|
|
819
|
-
* Lookup order:
|
|
820
|
-
* 1.
|
|
821
|
-
* 2.
|
|
1161
|
+
* Lookup order (see `resolveModelPricing` for provenance):
|
|
1162
|
+
* 1. Registered entries (`registerModelPricing`), exact matches only.
|
|
1163
|
+
* 2. Imported resolutions, then the runtime override map (from LiteLLM
|
|
1164
|
+
* catalog hydration), then the static PRICING_TABLE — exact before prefix,
|
|
1165
|
+
* with gap-filling registered entries between the two.
|
|
822
1166
|
* 3. `null` — unknown model. Callers MUST handle this.
|
|
823
1167
|
*
|
|
824
1168
|
* The ID is first looked up verbatim (minus the "[1m]" suffix) — override
|
|
@@ -910,22 +1254,47 @@ export function mergeCostSources(a, b) {
|
|
|
910
1254
|
};
|
|
911
1255
|
return rank[a] >= rank[b] ? a : b;
|
|
912
1256
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1257
|
+
/**
|
|
1258
|
+
* Map the provenance `calculateNormalizedUsageCost` reports to the display
|
|
1259
|
+
* cost source: provider-reported costs are `reported`, costs computed from
|
|
1260
|
+
* explicit or catalog pricing are `estimated`, and unpriced stays `unpriced`.
|
|
1261
|
+
*/
|
|
1262
|
+
export function costSourceFromPricingProvenance(provenance) {
|
|
1263
|
+
switch (provenance) {
|
|
1264
|
+
case 'provider-reported':
|
|
1265
|
+
return 'reported';
|
|
1266
|
+
case 'explicit-pricing':
|
|
1267
|
+
case 'model-catalog':
|
|
1268
|
+
return 'estimated';
|
|
1269
|
+
default:
|
|
1270
|
+
return 'unpriced';
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Merge the cost sources of a rollup's components, least certain winning (as
|
|
1275
|
+
* `mergeCostSources`). Components without a `source` have not been seen yet
|
|
1276
|
+
* and are ignored, and an `unpriced` component that contributed no tokens
|
|
1277
|
+
* does not taint the total. Returns `undefined` when nothing counted.
|
|
1278
|
+
*/
|
|
1279
|
+
export function mergeCostComponents(components) {
|
|
1280
|
+
let merged;
|
|
1281
|
+
for (const component of components) {
|
|
1282
|
+
const source = component?.source;
|
|
1283
|
+
if (!source)
|
|
1284
|
+
continue;
|
|
1285
|
+
if (source === 'unpriced' && !(component.tokens > 0))
|
|
1286
|
+
continue;
|
|
1287
|
+
merged = merged ? mergeCostSources(merged, source) : source;
|
|
1288
|
+
}
|
|
1289
|
+
return merged;
|
|
922
1290
|
}
|
|
1291
|
+
// ── Display ──
|
|
923
1292
|
/**
|
|
924
1293
|
* Short display label for model IDs. Keeps historical Claude family labels
|
|
925
1294
|
* compact while normalizing common OpenAI labels.
|
|
926
1295
|
*/
|
|
927
1296
|
export function shortModelName(modelId) {
|
|
928
|
-
const normalized =
|
|
1297
|
+
const normalized = canonicalModelId(modelId);
|
|
929
1298
|
const parsed = parseModelId(normalized);
|
|
930
1299
|
if (normalized.includes('codex'))
|
|
931
1300
|
return 'Codex';
|
|
@@ -964,7 +1333,7 @@ function versionRank(version) {
|
|
|
964
1333
|
*/
|
|
965
1334
|
export function getModelDisplayInfo(modelId) {
|
|
966
1335
|
const parsed = parseModelId(modelId);
|
|
967
|
-
const normalized =
|
|
1336
|
+
const normalized = canonicalModelId(modelId);
|
|
968
1337
|
let rank = 1_000;
|
|
969
1338
|
if (parsed?.provider === 'anthropic') {
|
|
970
1339
|
rank = (CLAUDE_FAMILY_RANK[parsed.family] ?? 9) * 100 + versionRank(parsed.version);
|
|
@@ -990,29 +1359,37 @@ export function getModelDisplayInfo(modelId) {
|
|
|
990
1359
|
rank,
|
|
991
1360
|
};
|
|
992
1361
|
}
|
|
993
|
-
/**
|
|
1362
|
+
/**
|
|
1363
|
+
* Order two GPT tier variants of the same family and numeric version
|
|
1364
|
+
* (astra > sol > terra > luna); 0 for every other pair.
|
|
1365
|
+
*/
|
|
1366
|
+
function compareTierVariants(a, b) {
|
|
1367
|
+
const left = parseModelId(a);
|
|
1368
|
+
const right = parseModelId(b);
|
|
1369
|
+
if (!left?.variant || !right?.variant)
|
|
1370
|
+
return 0;
|
|
1371
|
+
if (left.provider !== right.provider || left.family !== right.family)
|
|
1372
|
+
return 0;
|
|
1373
|
+
if (versionRank(left.version) !== versionRank(right.version))
|
|
1374
|
+
return 0;
|
|
1375
|
+
return ((GPT_TIER_VARIANT_RANK[left.variant] ?? Number.MAX_SAFE_INTEGER) -
|
|
1376
|
+
(GPT_TIER_VARIANT_RANK[right.variant] ?? Number.MAX_SAFE_INTEGER));
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Compare two model IDs using shared provider/family ranking rules. Within a
|
|
1380
|
+
* family and numeric version, GPT tiers rank astra > sol > terra > luna.
|
|
1381
|
+
*/
|
|
994
1382
|
export function compareModelIds(a, b) {
|
|
995
1383
|
const left = getModelDisplayInfo(a);
|
|
996
1384
|
const right = getModelDisplayInfo(b);
|
|
997
1385
|
if (left.rank !== right.rank)
|
|
998
1386
|
return left.rank - right.rank;
|
|
1387
|
+
const variantOrder = compareTierVariants(a, b);
|
|
1388
|
+
if (variantOrder !== 0)
|
|
1389
|
+
return variantOrder;
|
|
999
1390
|
return a.localeCompare(b);
|
|
1000
1391
|
}
|
|
1001
1392
|
/** Return a sorted copy of model IDs using shared provider/family ranking rules. */
|
|
1002
1393
|
export function sortModelIds(modelIds) {
|
|
1003
1394
|
return [...modelIds].sort(compareModelIds);
|
|
1004
1395
|
}
|
|
1005
|
-
/**
|
|
1006
|
-
* Formats a USD cost as a currency string.
|
|
1007
|
-
*
|
|
1008
|
-
* - `null` / `undefined` → `"—"` (honest "pricing unavailable").
|
|
1009
|
-
* - `< $0.01` → 4 decimals, so sub-cent costs are still visible.
|
|
1010
|
-
* - otherwise → 2 decimals.
|
|
1011
|
-
*/
|
|
1012
|
-
export function formatCost(cost) {
|
|
1013
|
-
if (cost === null || cost === undefined)
|
|
1014
|
-
return '—';
|
|
1015
|
-
if (cost < 0.01)
|
|
1016
|
-
return `$${cost.toFixed(4)}`;
|
|
1017
|
-
return `$${cost.toFixed(2)}`;
|
|
1018
|
-
}
|
|
@@ -290,7 +290,7 @@ export class MultiProviderQuotaService {
|
|
|
290
290
|
await this.refreshPeakHours();
|
|
291
291
|
const creds = await this.readClaudeCredentials();
|
|
292
292
|
if (!creds) {
|
|
293
|
-
this.handleUnavailableState(makeUnavailableClaudeState('Renew your Claude
|
|
293
|
+
this.handleUnavailableState(makeUnavailableClaudeState('Renew your Claude login to view quota', 'auth'));
|
|
294
294
|
return;
|
|
295
295
|
}
|
|
296
296
|
const state = await this.fetchClaudeQuota(creds.accessToken);
|
package/dist/esm/node.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
export { hydratePricingCatalog, normalizeLiteLlmCatalog, normalizeLiteLlmContextWindows, LITELLM_CATALOG_URL, } from './pricingCatalog';
|
|
9
9
|
export { loadObservedContextWindows, recordObservedContextWindow, getObservedContextWindowPath, } from './observedContextWindows';
|
|
10
10
|
export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
|
|
11
|
-
export { collectPromptHistory, isPromptHistorySessionSettled, parsePromptHistoryCursor, } from './promptHistory';
|
|
11
|
+
export { collectPromptHistory, isPromptHistorySessionSettled, parsePromptHistoryCursor, PROMPT_HISTORY_ORDINAL_MAX_RECORD_BYTES, } from './promptHistory';
|
|
12
|
+
export { findToolCallOrigins } from './toolCallOrigins';
|
|
12
13
|
export { collectSessionPromptHistory } from './sessionPromptHistory';
|
|
13
14
|
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
|
14
15
|
export { computeSessionFileStats, firstUserPrompt, providerContextSizeFn, readSessionFileStats, } from './sessionStats';
|
|
@@ -35,7 +36,12 @@ export { CONFIG_DIR_ENV_VAR, getConfigDir, getConfigDirOverride, getDefaultConfi
|
|
|
35
36
|
export { encodeWorkspacePath as encodeClaudeWorkspacePath, getSessionDirectory as getClaudeSessionDirectory, } from './parsers/sessionPathResolver';
|
|
36
37
|
// Provider homes the CLIs read for this process
|
|
37
38
|
export { getLiveClaudeHome, getDefaultClaudeHome, isDefaultClaudeHome, getClaudeProjectsDir, } from './claudePaths';
|
|
38
|
-
export { getSystemCodexHome, getCodexMonitoringHomes, resolveSidekickCodexHome, getCodexExecutionEnv, getCodexSessionsDirs, CODEX_SESSIONS_SUBDIR, CODEX_ARCHIVED_SESSIONS_SUBDIR, } from './codexPaths';
|
|
39
|
+
export { getSystemCodexHome, getCodexMonitoringHomes, resolveSidekickCodexHome, getCodexExecutionEnv, getCodexSessionsDirs, getCodexCredentialStoreMode, forceFileCredentialStore, CODEX_SESSIONS_SUBDIR, CODEX_ARCHIVED_SESSIONS_SUBDIR, } from './codexPaths';
|
|
40
|
+
export { parseAuthJson as parseCodexAuthJson, readAuthIdentityFromRaw as readCodexAuthIdentity, readLastRefresh as readCodexLastRefresh, readAccessTokenExpiry as readCodexAccessTokenExpiry, identitiesMatch as codexIdentitiesMatch, codexRefreshFingerprint, compareCodexAuthFreshness, } from './codexAuth';
|
|
41
|
+
export { atomicWriteJson, atomicWriteJsonSync } from './writers/atomic';
|
|
42
|
+
export { parseClaudeAuthStatus, parseCodexLoginStatus } from './authStatus';
|
|
43
|
+
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
44
|
+
export { getPricingCatalogInfo, registerModelPricing, clearRegisteredModelPricing, } from './modelInfo';
|
|
39
45
|
export { fetchProviderServiceStatus } from './providerServiceStatus';
|
|
40
46
|
// Tool categories across providers
|
|
41
47
|
export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
@@ -43,4 +49,4 @@ export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
|
43
49
|
export { resolveWorkspaceRoots } from './workspaceRoots';
|
|
44
50
|
export { discoverWorktreeSiblings, resolveWorktreeMainRepo } from './parsers/sessionPathResolver';
|
|
45
51
|
// Bounded JSONL tail reader
|
|
46
|
-
export { createJsonlTail, DEFAULT_JSONL_TAIL_MAX_LINE_BYTES, DEFAULT_JSONL_TAIL_READ_BYTES, } from './watchers/jsonlTail';
|
|
52
|
+
export { createJsonlTail, DEFAULT_JSONL_TAIL_MAX_LINE_BYTES, DEFAULT_JSONL_TAIL_READ_BYTES, JSONL_TAIL_CHECKPOINT_VERSION, JsonlTailSymlinkError, } from './watchers/jsonlTail';
|