sidekick-shared 0.24.5 → 0.25.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 +35 -0
- package/README.md +159 -52
- package/dist/accountChangeSignal.d.ts +3 -0
- package/dist/accountChangeSignal.js +19 -0
- package/dist/accountChanges.d.ts +21 -0
- package/dist/accountChanges.js +151 -0
- package/dist/accountRegistry.d.ts +3 -1
- package/dist/accountRegistry.js +5 -0
- package/dist/browser.d.ts +8 -3
- package/dist/browser.js +15 -1
- package/dist/codexQuotaWatcher.d.ts +6 -0
- package/dist/codexQuotaWatcher.js +101 -47
- package/dist/index.d.ts +23 -13
- package/dist/index.js +34 -10
- package/dist/modelAliases.d.ts +13 -0
- package/dist/modelAliases.js +58 -0
- package/dist/modelCatalog.d.ts +32 -0
- package/dist/modelCatalog.js +145 -0
- package/dist/modelContext.d.ts +36 -3
- package/dist/modelContext.js +109 -34
- package/dist/modelInfo.d.ts +30 -1
- package/dist/modelInfo.js +116 -26
- package/dist/multiProviderQuotaService.d.ts +8 -0
- package/dist/multiProviderQuotaService.js +64 -3
- package/dist/node.d.ts +4 -4
- package/dist/node.js +4 -1
- package/dist/observedSessionCollector.d.ts +75 -4
- package/dist/observedSessionCollector.js +452 -42
- package/dist/parsers/codexHistory.d.ts +4 -2
- package/dist/parsers/codexHistory.js +9 -2
- package/dist/parsers/sessionActivityDetector.d.ts +6 -0
- package/dist/parsers/sessionActivityDetector.js +17 -0
- package/dist/providerIds.d.ts +11 -0
- package/dist/providerIds.js +9 -0
- package/dist/providerQuota.d.ts +3 -1
- package/dist/providerQuota.js +3 -0
- package/dist/providers/claudeCode.d.ts +10 -1
- package/dist/providers/claudeCode.js +204 -39
- package/dist/providers/codex.d.ts +18 -1
- package/dist/providers/codex.js +269 -40
- package/dist/providers/codexDatabase.d.ts +9 -0
- package/dist/providers/codexDatabase.js +107 -2
- package/dist/providers/diagnostics.d.ts +13 -0
- package/dist/providers/diagnostics.js +88 -0
- package/dist/providers/factory.d.ts +14 -0
- package/dist/providers/factory.js +57 -0
- package/dist/providers/openCode.d.ts +20 -1
- package/dist/providers/openCode.js +361 -11
- package/dist/providers/openCodeDatabase.d.ts +10 -0
- package/dist/providers/openCodeDatabase.js +69 -0
- package/dist/providers/types.d.ts +52 -2
- package/dist/providers/types.js +4 -0
- package/dist/quota.d.ts +4 -1
- package/dist/quota.js +3 -7
- package/dist/quotaHistory.d.ts +2 -1
- package/dist/quotaPoller.d.ts +13 -1
- package/dist/quotaPoller.js +65 -3
- package/dist/schemas/accountManager.d.ts +2 -2
- package/dist/schemas/accountManager.js +2 -4
- package/dist/schemas/accountStatus.d.ts +3 -0
- package/dist/schemas/accountStatus.js +1 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/observedSessionV1.d.ts +27 -26
- package/dist/schemas/observedSessionV1.js +6 -4
- package/dist/schemas/quota.d.ts +2 -2
- package/dist/schemas/quota.js +3 -6
- package/dist/schemas/quotaHistory.d.ts +2 -2
- package/dist/schemas/tokenEstimation.d.ts +1 -1
- package/dist/sessionMonitor.d.ts +15 -0
- package/dist/sessionMonitor.js +142 -0
- package/dist/sessionPreviews.d.ts +26 -1
- package/dist/sessionPreviews.js +319 -4
- package/dist/types/observedSessionV1.d.ts +6 -2
- package/dist/types/observedSessionV1.js +14 -8
- package/package.json +22 -1
package/dist/modelContext.js
CHANGED
|
@@ -10,13 +10,19 @@
|
|
|
10
10
|
* model, persisted across runs by `observedContextWindows.ts`. Reflects the
|
|
11
11
|
* effective window for this account/tier, which can be well below the
|
|
12
12
|
* model's published maximum.
|
|
13
|
-
* 3.
|
|
13
|
+
* 3. Imported resolutions — exact entries hydrated from another realm via
|
|
14
|
+
* `importResolvedModelCatalog()`. Below local observed data (a window this
|
|
15
|
+
* realm saw first-hand is fresher than a transferred snapshot), above the
|
|
16
|
+
* catalog.
|
|
17
|
+
* 4. Catalog overrides — `max_input_tokens` from the LiteLLM catalog, hydrated
|
|
14
18
|
* by `pricingCatalog.ts`. Keeps new models correct without a code change.
|
|
15
|
-
*
|
|
19
|
+
* 5. The static table below — offline baseline of last resort.
|
|
16
20
|
*
|
|
17
21
|
* Within that order, match quality comes first: every layer is tried for an
|
|
18
22
|
* exact hit before any layer is tried for a prefix hit. See
|
|
19
|
-
* `getModelContextWindowSize`.
|
|
23
|
+
* `getModelContextWindowSize`. The raw (alias) id is tried before its
|
|
24
|
+
* canonical target at every step, so registering an alias never orphans data
|
|
25
|
+
* recorded under the alias itself.
|
|
20
26
|
*
|
|
21
27
|
* Layers 2 and 3 are pushed in by Node-only modules through the `_set*` hooks,
|
|
22
28
|
* so this file stays browser-safe (no node:fs, no fetch) and can be bundled for
|
|
@@ -30,7 +36,12 @@ exports._clearObservedContextWindows = _clearObservedContextWindows;
|
|
|
30
36
|
exports._setCatalogContextWindows = _setCatalogContextWindows;
|
|
31
37
|
exports._getCatalogContextWindows = _getCatalogContextWindows;
|
|
32
38
|
exports._clearCatalogContextWindows = _clearCatalogContextWindows;
|
|
39
|
+
exports._setImportedResolvedContextWindows = _setImportedResolvedContextWindows;
|
|
40
|
+
exports._clearImportedResolvedContextWindows = _clearImportedResolvedContextWindows;
|
|
41
|
+
exports._getModelContextIds = _getModelContextIds;
|
|
42
|
+
exports.resolveModelContextWindow = resolveModelContextWindow;
|
|
33
43
|
exports.getModelContextWindowSize = getModelContextWindowSize;
|
|
44
|
+
const modelAliases_1 = require("./modelAliases");
|
|
34
45
|
/** Known model context window sizes (in tokens). */
|
|
35
46
|
const MODEL_CONTEXT_SIZES = {
|
|
36
47
|
// Claude — native 1M context (Fable 5, Opus 4.6+, Sonnet 4.6+)
|
|
@@ -92,6 +103,7 @@ let observedTable = {};
|
|
|
92
103
|
let observedSortedKeys = [];
|
|
93
104
|
let catalogTable = {};
|
|
94
105
|
let catalogSortedKeys = [];
|
|
106
|
+
let importedTable = {};
|
|
95
107
|
function sortKeysLongestFirst(table) {
|
|
96
108
|
return Object.keys(table).sort((a, b) => b.length - a.length);
|
|
97
109
|
}
|
|
@@ -145,20 +157,109 @@ function _clearCatalogContextWindows() {
|
|
|
145
157
|
catalogTable = {};
|
|
146
158
|
catalogSortedKeys = [];
|
|
147
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Internal: hydrate exact, already-resolved context data from another realm.
|
|
162
|
+
* Merges so successive partial imports accumulate (aliases already merge);
|
|
163
|
+
* use `_clearImportedResolvedContextWindows` to reset.
|
|
164
|
+
*/
|
|
165
|
+
function _setImportedResolvedContextWindows(values) {
|
|
166
|
+
importedTable = { ...importedTable, ...values };
|
|
167
|
+
}
|
|
168
|
+
/** Internal test hook. */
|
|
169
|
+
function _clearImportedResolvedContextWindows() {
|
|
170
|
+
importedTable = {};
|
|
171
|
+
}
|
|
172
|
+
/** Internal: list every ID known to the context resolver. */
|
|
173
|
+
function _getModelContextIds() {
|
|
174
|
+
return Array.from(new Set([
|
|
175
|
+
...Object.keys(MODEL_CONTEXT_SIZES),
|
|
176
|
+
...Object.keys(catalogTable),
|
|
177
|
+
...Object.keys(observedTable),
|
|
178
|
+
...Object.keys(importedTable),
|
|
179
|
+
]));
|
|
180
|
+
}
|
|
148
181
|
// ── Lookup ──
|
|
149
182
|
/** Exact match against one table. */
|
|
150
183
|
function exactWindow(table, modelId) {
|
|
151
184
|
const hit = table[modelId];
|
|
152
185
|
return hit === undefined ? null : hit;
|
|
153
186
|
}
|
|
154
|
-
|
|
155
|
-
|
|
187
|
+
function exactWindowMatch(table, modelId) {
|
|
188
|
+
const exact = exactWindow(table, modelId);
|
|
189
|
+
return exact === null ? null : { value: exact, match: 'exact', matchedModelId: modelId };
|
|
190
|
+
}
|
|
191
|
+
function prefixWindowMatch(table, sortedKeys, modelId) {
|
|
156
192
|
for (const key of sortedKeys) {
|
|
157
|
-
if (modelId.startsWith(key))
|
|
158
|
-
return table[key];
|
|
193
|
+
if (modelId !== key && modelId.startsWith(key)) {
|
|
194
|
+
return { value: table[key], match: 'prefix', matchedModelId: key };
|
|
195
|
+
}
|
|
159
196
|
}
|
|
160
197
|
return null;
|
|
161
198
|
}
|
|
199
|
+
/** Resolve published, observed, and tier-effective context windows with provenance. */
|
|
200
|
+
function resolveModelContextWindow(modelId) {
|
|
201
|
+
const rawModelId = modelId ?? '';
|
|
202
|
+
const stripped = rawModelId
|
|
203
|
+
.replace(/\[1m\]/gi, '')
|
|
204
|
+
.trim()
|
|
205
|
+
.toLowerCase();
|
|
206
|
+
const canonicalModelId = (0, modelAliases_1.resolveModelAlias)(stripped);
|
|
207
|
+
if (/\[1m\]/i.test(rawModelId) || /\[1m\]/i.test(canonicalModelId)) {
|
|
208
|
+
return {
|
|
209
|
+
modelId: rawModelId,
|
|
210
|
+
canonicalModelId: canonicalModelId.replace(/\[1m\]/gi, ''),
|
|
211
|
+
published: 1_000_000,
|
|
212
|
+
observed: null,
|
|
213
|
+
tierEffective: 1_000_000,
|
|
214
|
+
provenance: { source: 'explicit-1m', match: 'exact', matchedModelId: canonicalModelId },
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
// The raw id is tried before its alias target at every step: data recorded
|
|
218
|
+
// for the alias id itself is more specific than the canonical fallback.
|
|
219
|
+
const candidateIds = stripped === canonicalModelId ? [canonicalModelId] : [stripped, canonicalModelId];
|
|
220
|
+
const firstMatch = (lookup) => {
|
|
221
|
+
for (const id of candidateIds) {
|
|
222
|
+
const hit = lookup(id);
|
|
223
|
+
if (hit)
|
|
224
|
+
return hit;
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
};
|
|
228
|
+
const observedExact = firstMatch((id) => exactWindowMatch(observedTable, id));
|
|
229
|
+
// Imported resolutions rank below local observed data: a window this realm
|
|
230
|
+
// saw first-hand is fresher than a snapshot transferred from another realm.
|
|
231
|
+
if (!observedExact) {
|
|
232
|
+
const imported = importedTable[stripped] ?? importedTable[canonicalModelId];
|
|
233
|
+
if (imported) {
|
|
234
|
+
return { ...imported, modelId: rawModelId, canonicalModelId };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const catalogExact = firstMatch((id) => exactWindowMatch(catalogTable, id));
|
|
238
|
+
const staticExact = firstMatch((id) => exactWindowMatch(MODEL_CONTEXT_SIZES, id));
|
|
239
|
+
const observedPrefix = firstMatch((id) => prefixWindowMatch(observedTable, observedSortedKeys, id));
|
|
240
|
+
const catalogPrefix = firstMatch((id) => prefixWindowMatch(catalogTable, catalogSortedKeys, id));
|
|
241
|
+
const staticPrefix = firstMatch((id) => prefixWindowMatch(MODEL_CONTEXT_SIZES, SORTED_KEYS, id));
|
|
242
|
+
const published = catalogExact ?? staticExact ?? catalogPrefix ?? staticPrefix;
|
|
243
|
+
const effective = observedExact ?? catalogExact ?? staticExact ?? observedPrefix ?? catalogPrefix ?? staticPrefix;
|
|
244
|
+
return {
|
|
245
|
+
modelId: rawModelId,
|
|
246
|
+
canonicalModelId,
|
|
247
|
+
published: published?.value ?? null,
|
|
248
|
+
observed: (observedExact ?? observedPrefix)?.value ?? null,
|
|
249
|
+
tierEffective: effective?.value ?? exports.DEFAULT_CONTEXT_WINDOW,
|
|
250
|
+
provenance: effective
|
|
251
|
+
? {
|
|
252
|
+
source: effective === observedExact || effective === observedPrefix
|
|
253
|
+
? 'observed'
|
|
254
|
+
: effective === catalogExact || effective === catalogPrefix
|
|
255
|
+
? 'catalog'
|
|
256
|
+
: 'static',
|
|
257
|
+
match: effective.match,
|
|
258
|
+
matchedModelId: effective.matchedModelId,
|
|
259
|
+
}
|
|
260
|
+
: { source: 'default', match: 'default' },
|
|
261
|
+
};
|
|
262
|
+
}
|
|
162
263
|
/**
|
|
163
264
|
* Returns the context window size for a model ID.
|
|
164
265
|
*
|
|
@@ -180,31 +281,5 @@ function prefixWindow(table, sortedKeys, modelId) {
|
|
|
180
281
|
* of the static table's exact 1M.
|
|
181
282
|
*/
|
|
182
283
|
function getModelContextWindowSize(modelId) {
|
|
183
|
-
|
|
184
|
-
return exports.DEFAULT_CONTEXT_WINDOW;
|
|
185
|
-
// Claude Code tags the 1M-context variant with a "[1m]" suffix on the
|
|
186
|
-
// model ID. If we see it, honor it regardless of the base family.
|
|
187
|
-
if (/\[1m\]/i.test(modelId))
|
|
188
|
-
return 1_000_000;
|
|
189
|
-
// Strip the suffix if present, so the normal lookup still succeeds when
|
|
190
|
-
// a caller passes e.g. "claude-opus-5[1m]" and we've already handled it.
|
|
191
|
-
// Trim/lowercase so padded or mixed-case IDs match the lowercase table keys.
|
|
192
|
-
const normalized = modelId
|
|
193
|
-
.replace(/\[1m\]/gi, '')
|
|
194
|
-
.trim()
|
|
195
|
-
.toLowerCase();
|
|
196
|
-
// Pass 1 — exact matches, most-trusted layer first.
|
|
197
|
-
const exact = exactWindow(observedTable, normalized) ??
|
|
198
|
-
exactWindow(catalogTable, normalized) ??
|
|
199
|
-
exactWindow(MODEL_CONTEXT_SIZES, normalized);
|
|
200
|
-
if (exact !== null)
|
|
201
|
-
return exact;
|
|
202
|
-
// Pass 2 — longest-prefix matches, same layer order. Resolves versioned IDs
|
|
203
|
-
// that no layer spells out, e.g. "claude-opus-4-6-20250414".
|
|
204
|
-
const prefix = prefixWindow(observedTable, observedSortedKeys, normalized) ??
|
|
205
|
-
prefixWindow(catalogTable, catalogSortedKeys, normalized) ??
|
|
206
|
-
prefixWindow(MODEL_CONTEXT_SIZES, SORTED_KEYS, normalized);
|
|
207
|
-
if (prefix !== null)
|
|
208
|
-
return prefix;
|
|
209
|
-
return exports.DEFAULT_CONTEXT_WINDOW;
|
|
284
|
+
return resolveModelContextWindow(modelId).tierEffective;
|
|
210
285
|
}
|
package/dist/modelInfo.d.ts
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @module modelInfo
|
|
19
19
|
*/
|
|
20
|
+
import type { ModelProviderId } from './providerIds';
|
|
21
|
+
export { MODEL_PROVIDER_IDS } from './providerIds';
|
|
20
22
|
/** Pricing information for a model. All costs are per million tokens in USD. */
|
|
21
23
|
export interface ModelPricing {
|
|
22
24
|
inputCostPerMillion: number;
|
|
@@ -24,6 +26,21 @@ export interface ModelPricing {
|
|
|
24
26
|
cacheWriteCostPerMillion: number;
|
|
25
27
|
cacheReadCostPerMillion: number;
|
|
26
28
|
}
|
|
29
|
+
export type ModelPricingSource = 'imported' | 'catalog' | 'static' | 'none';
|
|
30
|
+
export type ModelPricingMatch = 'exact' | 'prefix' | 'none';
|
|
31
|
+
export interface ModelPricingProvenance {
|
|
32
|
+
source: ModelPricingSource;
|
|
33
|
+
match: ModelPricingMatch;
|
|
34
|
+
matchedModelId?: string;
|
|
35
|
+
/** True when the price was inherited from a shorter model-ID prefix. */
|
|
36
|
+
inheritedByPrefix: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface ResolvedModelPricing {
|
|
39
|
+
modelId: string;
|
|
40
|
+
canonicalModelId: string;
|
|
41
|
+
pricing: ModelPricing | null;
|
|
42
|
+
provenance: ModelPricingProvenance;
|
|
43
|
+
}
|
|
27
44
|
/**
|
|
28
45
|
* Token usage for the legacy cost calculation contract.
|
|
29
46
|
* @deprecated Use NormalizedUsage and calculateNormalizedUsageCost. This shape
|
|
@@ -42,7 +59,7 @@ export interface CostTokenUsage {
|
|
|
42
59
|
reasoningTokens?: number;
|
|
43
60
|
}
|
|
44
61
|
/** Provider that hosts a model. "unknown" means we couldn't classify it. */
|
|
45
|
-
export type ModelProvider =
|
|
62
|
+
export type ModelProvider = ModelProviderId;
|
|
46
63
|
/** Structured result of parsing a raw model ID. */
|
|
47
64
|
export interface ParsedModelId {
|
|
48
65
|
provider: ModelProvider;
|
|
@@ -93,6 +110,16 @@ export declare function _setPricingOverrides(overrides: Record<string, ModelPric
|
|
|
93
110
|
export declare function _getPricingOverrides(): Record<string, ModelPricing>;
|
|
94
111
|
/** Internal: clear overrides (used by tests and when disabling hydration). */
|
|
95
112
|
export declare function _clearPricingOverrides(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Internal: hydrate exact pricing resolutions exported by another realm.
|
|
115
|
+
* Merges so successive partial imports accumulate (aliases already merge);
|
|
116
|
+
* use `_clearImportedResolvedPricing` to reset.
|
|
117
|
+
*/
|
|
118
|
+
export declare function _setImportedResolvedPricing(values: Record<string, ResolvedModelPricing>): void;
|
|
119
|
+
/** Internal test hook. */
|
|
120
|
+
export declare function _clearImportedResolvedPricing(): void;
|
|
121
|
+
/** Internal: list every ID known to the pricing resolver. */
|
|
122
|
+
export declare function _getModelPricingIds(): string[];
|
|
96
123
|
/**
|
|
97
124
|
* Parses a model ID into {provider, family, version}.
|
|
98
125
|
*
|
|
@@ -103,6 +130,8 @@ export declare function _clearPricingOverrides(): void;
|
|
|
103
130
|
* Returns null for anything else — callers should treat that as "unknown model".
|
|
104
131
|
*/
|
|
105
132
|
export declare function parseModelId(modelId: string): ParsedModelId | null;
|
|
133
|
+
/** Resolve pricing and disclose whether the result was inherited by prefix. */
|
|
134
|
+
export declare function resolveModelPricing(modelId: string): ResolvedModelPricing;
|
|
106
135
|
/**
|
|
107
136
|
* Gets pricing for a model ID.
|
|
108
137
|
*
|
package/dist/modelInfo.js
CHANGED
|
@@ -19,10 +19,15 @@
|
|
|
19
19
|
* @module modelInfo
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.MODEL_PROVIDER_IDS = void 0;
|
|
22
23
|
exports._setPricingOverrides = _setPricingOverrides;
|
|
23
24
|
exports._getPricingOverrides = _getPricingOverrides;
|
|
24
25
|
exports._clearPricingOverrides = _clearPricingOverrides;
|
|
26
|
+
exports._setImportedResolvedPricing = _setImportedResolvedPricing;
|
|
27
|
+
exports._clearImportedResolvedPricing = _clearImportedResolvedPricing;
|
|
28
|
+
exports._getModelPricingIds = _getModelPricingIds;
|
|
25
29
|
exports.parseModelId = parseModelId;
|
|
30
|
+
exports.resolveModelPricing = resolveModelPricing;
|
|
26
31
|
exports.getModelPricing = getModelPricing;
|
|
27
32
|
exports.getModelInfo = getModelInfo;
|
|
28
33
|
exports.calculateCostWithPricing = calculateCostWithPricing;
|
|
@@ -35,6 +40,9 @@ exports.compareModelIds = compareModelIds;
|
|
|
35
40
|
exports.sortModelIds = sortModelIds;
|
|
36
41
|
exports.formatCost = formatCost;
|
|
37
42
|
const modelContext_1 = require("./modelContext");
|
|
43
|
+
const modelAliases_1 = require("./modelAliases");
|
|
44
|
+
var providerIds_1 = require("./providerIds");
|
|
45
|
+
Object.defineProperty(exports, "MODEL_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.MODEL_PROVIDER_IDS; } });
|
|
38
46
|
// ── Static Pricing Table ──
|
|
39
47
|
/**
|
|
40
48
|
* Static baseline pricing. Keys are model-ID prefixes; lookup uses
|
|
@@ -412,6 +420,7 @@ const STATIC_SORTED_KEYS = Object.keys(PRICING_TABLE).sort((a, b) => b.length -
|
|
|
412
420
|
// ── Override Table (populated at runtime by pricingCatalog) ──
|
|
413
421
|
let overrideTable = {};
|
|
414
422
|
let overrideSortedKeys = [];
|
|
423
|
+
let importedTable = {};
|
|
415
424
|
/**
|
|
416
425
|
* Internal: replace the runtime override map. Called by `pricingCatalog.ts`
|
|
417
426
|
* after a successful LiteLLM hydration. Not part of the stable public API,
|
|
@@ -419,7 +428,7 @@ let overrideSortedKeys = [];
|
|
|
419
428
|
* creating a circular import.
|
|
420
429
|
*/
|
|
421
430
|
function _setPricingOverrides(overrides) {
|
|
422
|
-
overrideTable = { ...
|
|
431
|
+
overrideTable = Object.fromEntries(Object.entries(overrides).map(([key, value]) => [key.trim().toLowerCase(), { ...value }]));
|
|
423
432
|
overrideSortedKeys = Object.keys(overrideTable).sort((a, b) => b.length - a.length);
|
|
424
433
|
}
|
|
425
434
|
/** Internal: snapshot current overrides (test + diagnostics). */
|
|
@@ -431,6 +440,26 @@ function _clearPricingOverrides() {
|
|
|
431
440
|
overrideTable = {};
|
|
432
441
|
overrideSortedKeys = [];
|
|
433
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* Internal: hydrate exact pricing resolutions exported by another realm.
|
|
445
|
+
* Merges so successive partial imports accumulate (aliases already merge);
|
|
446
|
+
* use `_clearImportedResolvedPricing` to reset.
|
|
447
|
+
*/
|
|
448
|
+
function _setImportedResolvedPricing(values) {
|
|
449
|
+
importedTable = { ...importedTable, ...values };
|
|
450
|
+
}
|
|
451
|
+
/** Internal test hook. */
|
|
452
|
+
function _clearImportedResolvedPricing() {
|
|
453
|
+
importedTable = {};
|
|
454
|
+
}
|
|
455
|
+
/** Internal: list every ID known to the pricing resolver. */
|
|
456
|
+
function _getModelPricingIds() {
|
|
457
|
+
return Array.from(new Set([
|
|
458
|
+
...Object.keys(PRICING_TABLE),
|
|
459
|
+
...Object.keys(overrideTable),
|
|
460
|
+
...Object.keys(importedTable),
|
|
461
|
+
]));
|
|
462
|
+
}
|
|
434
463
|
// ── Model ID Parsing ──
|
|
435
464
|
// Anthropic writes the minor version with a hyphen in modern IDs
|
|
436
465
|
// (`claude-sonnet-4-6-20260321`) and a dot in older ones
|
|
@@ -454,10 +483,7 @@ const GEMINI_RE = /^gemini-([0-9][0-9.A-Za-z-]*)/i;
|
|
|
454
483
|
function parseModelId(modelId) {
|
|
455
484
|
if (!modelId)
|
|
456
485
|
return null;
|
|
457
|
-
const normalized = modelId
|
|
458
|
-
.replace(/\[1m\]/gi, '')
|
|
459
|
-
.trim()
|
|
460
|
-
.toLowerCase();
|
|
486
|
+
const normalized = (0, modelAliases_1.resolveModelAlias)(modelId.replace(/\[1m\]/gi, ''));
|
|
461
487
|
const claude = normalized.match(CLAUDE_RE);
|
|
462
488
|
if (claude) {
|
|
463
489
|
return {
|
|
@@ -490,27 +516,96 @@ function parseModelId(modelId) {
|
|
|
490
516
|
return null;
|
|
491
517
|
}
|
|
492
518
|
// ── Pricing Lookup ──
|
|
493
|
-
/** Find the longest key in `keys` that is a prefix of `modelId`, or null. */
|
|
519
|
+
/** Find the longest shorter key in `keys` that is a prefix of `modelId`, or null. */
|
|
494
520
|
function findLongestPrefix(keys, modelId) {
|
|
495
521
|
for (const key of keys) {
|
|
496
|
-
if (modelId
|
|
522
|
+
if (modelId !== key && modelId.startsWith(key))
|
|
497
523
|
return key;
|
|
498
524
|
}
|
|
499
525
|
return null;
|
|
500
526
|
}
|
|
501
|
-
/**
|
|
502
|
-
function
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
if (
|
|
512
|
-
return
|
|
513
|
-
|
|
527
|
+
/** Resolve pricing and disclose whether the result was inherited by prefix. */
|
|
528
|
+
function resolveModelPricing(modelId) {
|
|
529
|
+
const stripped = modelId.replace(/\[1m\]/gi, '');
|
|
530
|
+
const rawId = stripped.trim().toLowerCase();
|
|
531
|
+
const canonicalModelId = (0, modelAliases_1.resolveModelAlias)(stripped);
|
|
532
|
+
// The raw id is tried before its alias target at every step: pricing
|
|
533
|
+
// recorded for the alias id itself is more specific than the canonical
|
|
534
|
+
// fallback, so registering an alias never orphans it.
|
|
535
|
+
const candidateIds = rawId === canonicalModelId ? [canonicalModelId] : [rawId, canonicalModelId];
|
|
536
|
+
const imported = importedTable[rawId] ?? importedTable[canonicalModelId];
|
|
537
|
+
if (imported)
|
|
538
|
+
return { ...imported, modelId, canonicalModelId };
|
|
539
|
+
for (const id of candidateIds) {
|
|
540
|
+
const exactOverride = overrideTable[id];
|
|
541
|
+
if (exactOverride) {
|
|
542
|
+
return {
|
|
543
|
+
modelId,
|
|
544
|
+
canonicalModelId,
|
|
545
|
+
pricing: exactOverride,
|
|
546
|
+
provenance: {
|
|
547
|
+
source: 'catalog',
|
|
548
|
+
match: 'exact',
|
|
549
|
+
matchedModelId: id,
|
|
550
|
+
inheritedByPrefix: false,
|
|
551
|
+
},
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
for (const id of candidateIds) {
|
|
556
|
+
const exactStatic = PRICING_TABLE[id];
|
|
557
|
+
if (exactStatic) {
|
|
558
|
+
return {
|
|
559
|
+
modelId,
|
|
560
|
+
canonicalModelId,
|
|
561
|
+
pricing: exactStatic,
|
|
562
|
+
provenance: {
|
|
563
|
+
source: 'static',
|
|
564
|
+
match: 'exact',
|
|
565
|
+
matchedModelId: id,
|
|
566
|
+
inheritedByPrefix: false,
|
|
567
|
+
},
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
for (const id of candidateIds) {
|
|
572
|
+
const overridePrefix = findLongestPrefix(overrideSortedKeys, id);
|
|
573
|
+
if (overridePrefix) {
|
|
574
|
+
return {
|
|
575
|
+
modelId,
|
|
576
|
+
canonicalModelId,
|
|
577
|
+
pricing: overrideTable[overridePrefix],
|
|
578
|
+
provenance: {
|
|
579
|
+
source: 'catalog',
|
|
580
|
+
match: 'prefix',
|
|
581
|
+
matchedModelId: overridePrefix,
|
|
582
|
+
inheritedByPrefix: true,
|
|
583
|
+
},
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
for (const id of candidateIds) {
|
|
588
|
+
const staticPrefix = findLongestPrefix(STATIC_SORTED_KEYS, id);
|
|
589
|
+
if (staticPrefix) {
|
|
590
|
+
return {
|
|
591
|
+
modelId,
|
|
592
|
+
canonicalModelId,
|
|
593
|
+
pricing: PRICING_TABLE[staticPrefix],
|
|
594
|
+
provenance: {
|
|
595
|
+
source: 'static',
|
|
596
|
+
match: 'prefix',
|
|
597
|
+
matchedModelId: staticPrefix,
|
|
598
|
+
inheritedByPrefix: true,
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return {
|
|
604
|
+
modelId,
|
|
605
|
+
canonicalModelId,
|
|
606
|
+
pricing: null,
|
|
607
|
+
provenance: { source: 'none', match: 'none', inheritedByPrefix: false },
|
|
608
|
+
};
|
|
514
609
|
}
|
|
515
610
|
/**
|
|
516
611
|
* Gets pricing for a model ID.
|
|
@@ -530,12 +625,7 @@ function lookupPricing(modelId) {
|
|
|
530
625
|
function getModelPricing(modelId) {
|
|
531
626
|
if (!modelId)
|
|
532
627
|
return null;
|
|
533
|
-
|
|
534
|
-
const direct = lookupPricing(stripped);
|
|
535
|
-
if (direct)
|
|
536
|
-
return direct;
|
|
537
|
-
const normalized = stripped.trim().toLowerCase();
|
|
538
|
-
return normalized === stripped ? null : lookupPricing(normalized);
|
|
628
|
+
return resolveModelPricing(modelId).pricing;
|
|
539
629
|
}
|
|
540
630
|
/**
|
|
541
631
|
* Returns comprehensive metadata for a model ID.
|
|
@@ -4,6 +4,7 @@ import type { PeakHoursState } from './peakHours';
|
|
|
4
4
|
import type { QuotaState } from './quota';
|
|
5
5
|
import type { Disposable } from './quotaPoller';
|
|
6
6
|
import type { ProviderQuotaMap, ProviderQuotaState } from './providerQuota';
|
|
7
|
+
import { type AccountsChangedEvent } from './accountChanges';
|
|
7
8
|
type Logger = (message: string, error?: unknown) => void;
|
|
8
9
|
interface CodexWatcherLike extends Disposable {
|
|
9
10
|
start(): void;
|
|
@@ -28,6 +29,7 @@ export interface MultiProviderQuotaServiceOptions {
|
|
|
28
29
|
readClaudeAccount?: typeof resolveActiveClaudeAccount;
|
|
29
30
|
fetchClaudeQuota?: (accessToken: string) => Promise<QuotaState>;
|
|
30
31
|
fetchPeakHours?: () => Promise<PeakHoursState>;
|
|
32
|
+
subscribeAccountsChanged?: (listener: (event: AccountsChangedEvent) => void) => Disposable;
|
|
31
33
|
log?: Logger;
|
|
32
34
|
}
|
|
33
35
|
export declare class MultiProviderQuotaService implements Disposable {
|
|
@@ -41,6 +43,7 @@ export declare class MultiProviderQuotaService implements Disposable {
|
|
|
41
43
|
private readonly fetchClaudeQuota;
|
|
42
44
|
private readonly fetchPeakHours;
|
|
43
45
|
private readonly log?;
|
|
46
|
+
private readonly subscribeAccountsChanged;
|
|
44
47
|
private readonly listeners;
|
|
45
48
|
private readonly codexWatcher;
|
|
46
49
|
private readonly ownsCodexWatcher;
|
|
@@ -60,6 +63,10 @@ export declare class MultiProviderQuotaService implements Disposable {
|
|
|
60
63
|
private currentPeakHours;
|
|
61
64
|
private lastFreshPeakHoursAt;
|
|
62
65
|
private peakHoursErrorLogged;
|
|
66
|
+
private claudeDormant;
|
|
67
|
+
private accountSubscription;
|
|
68
|
+
private pollInFlight;
|
|
69
|
+
private pendingWake;
|
|
63
70
|
constructor(options?: MultiProviderQuotaServiceOptions);
|
|
64
71
|
startPolling(): void;
|
|
65
72
|
stopPolling(): void;
|
|
@@ -73,6 +80,7 @@ export declare class MultiProviderQuotaService implements Disposable {
|
|
|
73
80
|
dispose(): void;
|
|
74
81
|
private refreshPeakHours;
|
|
75
82
|
private poll;
|
|
83
|
+
private wakeForAccountChange;
|
|
76
84
|
private emitClaudeState;
|
|
77
85
|
private handleUnavailableState;
|
|
78
86
|
private handleTransientFailure;
|
|
@@ -7,10 +7,12 @@ const credentials_1 = require("./credentials");
|
|
|
7
7
|
const peakHours_1 = require("./peakHours");
|
|
8
8
|
const quota_1 = require("./quota");
|
|
9
9
|
const quotaPresentation_1 = require("./quotaPresentation");
|
|
10
|
+
const accountChanges_1 = require("./accountChanges");
|
|
10
11
|
const ACTIVE_POLL_INTERVAL_MS = 60_000;
|
|
11
12
|
const IDLE_POLL_INTERVAL_MS = 300_000;
|
|
12
13
|
const TRANSIENT_FAILURE_BACKOFF_MS = [30_000, 60_000, 120_000, 240_000, 300_000];
|
|
13
14
|
const PEAK_HOURS_CACHE_MAX_AGE_MS = 10 * 60 * 1000;
|
|
15
|
+
const SIGNED_OUT_ERROR = 'Sign in to a Claude account to view quota';
|
|
14
16
|
function makeUnavailableClaudeState(error, failureKind) {
|
|
15
17
|
return {
|
|
16
18
|
runtimeProvider: 'claude',
|
|
@@ -55,6 +57,7 @@ class MultiProviderQuotaService {
|
|
|
55
57
|
fetchClaudeQuota;
|
|
56
58
|
fetchPeakHours;
|
|
57
59
|
log;
|
|
60
|
+
subscribeAccountsChanged;
|
|
58
61
|
listeners = [];
|
|
59
62
|
codexWatcher;
|
|
60
63
|
ownsCodexWatcher;
|
|
@@ -74,6 +77,10 @@ class MultiProviderQuotaService {
|
|
|
74
77
|
currentPeakHours;
|
|
75
78
|
lastFreshPeakHoursAt = 0;
|
|
76
79
|
peakHoursErrorLogged = false;
|
|
80
|
+
claudeDormant = false;
|
|
81
|
+
accountSubscription = null;
|
|
82
|
+
pollInFlight = false;
|
|
83
|
+
pendingWake = false;
|
|
77
84
|
constructor(options = {}) {
|
|
78
85
|
this.activeIntervalMs = options.activeIntervalMs ?? ACTIVE_POLL_INTERVAL_MS;
|
|
79
86
|
this.idleIntervalMs = options.idleIntervalMs ?? IDLE_POLL_INTERVAL_MS;
|
|
@@ -85,6 +92,7 @@ class MultiProviderQuotaService {
|
|
|
85
92
|
this.readClaudeAccount = options.readClaudeAccount ?? accounts_1.resolveActiveClaudeAccount;
|
|
86
93
|
this.fetchClaudeQuota = options.fetchClaudeQuota ?? quota_1.fetchQuota;
|
|
87
94
|
this.fetchPeakHours = options.fetchPeakHours ?? peakHours_1.fetchPeakHoursStatus;
|
|
95
|
+
this.subscribeAccountsChanged = options.subscribeAccountsChanged ?? accountChanges_1.onAccountsChanged;
|
|
88
96
|
this.log = options.log;
|
|
89
97
|
if (options.codexWatcher !== undefined) {
|
|
90
98
|
this.codexWatcher = options.codexWatcher;
|
|
@@ -119,21 +127,25 @@ class MultiProviderQuotaService {
|
|
|
119
127
|
if (this.polling)
|
|
120
128
|
return;
|
|
121
129
|
this.polling = true;
|
|
130
|
+
this.accountSubscription ??= this.subscribeAccountsChanged(() => this.wakeForAccountChange());
|
|
122
131
|
this.codexWatcher?.start();
|
|
123
132
|
this.zaiWatcher?.start();
|
|
124
|
-
|
|
133
|
+
this.wakeForAccountChange();
|
|
125
134
|
this.log?.('[Quota] Polling started');
|
|
126
135
|
}
|
|
127
136
|
stopPolling() {
|
|
128
137
|
if (!this.polling)
|
|
129
138
|
return;
|
|
130
139
|
this.polling = false;
|
|
140
|
+
this.claudeDormant = false;
|
|
131
141
|
if (this.timer) {
|
|
132
142
|
clearTimeout(this.timer);
|
|
133
143
|
this.timer = undefined;
|
|
134
144
|
}
|
|
135
145
|
this.codexWatcher?.stop();
|
|
136
146
|
this.zaiWatcher?.stop();
|
|
147
|
+
this.accountSubscription?.dispose();
|
|
148
|
+
this.accountSubscription = null;
|
|
137
149
|
this.log?.('[Quota] Polling stopped');
|
|
138
150
|
}
|
|
139
151
|
setPollingMode(mode) {
|
|
@@ -250,8 +262,35 @@ class MultiProviderQuotaService {
|
|
|
250
262
|
this.currentPeakHours = result;
|
|
251
263
|
}
|
|
252
264
|
async poll() {
|
|
253
|
-
|
|
265
|
+
if (!this.polling || this.pollInFlight) {
|
|
266
|
+
this.pendingWake = this.polling;
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
this.pollInFlight = true;
|
|
270
|
+
this.pendingWake = false;
|
|
254
271
|
try {
|
|
272
|
+
let accountPresent = false;
|
|
273
|
+
try {
|
|
274
|
+
accountPresent = this.readClaudeAccount().source !== 'none';
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
accountPresent = false;
|
|
278
|
+
}
|
|
279
|
+
if (!accountPresent) {
|
|
280
|
+
this.claudeDormant = true;
|
|
281
|
+
this.resetTransientFailureState();
|
|
282
|
+
this.authUnavailableActive = false;
|
|
283
|
+
this.lastSuccessfulClaudeState = null;
|
|
284
|
+
// Stay visible while dormant: consumers render their sign-in prompt
|
|
285
|
+
// from an unavailable auth entry, not from a missing map key.
|
|
286
|
+
if (this.quotaByProvider.claude?.error !== SIGNED_OUT_ERROR) {
|
|
287
|
+
this.lastEmittedClaudeState = null;
|
|
288
|
+
this.emitClaudeState(makeUnavailableClaudeState(SIGNED_OUT_ERROR, 'auth'));
|
|
289
|
+
}
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this.claudeDormant = false;
|
|
293
|
+
await this.refreshPeakHours();
|
|
255
294
|
const creds = await this.readClaudeCredentials();
|
|
256
295
|
if (!creds) {
|
|
257
296
|
this.handleUnavailableState(makeUnavailableClaudeState('Renew your Claude Max OAuth to view quota', 'auth'));
|
|
@@ -289,9 +328,31 @@ class MultiProviderQuotaService {
|
|
|
289
328
|
this.handleTransientFailure(makeUnavailableClaudeState(message));
|
|
290
329
|
}
|
|
291
330
|
finally {
|
|
292
|
-
this.
|
|
331
|
+
this.pollInFlight = false;
|
|
332
|
+
if (this.pendingWake) {
|
|
333
|
+
this.pendingWake = false;
|
|
334
|
+
void this.poll();
|
|
335
|
+
}
|
|
336
|
+
else if (!this.claudeDormant) {
|
|
337
|
+
this.scheduleNextPoll();
|
|
338
|
+
}
|
|
293
339
|
}
|
|
294
340
|
}
|
|
341
|
+
wakeForAccountChange() {
|
|
342
|
+
if (!this.polling)
|
|
343
|
+
return;
|
|
344
|
+
if (this.timer) {
|
|
345
|
+
clearTimeout(this.timer);
|
|
346
|
+
this.timer = undefined;
|
|
347
|
+
}
|
|
348
|
+
this.codexWatcher?.start();
|
|
349
|
+
this.zaiWatcher?.start();
|
|
350
|
+
if (this.pollInFlight) {
|
|
351
|
+
this.pendingWake = true;
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
void this.poll();
|
|
355
|
+
}
|
|
295
356
|
emitClaudeState(state) {
|
|
296
357
|
const withPeakHours = this.currentPeakHours !== undefined ? { ...state, peakHours: this.currentPeakHours } : state;
|
|
297
358
|
const withFailure = {
|
package/dist/node.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { findCodexRolloutFile } from './providers/codex';
|
|
|
15
15
|
export type { FindCodexRolloutFileOptions } from './providers/codex';
|
|
16
16
|
export { readCodexHistory } from './parsers/codexHistory';
|
|
17
17
|
export type { CodexHistoryEntry, ReadCodexHistoryOptions } from './parsers/codexHistory';
|
|
18
|
-
export { listSessionPreviews, readSessionPreview } from './sessionPreviews';
|
|
19
|
-
export type { ListSessionPreviewsOptions, ReadSessionPreviewOptions, SessionPreview, } from './sessionPreviews';
|
|
20
|
-
export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, } from './observedSessionCollector';
|
|
21
|
-
export type { ObservedSessionReference, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
|
|
18
|
+
export { listSessionPreviews, listSessionPreviewsAsync, readSessionPreview, readSessionPreviewAsync, } from './sessionPreviews';
|
|
19
|
+
export type { AsyncSessionPreviewOptions, ListSessionPreviewsAsyncOptions, ListSessionPreviewsOptions, ReadSessionPreviewAsyncOptions, ReadSessionPreviewOptions, SessionPreview, SessionPreviewListResult, SessionPreviewReadResult, } from './sessionPreviews';
|
|
20
|
+
export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
|
|
21
|
+
export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
|
package/dist/node.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* for browser bundles — use `sidekick-shared/browser` there.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreview = exports.listSessionPreviews = exports.readCodexHistory = exports.findCodexRolloutFile = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
|
|
10
|
+
exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.findCodexRolloutFile = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
|
|
11
11
|
var pricingCatalog_1 = require("./pricingCatalog");
|
|
12
12
|
Object.defineProperty(exports, "hydratePricingCatalog", { enumerable: true, get: function () { return pricingCatalog_1.hydratePricingCatalog; } });
|
|
13
13
|
Object.defineProperty(exports, "normalizeLiteLlmCatalog", { enumerable: true, get: function () { return pricingCatalog_1.normalizeLiteLlmCatalog; } });
|
|
@@ -26,8 +26,11 @@ var codexHistory_1 = require("./parsers/codexHistory");
|
|
|
26
26
|
Object.defineProperty(exports, "readCodexHistory", { enumerable: true, get: function () { return codexHistory_1.readCodexHistory; } });
|
|
27
27
|
var sessionPreviews_1 = require("./sessionPreviews");
|
|
28
28
|
Object.defineProperty(exports, "listSessionPreviews", { enumerable: true, get: function () { return sessionPreviews_1.listSessionPreviews; } });
|
|
29
|
+
Object.defineProperty(exports, "listSessionPreviewsAsync", { enumerable: true, get: function () { return sessionPreviews_1.listSessionPreviewsAsync; } });
|
|
29
30
|
Object.defineProperty(exports, "readSessionPreview", { enumerable: true, get: function () { return sessionPreviews_1.readSessionPreview; } });
|
|
31
|
+
Object.defineProperty(exports, "readSessionPreviewAsync", { enumerable: true, get: function () { return sessionPreviews_1.readSessionPreviewAsync; } });
|
|
30
32
|
var observedSessionCollector_1 = require("./observedSessionCollector");
|
|
31
33
|
Object.defineProperty(exports, "ObservedSessionCollector", { enumerable: true, get: function () { return observedSessionCollector_1.ObservedSessionCollector; } });
|
|
32
34
|
Object.defineProperty(exports, "observedSessionSourceFromProvider", { enumerable: true, get: function () { return observedSessionCollector_1.observedSessionSourceFromProvider; } });
|
|
33
35
|
Object.defineProperty(exports, "fileFingerprint", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprint; } });
|
|
36
|
+
Object.defineProperty(exports, "fileFingerprintParts", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprintParts; } });
|