sidekick-shared 0.24.5 → 0.26.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 +92 -0
- package/README.md +205 -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 +170 -0
- package/dist/accountRegistry.d.ts +25 -2
- package/dist/accountRegistry.js +41 -13
- package/dist/accountStatus.d.ts +9 -1
- package/dist/accountStatus.js +3 -3
- package/dist/accounts.d.ts +3 -1
- package/dist/accounts.js +84 -64
- package/dist/aggregation/EventAggregator.d.ts +15 -2
- package/dist/aggregation/EventAggregator.js +54 -9
- package/dist/aggregation/costProvenance.d.ts +14 -0
- package/dist/aggregation/costProvenance.js +35 -0
- package/dist/aggregation/snapshot.d.ts +13 -2
- package/dist/aggregation/snapshot.js +57 -6
- package/dist/aggregation/types.d.ts +30 -1
- package/dist/analytics/compactionLedger.js +15 -5
- package/dist/analytics/qualityScore.js +2 -1
- package/dist/browser.d.ts +19 -4
- package/dist/browser.js +43 -1
- package/dist/codexProfiles.d.ts +3 -1
- package/dist/codexProfiles.js +4 -2
- package/dist/codexQuota.d.ts +2 -0
- package/dist/codexQuota.js +11 -66
- package/dist/codexQuotaWatcher.d.ts +6 -0
- package/dist/codexQuotaWatcher.js +101 -47
- package/dist/failingTools.d.ts +37 -0
- package/dist/failingTools.js +70 -0
- package/dist/formatters/sessionDump.js +13 -7
- package/dist/formatting.d.ts +13 -0
- package/dist/formatting.js +35 -0
- package/dist/historicalStore.d.ts +47 -0
- package/dist/historicalStore.js +312 -0
- package/dist/index.d.ts +67 -23
- package/dist/index.js +138 -26
- 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 +23 -4
- package/dist/node.js +50 -1
- package/dist/observedContextWindows.d.ts +7 -0
- package/dist/observedContextWindows.js +17 -2
- package/dist/observedSessionCollector.d.ts +72 -6
- package/dist/observedSessionCollector.js +440 -47
- package/dist/parsers/codexHistory.d.ts +4 -2
- package/dist/parsers/codexHistory.js +9 -2
- package/dist/parsers/sessionActivityDetector.d.ts +28 -0
- package/dist/parsers/sessionActivityDetector.js +110 -15
- package/dist/parsers/sessionPathResolver.d.ts +11 -0
- package/dist/parsers/sessionPathResolver.js +13 -10
- package/dist/peakHours.d.ts +34 -3
- package/dist/peakHours.js +92 -7
- package/dist/pricingCatalog.d.ts +7 -0
- package/dist/pricingCatalog.js +8 -5
- 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 +211 -131
- package/dist/providers/codex.d.ts +20 -1
- package/dist/providers/codex.js +308 -244
- package/dist/providers/codexDatabase.d.ts +9 -0
- package/dist/providers/codexDatabase.js +107 -2
- package/dist/providers/detect.d.ts +2 -0
- package/dist/providers/detect.js +29 -24
- package/dist/providers/diagnostics.d.ts +13 -0
- package/dist/providers/diagnostics.js +88 -0
- package/dist/providers/factory.d.ts +20 -0
- package/dist/providers/factory.js +57 -0
- package/dist/providers/openCode.d.ts +22 -1
- package/dist/providers/openCode.js +460 -126
- package/dist/providers/openCodeDatabase.d.ts +10 -0
- package/dist/providers/openCodeDatabase.js +69 -0
- package/dist/providers/rolloutWalker.d.ts +53 -0
- package/dist/providers/rolloutWalker.js +209 -0
- package/dist/providers/types.d.ts +82 -2
- package/dist/providers/types.js +4 -0
- package/dist/quota.d.ts +34 -4
- package/dist/quota.js +37 -9
- package/dist/quotaHistory.d.ts +3 -2
- package/dist/quotaHistory.js +36 -35
- package/dist/quotaPoller.d.ts +13 -1
- package/dist/quotaPoller.js +65 -3
- package/dist/quotaResolver.d.ts +81 -0
- package/dist/quotaResolver.js +213 -0
- package/dist/quotaSnapshots.d.ts +15 -2
- package/dist/quotaSnapshots.js +25 -3
- package/dist/quotaThresholds.d.ts +60 -0
- package/dist/quotaThresholds.js +90 -0
- package/dist/report/htmlReportGenerator.js +10 -4
- package/dist/report/sessionReportInputs.d.ts +23 -0
- package/dist/report/sessionReportInputs.js +34 -0
- 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 +3 -0
- package/dist/schemas/index.js +16 -2
- package/dist/schemas/observedSessionV1.d.ts +27 -26
- package/dist/schemas/observedSessionV1.js +6 -4
- package/dist/schemas/quota.d.ts +141 -2
- package/dist/schemas/quota.js +20 -8
- package/dist/schemas/quotaHistory.d.ts +3 -2
- package/dist/schemas/quotaHistory.js +1 -1
- package/dist/schemas/sessionEvent.d.ts +6 -0
- package/dist/schemas/sessionEvent.js +1 -0
- package/dist/schemas/stateFile.d.ts +198 -0
- package/dist/schemas/stateFile.js +77 -0
- package/dist/schemas/tokenEstimation.d.ts +1 -1
- package/dist/schemas/transcript.js +2 -0
- package/dist/sessionFingerprint.d.ts +25 -0
- package/dist/sessionFingerprint.js +46 -0
- package/dist/sessionMonitor.d.ts +15 -0
- package/dist/sessionMonitor.js +142 -0
- package/dist/sessionPreviews.d.ts +33 -2
- package/dist/sessionPreviews.js +333 -6
- package/dist/sessionStats.d.ts +51 -0
- package/dist/sessionStats.js +166 -0
- package/dist/stateFile.d.ts +113 -0
- package/dist/stateFile.js +160 -0
- package/dist/statusline/claudeStatuslinePayload.d.ts +89 -0
- package/dist/statusline/claudeStatuslinePayload.js +152 -0
- package/dist/statusline/formatter.d.ts +13 -0
- package/dist/statusline/formatter.js +48 -6
- package/dist/statusline/index.d.ts +10 -2
- package/dist/statusline/index.js +19 -1
- package/dist/tokenSummary.d.ts +62 -0
- package/dist/tokenSummary.js +72 -0
- package/dist/transcript.d.ts +5 -0
- package/dist/transcript.js +2 -0
- package/dist/types/observedSessionV1.d.ts +8 -2
- package/dist/types/observedSessionV1.js +88 -25
- package/dist/types/sessionEvent.d.ts +2 -0
- package/dist/usage/billingBlocks.d.ts +85 -0
- package/dist/usage/billingBlocks.js +153 -0
- package/dist/usage/importSessionHistory.d.ts +53 -0
- package/dist/usage/importSessionHistory.js +88 -0
- package/dist/usage/usageEvents.d.ts +92 -0
- package/dist/usage/usageEvents.js +322 -0
- package/dist/usage/usageReports.d.ts +76 -0
- package/dist/usage/usageReports.js +208 -0
- package/dist/watchers/factory.d.ts +6 -0
- package/dist/watchers/factory.js +30 -25
- package/dist/zaiQuotaApi.d.ts +2 -0
- package/dist/zaiQuotaApi.js +2 -0
- package/package.json +22 -1
|
@@ -16,6 +16,7 @@ const planExtractor_1 = require("../parsers/planExtractor");
|
|
|
16
16
|
const eventBridge_1 = require("../watchers/eventBridge");
|
|
17
17
|
const toolSummary_1 = require("../formatters/toolSummary");
|
|
18
18
|
const noiseClassifier_1 = require("../formatters/noiseClassifier");
|
|
19
|
+
const costProvenance_1 = require("./costProvenance");
|
|
19
20
|
const FrequencyTracker_1 = require("./FrequencyTracker");
|
|
20
21
|
const HeatmapTracker_1 = require("./HeatmapTracker");
|
|
21
22
|
const PatternExtractor_1 = require("./PatternExtractor");
|
|
@@ -30,7 +31,7 @@ const DEFAULT_BURN_WINDOW_MS = 5 * 60_000;
|
|
|
30
31
|
const DEFAULT_BURN_SAMPLE_MS = 10_000;
|
|
31
32
|
const COMPACTION_DROP_THRESHOLD = 0.8; // >20% drop
|
|
32
33
|
/** Schema version for serialized snapshots. */
|
|
33
|
-
exports.SNAPSHOT_SCHEMA_VERSION =
|
|
34
|
+
exports.SNAPSHOT_SCHEMA_VERSION = 5;
|
|
34
35
|
// ── Goal gate detection regex ──
|
|
35
36
|
const GOAL_GATE_REGEX = /\b(CRITICAL|MUST|blocker|required|must.?complete|goal.?gate|essential|do.?not.?skip|blocking)\b/i;
|
|
36
37
|
// ── Todo dependency parsing ──
|
|
@@ -78,7 +79,13 @@ class EventAggregator {
|
|
|
78
79
|
cacheReadTokens = 0;
|
|
79
80
|
reasoningTokens = 0;
|
|
80
81
|
totalTokens = 0;
|
|
81
|
-
|
|
82
|
+
/** Running cost in USD (reported + estimated). */
|
|
83
|
+
costUsd = 0;
|
|
84
|
+
reportedCostUsd = 0;
|
|
85
|
+
estimatedCostUsd = 0;
|
|
86
|
+
reportedCalls = 0;
|
|
87
|
+
estimatedCalls = 0;
|
|
88
|
+
unpricedCalls = 0;
|
|
82
89
|
// Per-model usage
|
|
83
90
|
modelUsage = new Map();
|
|
84
91
|
// Context size tracking
|
|
@@ -262,8 +269,10 @@ class EventAggregator {
|
|
|
262
269
|
this.attributePlanUsage(normalized.totalTokens, cost);
|
|
263
270
|
}
|
|
264
271
|
else if (typeof event.cost === 'number' && Number.isFinite(event.cost) && event.cost >= 0) {
|
|
265
|
-
// Compatibility for cost-only follow events.
|
|
266
|
-
this.
|
|
272
|
+
// Compatibility for cost-only follow events (provider-reported by definition).
|
|
273
|
+
this.costUsd += event.cost;
|
|
274
|
+
this.reportedCostUsd += event.cost;
|
|
275
|
+
this.reportedCalls += 1;
|
|
267
276
|
}
|
|
268
277
|
// 4. Tool tracking from FollowEvent
|
|
269
278
|
if (event.type === 'tool_use' && event.toolName) {
|
|
@@ -309,7 +318,16 @@ class EventAggregator {
|
|
|
309
318
|
cacheReadTokens: this.cacheReadTokens,
|
|
310
319
|
reasoningTokens: this.reasoningTokens,
|
|
311
320
|
totalTokens: this.totalTokens,
|
|
312
|
-
|
|
321
|
+
costUsd: this.costUsd,
|
|
322
|
+
reportedCostUsd: this.reportedCostUsd,
|
|
323
|
+
estimatedCostUsd: this.estimatedCostUsd,
|
|
324
|
+
unpricedCalls: this.unpricedCalls,
|
|
325
|
+
costProvenance: (0, costProvenance_1.classifyCostProvenance)({
|
|
326
|
+
reportedCalls: this.reportedCalls,
|
|
327
|
+
estimatedCalls: this.estimatedCalls,
|
|
328
|
+
unpricedCalls: this.unpricedCalls,
|
|
329
|
+
}),
|
|
330
|
+
reportedCost: this.costUsd,
|
|
313
331
|
};
|
|
314
332
|
}
|
|
315
333
|
getModelStats() {
|
|
@@ -427,7 +445,12 @@ class EventAggregator {
|
|
|
427
445
|
this.cacheReadTokens = 0;
|
|
428
446
|
this.reasoningTokens = 0;
|
|
429
447
|
this.totalTokens = 0;
|
|
430
|
-
this.
|
|
448
|
+
this.costUsd = 0;
|
|
449
|
+
this.reportedCostUsd = 0;
|
|
450
|
+
this.estimatedCostUsd = 0;
|
|
451
|
+
this.reportedCalls = 0;
|
|
452
|
+
this.estimatedCalls = 0;
|
|
453
|
+
this.unpricedCalls = 0;
|
|
431
454
|
this.modelUsage.clear();
|
|
432
455
|
this.currentContextSize = 0;
|
|
433
456
|
this.previousContextSize = 0;
|
|
@@ -503,7 +526,13 @@ class EventAggregator {
|
|
|
503
526
|
cacheRead: this.cacheReadTokens,
|
|
504
527
|
reasoning: this.reasoningTokens,
|
|
505
528
|
total: this.totalTokens,
|
|
506
|
-
reportedCost: this.
|
|
529
|
+
reportedCost: this.costUsd,
|
|
530
|
+
costUsd: this.costUsd,
|
|
531
|
+
reportedCostUsd: this.reportedCostUsd,
|
|
532
|
+
estimatedCostUsd: this.estimatedCostUsd,
|
|
533
|
+
reportedCalls: this.reportedCalls,
|
|
534
|
+
estimatedCalls: this.estimatedCalls,
|
|
535
|
+
unpricedCalls: this.unpricedCalls,
|
|
507
536
|
},
|
|
508
537
|
modelUsage: Array.from(this.modelUsage.entries()),
|
|
509
538
|
contextSize: this.currentContextSize,
|
|
@@ -550,7 +579,12 @@ class EventAggregator {
|
|
|
550
579
|
this.cacheReadTokens = state.tokens.cacheRead;
|
|
551
580
|
this.reasoningTokens = state.tokens.reasoning;
|
|
552
581
|
this.totalTokens = state.tokens.total;
|
|
553
|
-
this.
|
|
582
|
+
this.costUsd = state.tokens.costUsd;
|
|
583
|
+
this.reportedCostUsd = state.tokens.reportedCostUsd;
|
|
584
|
+
this.estimatedCostUsd = state.tokens.estimatedCostUsd;
|
|
585
|
+
this.reportedCalls = state.tokens.reportedCalls;
|
|
586
|
+
this.estimatedCalls = state.tokens.estimatedCalls;
|
|
587
|
+
this.unpricedCalls = state.tokens.unpricedCalls;
|
|
554
588
|
this.modelUsage = new Map(state.modelUsage);
|
|
555
589
|
this.currentContextSize = state.contextSize;
|
|
556
590
|
this.previousContextSize = state.previousContextSize;
|
|
@@ -619,7 +653,18 @@ class EventAggregator {
|
|
|
619
653
|
this.cacheReadTokens += cacheRead;
|
|
620
654
|
this.reasoningTokens += reasoningTok;
|
|
621
655
|
this.totalTokens += usage.totalTokens;
|
|
622
|
-
this.
|
|
656
|
+
this.costUsd += cost;
|
|
657
|
+
if (pricedUsage.source === 'provider-reported') {
|
|
658
|
+
this.reportedCostUsd += cost;
|
|
659
|
+
this.reportedCalls += 1;
|
|
660
|
+
}
|
|
661
|
+
else if (pricedUsage.source === 'unpriced') {
|
|
662
|
+
this.unpricedCalls += 1;
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
this.estimatedCostUsd += cost;
|
|
666
|
+
this.estimatedCalls += 1;
|
|
667
|
+
}
|
|
623
668
|
// Burn rate sample accumulation
|
|
624
669
|
this.tokensSinceLastSample += usage.totalTokens;
|
|
625
670
|
// Context size computation
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AggregatedCostProvenance, AggregatedTokens } from './types';
|
|
2
|
+
/** The fields `describeCostProvenance` reads; any `AggregatedTokens` qualifies. */
|
|
3
|
+
export type AggregatedCostProvenanceInput = Pick<AggregatedTokens, 'costProvenance' | 'unpricedCalls'>;
|
|
4
|
+
/**
|
|
5
|
+
* Human-readable qualifier for an aggregate cost, for report footers and
|
|
6
|
+
* table cells. Empty when there is nothing to qualify.
|
|
7
|
+
*/
|
|
8
|
+
export declare function describeCostProvenance(tokens: AggregatedCostProvenanceInput): string;
|
|
9
|
+
/** Classify a cost breakdown by how many events fell into each bucket. */
|
|
10
|
+
export declare function classifyCostProvenance(counts: {
|
|
11
|
+
reportedCalls: number;
|
|
12
|
+
estimatedCalls: number;
|
|
13
|
+
unpricedCalls: number;
|
|
14
|
+
}): AggregatedCostProvenance;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeCostProvenance = describeCostProvenance;
|
|
4
|
+
exports.classifyCostProvenance = classifyCostProvenance;
|
|
5
|
+
const PROVENANCE_LABELS = {
|
|
6
|
+
reported: 'provider-reported',
|
|
7
|
+
estimated: 'estimated from catalog pricing',
|
|
8
|
+
mixed: 'partly provider-reported, partly estimated',
|
|
9
|
+
unpriced: 'unpriced',
|
|
10
|
+
none: '',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Human-readable qualifier for an aggregate cost, for report footers and
|
|
14
|
+
* table cells. Empty when there is nothing to qualify.
|
|
15
|
+
*/
|
|
16
|
+
function describeCostProvenance(tokens) {
|
|
17
|
+
const base = PROVENANCE_LABELS[tokens.costProvenance] ?? '';
|
|
18
|
+
const unpriced = tokens.unpricedCalls > 0
|
|
19
|
+
? `${tokens.unpricedCalls} unpriced call${tokens.unpricedCalls === 1 ? '' : 's'}`
|
|
20
|
+
: '';
|
|
21
|
+
if (base && unpriced)
|
|
22
|
+
return `${base} · ${unpriced}`;
|
|
23
|
+
return base || unpriced;
|
|
24
|
+
}
|
|
25
|
+
/** Classify a cost breakdown by how many events fell into each bucket. */
|
|
26
|
+
function classifyCostProvenance(counts) {
|
|
27
|
+
const { reportedCalls, estimatedCalls, unpricedCalls } = counts;
|
|
28
|
+
if (reportedCalls > 0 && estimatedCalls > 0)
|
|
29
|
+
return 'mixed';
|
|
30
|
+
if (reportedCalls > 0)
|
|
31
|
+
return 'reported';
|
|
32
|
+
if (estimatedCalls > 0)
|
|
33
|
+
return 'estimated';
|
|
34
|
+
return unpricedCalls > 0 ? 'unpriced' : 'none';
|
|
35
|
+
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @module aggregation/snapshot
|
|
9
9
|
*/
|
|
10
10
|
import { type SerializedAggregatorState } from './EventAggregator';
|
|
11
|
+
/** Newest snapshots kept on disk; older ones are pruned opportunistically. */
|
|
12
|
+
export declare const MAX_SNAPSHOT_FILES = 200;
|
|
11
13
|
/** Snapshot sidecar file content. */
|
|
12
14
|
export interface SessionSnapshot {
|
|
13
15
|
/** Schema version for forward-compatibility checks. */
|
|
@@ -32,10 +34,19 @@ export declare function getSnapshotPath(sessionId: string): string;
|
|
|
32
34
|
/**
|
|
33
35
|
* Saves a session snapshot to disk.
|
|
34
36
|
*
|
|
35
|
-
* Creates the snapshots directory if it doesn't exist.
|
|
36
|
-
*
|
|
37
|
+
* Creates the snapshots directory if it doesn't exist. Uses the shared
|
|
38
|
+
* fsynced atomic writer with a per-process temp name, so the CLI dashboard and
|
|
39
|
+
* the extension host snapshotting the same session cannot collide on a shared
|
|
40
|
+
* `.tmp` file. Every {@link PRUNE_EVERY_N_SAVES} saves the directory is
|
|
41
|
+
* trimmed to the newest {@link MAX_SNAPSHOT_FILES}; snapshots are caches, so
|
|
42
|
+
* dropping an old one only costs a replay.
|
|
37
43
|
*/
|
|
38
44
|
export declare function saveSnapshot(snapshot: SessionSnapshot): void;
|
|
45
|
+
/**
|
|
46
|
+
* Deletes all but the newest `keep` snapshot files (by modification time).
|
|
47
|
+
* Returns how many files were removed. Best-effort; never throws.
|
|
48
|
+
*/
|
|
49
|
+
export declare function pruneSnapshots(keep?: number): number;
|
|
39
50
|
/**
|
|
40
51
|
* Loads a session snapshot from disk if it exists and is valid.
|
|
41
52
|
*
|
|
@@ -42,17 +42,25 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
42
42
|
};
|
|
43
43
|
})();
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.MAX_SNAPSHOT_FILES = void 0;
|
|
45
46
|
exports.getSnapshotPath = getSnapshotPath;
|
|
46
47
|
exports.saveSnapshot = saveSnapshot;
|
|
48
|
+
exports.pruneSnapshots = pruneSnapshots;
|
|
47
49
|
exports.loadSnapshot = loadSnapshot;
|
|
48
50
|
exports.deleteSnapshot = deleteSnapshot;
|
|
49
51
|
exports.isSnapshotValid = isSnapshotValid;
|
|
50
52
|
const fs = __importStar(require("fs"));
|
|
51
53
|
const path = __importStar(require("path"));
|
|
52
54
|
const paths_1 = require("../paths");
|
|
55
|
+
const atomic_1 = require("../writers/atomic");
|
|
53
56
|
const EventAggregator_1 = require("./EventAggregator");
|
|
54
57
|
/** Current schema version — bump when format changes. */
|
|
55
58
|
const SNAPSHOT_VERSION = EventAggregator_1.SNAPSHOT_SCHEMA_VERSION;
|
|
59
|
+
/** Newest snapshots kept on disk; older ones are pruned opportunistically. */
|
|
60
|
+
exports.MAX_SNAPSHOT_FILES = 200;
|
|
61
|
+
/** Prune runs once per this many saves, so steady-state writes stay one file each. */
|
|
62
|
+
const PRUNE_EVERY_N_SAVES = 25;
|
|
63
|
+
let savesSincePrune = 0;
|
|
56
64
|
/** Returns the directory for snapshot files. */
|
|
57
65
|
function getSnapshotsDir() {
|
|
58
66
|
return path.join((0, paths_1.getConfigDir)(), 'snapshots');
|
|
@@ -66,8 +74,12 @@ function getSnapshotPath(sessionId) {
|
|
|
66
74
|
/**
|
|
67
75
|
* Saves a session snapshot to disk.
|
|
68
76
|
*
|
|
69
|
-
* Creates the snapshots directory if it doesn't exist.
|
|
70
|
-
*
|
|
77
|
+
* Creates the snapshots directory if it doesn't exist. Uses the shared
|
|
78
|
+
* fsynced atomic writer with a per-process temp name, so the CLI dashboard and
|
|
79
|
+
* the extension host snapshotting the same session cannot collide on a shared
|
|
80
|
+
* `.tmp` file. Every {@link PRUNE_EVERY_N_SAVES} saves the directory is
|
|
81
|
+
* trimmed to the newest {@link MAX_SNAPSHOT_FILES}; snapshots are caches, so
|
|
82
|
+
* dropping an old one only costs a replay.
|
|
71
83
|
*/
|
|
72
84
|
function saveSnapshot(snapshot) {
|
|
73
85
|
try {
|
|
@@ -75,15 +87,54 @@ function saveSnapshot(snapshot) {
|
|
|
75
87
|
if (!fs.existsSync(dir)) {
|
|
76
88
|
fs.mkdirSync(dir, { recursive: true });
|
|
77
89
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
(0, atomic_1.atomicWriteJsonSync)(getSnapshotPath(snapshot.sessionId), snapshot);
|
|
91
|
+
savesSincePrune += 1;
|
|
92
|
+
if (savesSincePrune >= PRUNE_EVERY_N_SAVES) {
|
|
93
|
+
savesSincePrune = 0;
|
|
94
|
+
pruneSnapshots(exports.MAX_SNAPSHOT_FILES);
|
|
95
|
+
}
|
|
82
96
|
}
|
|
83
97
|
catch {
|
|
84
98
|
// Non-critical — snapshot failure should never break session monitoring
|
|
85
99
|
}
|
|
86
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Deletes all but the newest `keep` snapshot files (by modification time).
|
|
103
|
+
* Returns how many files were removed. Best-effort; never throws.
|
|
104
|
+
*/
|
|
105
|
+
function pruneSnapshots(keep = exports.MAX_SNAPSHOT_FILES) {
|
|
106
|
+
try {
|
|
107
|
+
const dir = getSnapshotsDir();
|
|
108
|
+
const entries = fs
|
|
109
|
+
.readdirSync(dir)
|
|
110
|
+
.filter((name) => name.endsWith('.json'))
|
|
111
|
+
.map((name) => {
|
|
112
|
+
const filePath = path.join(dir, name);
|
|
113
|
+
try {
|
|
114
|
+
return { filePath, mtimeMs: fs.statSync(filePath).mtimeMs };
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
.filter((entry) => entry !== null)
|
|
121
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
122
|
+
let removed = 0;
|
|
123
|
+
for (const entry of entries.slice(Math.max(0, keep))) {
|
|
124
|
+
try {
|
|
125
|
+
fs.unlinkSync(entry.filePath);
|
|
126
|
+
removed += 1;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Already gone or locked; skip.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return removed;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
87
138
|
/**
|
|
88
139
|
* Loads a session snapshot from disk if it exists and is valid.
|
|
89
140
|
*
|
|
@@ -50,7 +50,17 @@ export interface EventAggregatorOptions {
|
|
|
50
50
|
/** Read a plan file from disk (fallback when Edit tool is used instead of Write). */
|
|
51
51
|
readPlanFile?: (path: string) => string | null;
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* How an aggregate cost figure was produced.
|
|
55
|
+
*
|
|
56
|
+
* - `reported` — every priced event carried a provider-reported cost.
|
|
57
|
+
* - `estimated` — every priced event was priced from the model catalog.
|
|
58
|
+
* - `mixed` — some events reported, some estimated.
|
|
59
|
+
* - `unpriced` — no event could be priced at all.
|
|
60
|
+
* - `none` — no usage events yet.
|
|
61
|
+
*/
|
|
62
|
+
export type AggregatedCostProvenance = 'reported' | 'estimated' | 'mixed' | 'unpriced' | 'none';
|
|
63
|
+
/** Token accumulation totals (aggregation-specific, includes cost). */
|
|
54
64
|
export interface AggregatedTokens {
|
|
55
65
|
inputTokens: number;
|
|
56
66
|
outputTokens: number;
|
|
@@ -59,6 +69,25 @@ export interface AggregatedTokens {
|
|
|
59
69
|
reasoningTokens: number;
|
|
60
70
|
/** Overall total after applying provider reasoning-in-output semantics. */
|
|
61
71
|
totalTokens: number;
|
|
72
|
+
/**
|
|
73
|
+
* Cost in USD for the priced portion of the session. Read `costProvenance`
|
|
74
|
+
* before labelling it: only `'reported'` came from the provider; anything
|
|
75
|
+
* else includes Sidekick's own catalog estimate.
|
|
76
|
+
*/
|
|
77
|
+
costUsd: number;
|
|
78
|
+
/** Portion of `costUsd` the provider reported itself. */
|
|
79
|
+
reportedCostUsd: number;
|
|
80
|
+
/** Portion of `costUsd` Sidekick estimated from catalog pricing. */
|
|
81
|
+
estimatedCostUsd: number;
|
|
82
|
+
/** Usage events that had neither a reported cost nor a catalog price. */
|
|
83
|
+
unpricedCalls: number;
|
|
84
|
+
/** Classification of `costUsd`. */
|
|
85
|
+
costProvenance: AggregatedCostProvenance;
|
|
86
|
+
/**
|
|
87
|
+
* @deprecated Same value as `costUsd`. Despite the name it has always mixed
|
|
88
|
+
* catalog estimates with provider-reported figures; use `costUsd` together
|
|
89
|
+
* with `costProvenance`.
|
|
90
|
+
*/
|
|
62
91
|
reportedCost: number;
|
|
63
92
|
}
|
|
64
93
|
/** Per-model usage breakdown. */
|
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.calculateCompactionLedger = calculateCompactionLedger;
|
|
4
4
|
exports.formatCompactionLedger = formatCompactionLedger;
|
|
5
|
-
const
|
|
5
|
+
const usageNormalization_1 = require("../usageNormalization");
|
|
6
6
|
function calculateCompactionLedger(events, model) {
|
|
7
7
|
const tokensEvicted = events.reduce((sum, event) => sum + Math.max(0, event.tokensReclaimed), 0);
|
|
8
8
|
const reportedCount = events.filter((event) => event.source === 'reported').length;
|
|
9
9
|
const heuristicCount = events.length - reportedCount;
|
|
10
|
-
|
|
10
|
+
// Re-establishing evicted context means sending it again as uncached input.
|
|
11
|
+
// Price it through the same normalized path every other cost figure uses so
|
|
12
|
+
// the ledger can never disagree with the session total on the same tokens.
|
|
13
|
+
const reestablishment = model
|
|
14
|
+
? (0, usageNormalization_1.calculateNormalizedUsageCost)({
|
|
15
|
+
usage: (0, usageNormalization_1.normalizeProviderUsage)({
|
|
16
|
+
semantics: 'sidekick',
|
|
17
|
+
inputTokens: tokensEvicted,
|
|
18
|
+
reasoningIncludedInOutput: true,
|
|
19
|
+
}),
|
|
20
|
+
modelId: model,
|
|
21
|
+
})
|
|
22
|
+
: null;
|
|
11
23
|
return {
|
|
12
24
|
count: events.length,
|
|
13
25
|
tokensEvicted,
|
|
14
|
-
reestablishmentCostUsd:
|
|
15
|
-
? (0, modelInfo_1.calculateCostWithPricing)({ inputTokens: tokensEvicted, outputTokens: 0, cacheWriteTokens: 0, cacheReadTokens: 0 }, pricing)
|
|
16
|
-
: null,
|
|
26
|
+
reestablishmentCostUsd: reestablishment?.costUsd ?? null,
|
|
17
27
|
source: reportedCount > 0 && heuristicCount > 0
|
|
18
28
|
? 'mixed'
|
|
19
29
|
: reportedCount > 0
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.scoreSessionQuality = scoreSessionQuality;
|
|
4
4
|
exports.calculateQualityTrend = calculateQualityTrend;
|
|
5
|
+
const tokenSummary_1 = require("../tokenSummary");
|
|
5
6
|
function awarded(maximum, ratio) {
|
|
6
7
|
return Math.round(maximum * Math.max(0, Math.min(1, ratio)) * 10) / 10;
|
|
7
8
|
}
|
|
@@ -10,7 +11,7 @@ function scoreSessionQuality(metrics) {
|
|
|
10
11
|
const latencyRatio = latencyMs > 0 ? 1 - Math.min(1, latencyMs / 15_000) : 1;
|
|
11
12
|
const completedCalls = metrics.toolStats.reduce((sum, tool) => sum + tool.completedCount, 0);
|
|
12
13
|
const errorRate = completedCalls > 0 ? metrics.errorRollup.totalFailures / completedCalls : 0;
|
|
13
|
-
const contextTokens = Math.max(1,
|
|
14
|
+
const contextTokens = Math.max(1, (0, tokenSummary_1.summarizeTokens)(metrics.tokens).context);
|
|
14
15
|
const evicted = metrics.compactionEvents.reduce((sum, event) => sum + event.tokensReclaimed, 0);
|
|
15
16
|
const contextRatio = 1 - Math.min(1, evicted / contextTokens);
|
|
16
17
|
const start = metrics.sessionStartTime ? Date.parse(metrics.sessionStartTime) : NaN;
|
package/dist/browser.d.ts
CHANGED
|
@@ -7,20 +7,35 @@
|
|
|
7
7
|
*
|
|
8
8
|
* For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
|
|
9
9
|
*/
|
|
10
|
-
export { getModelContextWindowSize, DEFAULT_CONTEXT_WINDOW } from './modelContext';
|
|
10
|
+
export { getModelContextWindowSize, resolveModelContextWindow, DEFAULT_CONTEXT_WINDOW, } from './modelContext';
|
|
11
|
+
export type { ModelCatalogMatch, ModelContextWindowProvenance, ModelContextWindowSource, ResolvedModelContextWindow, } from './modelContext';
|
|
11
12
|
export { normalizeProviderUsage, extractNormalizedUsage, calculateNormalizedUsageCost, } from './usageNormalization';
|
|
12
13
|
export type { UsageProvider, UsageSemantics, UsageNormalizationProvenance, ProviderUsageInput, AnthropicUsageInput, OpenAIUsageInput, SidekickUsageInput, NormalizedUsage, PricingProvenance, NormalizedUsageCostInput, NormalizedUsageCost, } from './usageNormalization';
|
|
14
|
+
export { summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
|
|
15
|
+
export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
|
|
13
16
|
export { estimateTextTokens, estimateSerializedTokens } from './tokenEstimation';
|
|
14
17
|
export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
|
|
15
18
|
export { projectSessionTranscript } from './transcript';
|
|
16
19
|
export type { TranscriptFidelity, TranscriptSourceProvenance, CanonicalTranscriptBlock, CanonicalTranscriptMessage, CanonicalToolCall, CanonicalTranscriptUsageTotals, CanonicalSessionTranscript, ProjectSessionTranscriptOptions, } from './transcript';
|
|
17
|
-
export { formatDurationMs, formatTokenCount } from './formatting';
|
|
20
|
+
export { addLocalDays, formatDurationMs, formatLocalDateKey, formatTokenCount, parseLocalDateKey, } from './formatting';
|
|
18
21
|
export type { FormatDurationMsOptions, FormatTokenCountOptions } from './formatting';
|
|
19
22
|
export { parseMcpToolName } from './parsers/mcpToolName';
|
|
20
23
|
export type { McpToolNameParts } from './parsers/mcpToolName';
|
|
21
24
|
export { buildSessionContextSnapshot, calculateSessionContextPressure, createSessionContextProjector, } from './context/sessionContext';
|
|
25
|
+
export { ACCOUNT_PROVIDER_IDS, MODEL_PROVIDER_IDS, QUOTA_PROVIDER_IDS, RUNTIME_QUOTA_PROVIDER_IDS, SESSION_PROVIDER_IDS, } from './providerIds';
|
|
26
|
+
export type { AccountProviderId, ModelProviderId, QuotaProviderId, RuntimeQuotaProviderId, SessionProviderId, } from './providerIds';
|
|
22
27
|
export type { BuildSessionContextSnapshotOptions, SessionContextCapabilities, SessionContextLayerBreakdown, SessionContextPressure, SessionContextProjector, SessionContextSnapshot, SessionContextSource, SessionContextSourceType, } from './context/sessionContext';
|
|
23
28
|
export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
|
|
24
29
|
export type { AssistantTurnEvent, AssistantTurnEventType, AssistantTurnProcess, AssistantTurnProcessStep, AssistantTurnProjection, AssistantTurnSubagent, AssistantTurnSubagentStatus, AssistantTurnTimelineItem, AssistantTurnToolRef, ExtractTurnSubagentsOptions, ReasoningSummary, SegmentAssistantTurnOptions, } from './turns/assistantTurn';
|
|
25
|
-
export { parseModelId, getModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, } from './modelInfo';
|
|
26
|
-
export type { ModelPricing, CostTokenUsage, CostSource, CostProvenanceInput, CostWithProvenance, ModelProvider, ParsedModelId, ModelInfo, ModelDisplayInfo, } from './modelInfo';
|
|
30
|
+
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, } from './modelInfo';
|
|
31
|
+
export type { ModelPricing, CostTokenUsage, CostSource, CostProvenanceInput, CostWithProvenance, ModelProvider, ParsedModelId, ModelInfo, ModelDisplayInfo, ModelPricingMatch, ModelPricingProvenance, ModelPricingSource, ResolvedModelPricing, } from './modelInfo';
|
|
32
|
+
export { exportResolvedModelCatalog, importResolvedModelCatalog, registerModelAlias, resolveModelAlias, RESOLVED_MODEL_CATALOG_SCHEMA_VERSION, } from './modelCatalog';
|
|
33
|
+
export type { ImportResolvedModelCatalogResult, ResolvedModelCatalogEntry, ResolvedModelCatalogSnapshot, } from './modelCatalog';
|
|
34
|
+
export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock, } from './usage/billingBlocks';
|
|
35
|
+
export type { BillingBlock, BillingBlockInput, BillingBlockModelUsage, BillingBlockTokens, ComputeBillingBlocksOptions, } from './usage/billingBlocks';
|
|
36
|
+
export { bucketUsage, summarizeUsageRows, usageBucketKey, weekKey } from './usage/usageReports';
|
|
37
|
+
export type { BucketUsageOptions, UsageBucketRow, UsageGranularity, UsageGroupDimension, UsageTotals, } from './usage/usageReports';
|
|
38
|
+
export { applySessionSummary, isFileImported, markFileImported, removeSessionSummary, sessionSummaryFromStats, } from './historicalStore';
|
|
39
|
+
export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
|
|
40
|
+
export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
|
|
41
|
+
export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';
|
package/dist/browser.js
CHANGED
|
@@ -9,28 +9,44 @@
|
|
|
9
9
|
* For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.formatTokenCount = exports.formatDurationMs = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = void 0;
|
|
12
|
+
exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
|
|
13
|
+
exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = void 0;
|
|
13
14
|
var modelContext_1 = require("./modelContext");
|
|
14
15
|
Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
|
|
16
|
+
Object.defineProperty(exports, "resolveModelContextWindow", { enumerable: true, get: function () { return modelContext_1.resolveModelContextWindow; } });
|
|
15
17
|
Object.defineProperty(exports, "DEFAULT_CONTEXT_WINDOW", { enumerable: true, get: function () { return modelContext_1.DEFAULT_CONTEXT_WINDOW; } });
|
|
16
18
|
var usageNormalization_1 = require("./usageNormalization");
|
|
17
19
|
Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
|
|
18
20
|
Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
|
|
19
21
|
Object.defineProperty(exports, "calculateNormalizedUsageCost", { enumerable: true, get: function () { return usageNormalization_1.calculateNormalizedUsageCost; } });
|
|
22
|
+
var tokenSummary_1 = require("./tokenSummary");
|
|
23
|
+
Object.defineProperty(exports, "summarizeTokens", { enumerable: true, get: function () { return tokenSummary_1.summarizeTokens; } });
|
|
24
|
+
Object.defineProperty(exports, "sumTokenTotals", { enumerable: true, get: function () { return tokenSummary_1.sumTokenTotals; } });
|
|
25
|
+
Object.defineProperty(exports, "TOKEN_CONTEXT_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_CONTEXT_LABEL; } });
|
|
26
|
+
Object.defineProperty(exports, "TOKEN_TOTAL_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_TOTAL_LABEL; } });
|
|
20
27
|
var tokenEstimation_1 = require("./tokenEstimation");
|
|
21
28
|
Object.defineProperty(exports, "estimateTextTokens", { enumerable: true, get: function () { return tokenEstimation_1.estimateTextTokens; } });
|
|
22
29
|
Object.defineProperty(exports, "estimateSerializedTokens", { enumerable: true, get: function () { return tokenEstimation_1.estimateSerializedTokens; } });
|
|
23
30
|
var transcript_1 = require("./transcript");
|
|
24
31
|
Object.defineProperty(exports, "projectSessionTranscript", { enumerable: true, get: function () { return transcript_1.projectSessionTranscript; } });
|
|
25
32
|
var formatting_1 = require("./formatting");
|
|
33
|
+
Object.defineProperty(exports, "addLocalDays", { enumerable: true, get: function () { return formatting_1.addLocalDays; } });
|
|
26
34
|
Object.defineProperty(exports, "formatDurationMs", { enumerable: true, get: function () { return formatting_1.formatDurationMs; } });
|
|
35
|
+
Object.defineProperty(exports, "formatLocalDateKey", { enumerable: true, get: function () { return formatting_1.formatLocalDateKey; } });
|
|
27
36
|
Object.defineProperty(exports, "formatTokenCount", { enumerable: true, get: function () { return formatting_1.formatTokenCount; } });
|
|
37
|
+
Object.defineProperty(exports, "parseLocalDateKey", { enumerable: true, get: function () { return formatting_1.parseLocalDateKey; } });
|
|
28
38
|
var mcpToolName_1 = require("./parsers/mcpToolName");
|
|
29
39
|
Object.defineProperty(exports, "parseMcpToolName", { enumerable: true, get: function () { return mcpToolName_1.parseMcpToolName; } });
|
|
30
40
|
var sessionContext_1 = require("./context/sessionContext");
|
|
31
41
|
Object.defineProperty(exports, "buildSessionContextSnapshot", { enumerable: true, get: function () { return sessionContext_1.buildSessionContextSnapshot; } });
|
|
32
42
|
Object.defineProperty(exports, "calculateSessionContextPressure", { enumerable: true, get: function () { return sessionContext_1.calculateSessionContextPressure; } });
|
|
33
43
|
Object.defineProperty(exports, "createSessionContextProjector", { enumerable: true, get: function () { return sessionContext_1.createSessionContextProjector; } });
|
|
44
|
+
var providerIds_1 = require("./providerIds");
|
|
45
|
+
Object.defineProperty(exports, "ACCOUNT_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.ACCOUNT_PROVIDER_IDS; } });
|
|
46
|
+
Object.defineProperty(exports, "MODEL_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.MODEL_PROVIDER_IDS; } });
|
|
47
|
+
Object.defineProperty(exports, "QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.QUOTA_PROVIDER_IDS; } });
|
|
48
|
+
Object.defineProperty(exports, "RUNTIME_QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.RUNTIME_QUOTA_PROVIDER_IDS; } });
|
|
49
|
+
Object.defineProperty(exports, "SESSION_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.SESSION_PROVIDER_IDS; } });
|
|
34
50
|
var assistantTurn_1 = require("./turns/assistantTurn");
|
|
35
51
|
Object.defineProperty(exports, "assistantTurnEventsFromSessionEvents", { enumerable: true, get: function () { return assistantTurn_1.assistantTurnEventsFromSessionEvents; } });
|
|
36
52
|
Object.defineProperty(exports, "extractTurnSubagents", { enumerable: true, get: function () { return assistantTurn_1.extractTurnSubagents; } });
|
|
@@ -40,6 +56,7 @@ Object.defineProperty(exports, "segmentAssistantTurn", { enumerable: true, get:
|
|
|
40
56
|
var modelInfo_1 = require("./modelInfo");
|
|
41
57
|
Object.defineProperty(exports, "parseModelId", { enumerable: true, get: function () { return modelInfo_1.parseModelId; } });
|
|
42
58
|
Object.defineProperty(exports, "getModelPricing", { enumerable: true, get: function () { return modelInfo_1.getModelPricing; } });
|
|
59
|
+
Object.defineProperty(exports, "resolveModelPricing", { enumerable: true, get: function () { return modelInfo_1.resolveModelPricing; } });
|
|
43
60
|
Object.defineProperty(exports, "getModelInfo", { enumerable: true, get: function () { return modelInfo_1.getModelInfo; } });
|
|
44
61
|
Object.defineProperty(exports, "calculateCost", { enumerable: true, get: function () { return modelInfo_1.calculateCost; } });
|
|
45
62
|
Object.defineProperty(exports, "calculateCostWithPricing", { enumerable: true, get: function () { return modelInfo_1.calculateCostWithPricing; } });
|
|
@@ -50,3 +67,28 @@ Object.defineProperty(exports, "getModelDisplayInfo", { enumerable: true, get: f
|
|
|
50
67
|
Object.defineProperty(exports, "compareModelIds", { enumerable: true, get: function () { return modelInfo_1.compareModelIds; } });
|
|
51
68
|
Object.defineProperty(exports, "sortModelIds", { enumerable: true, get: function () { return modelInfo_1.sortModelIds; } });
|
|
52
69
|
Object.defineProperty(exports, "formatCost", { enumerable: true, get: function () { return modelInfo_1.formatCost; } });
|
|
70
|
+
var modelCatalog_1 = require("./modelCatalog");
|
|
71
|
+
Object.defineProperty(exports, "exportResolvedModelCatalog", { enumerable: true, get: function () { return modelCatalog_1.exportResolvedModelCatalog; } });
|
|
72
|
+
Object.defineProperty(exports, "importResolvedModelCatalog", { enumerable: true, get: function () { return modelCatalog_1.importResolvedModelCatalog; } });
|
|
73
|
+
Object.defineProperty(exports, "registerModelAlias", { enumerable: true, get: function () { return modelCatalog_1.registerModelAlias; } });
|
|
74
|
+
Object.defineProperty(exports, "resolveModelAlias", { enumerable: true, get: function () { return modelCatalog_1.resolveModelAlias; } });
|
|
75
|
+
Object.defineProperty(exports, "RESOLVED_MODEL_CATALOG_SCHEMA_VERSION", { enumerable: true, get: function () { return modelCatalog_1.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION; } });
|
|
76
|
+
var billingBlocks_1 = require("./usage/billingBlocks");
|
|
77
|
+
Object.defineProperty(exports, "BILLING_BLOCK_DURATION_MS", { enumerable: true, get: function () { return billingBlocks_1.BILLING_BLOCK_DURATION_MS; } });
|
|
78
|
+
Object.defineProperty(exports, "computeBillingBlocks", { enumerable: true, get: function () { return billingBlocks_1.computeBillingBlocks; } });
|
|
79
|
+
Object.defineProperty(exports, "findActiveBillingBlock", { enumerable: true, get: function () { return billingBlocks_1.findActiveBillingBlock; } });
|
|
80
|
+
var usageReports_1 = require("./usage/usageReports");
|
|
81
|
+
Object.defineProperty(exports, "bucketUsage", { enumerable: true, get: function () { return usageReports_1.bucketUsage; } });
|
|
82
|
+
Object.defineProperty(exports, "summarizeUsageRows", { enumerable: true, get: function () { return usageReports_1.summarizeUsageRows; } });
|
|
83
|
+
Object.defineProperty(exports, "usageBucketKey", { enumerable: true, get: function () { return usageReports_1.usageBucketKey; } });
|
|
84
|
+
Object.defineProperty(exports, "weekKey", { enumerable: true, get: function () { return usageReports_1.weekKey; } });
|
|
85
|
+
var historicalStore_1 = require("./historicalStore");
|
|
86
|
+
Object.defineProperty(exports, "applySessionSummary", { enumerable: true, get: function () { return historicalStore_1.applySessionSummary; } });
|
|
87
|
+
Object.defineProperty(exports, "isFileImported", { enumerable: true, get: function () { return historicalStore_1.isFileImported; } });
|
|
88
|
+
Object.defineProperty(exports, "markFileImported", { enumerable: true, get: function () { return historicalStore_1.markFileImported; } });
|
|
89
|
+
Object.defineProperty(exports, "removeSessionSummary", { enumerable: true, get: function () { return historicalStore_1.removeSessionSummary; } });
|
|
90
|
+
Object.defineProperty(exports, "sessionSummaryFromStats", { enumerable: true, get: function () { return historicalStore_1.sessionSummaryFromStats; } });
|
|
91
|
+
var failingTools_1 = require("./failingTools");
|
|
92
|
+
Object.defineProperty(exports, "FAILING_TOOL_TREND_ARROWS", { enumerable: true, get: function () { return failingTools_1.FAILING_TOOL_TREND_ARROWS; } });
|
|
93
|
+
Object.defineProperty(exports, "failingToolTrend", { enumerable: true, get: function () { return failingTools_1.failingToolTrend; } });
|
|
94
|
+
Object.defineProperty(exports, "mergeFailingToolWindows", { enumerable: true, get: function () { return failingTools_1.mergeFailingToolWindows; } });
|
package/dist/codexProfiles.d.ts
CHANGED
|
@@ -31,7 +31,9 @@ export declare function resolveSidekickCodexHome(): string;
|
|
|
31
31
|
* isn't the current active pointer, the pointer is re-pointed so registry-keyed data
|
|
32
32
|
* (quota history, auto-switch) tracks reality too. Never creates or deletes profiles.
|
|
33
33
|
*/
|
|
34
|
-
export declare function resolveActiveCodexAccount(
|
|
34
|
+
export declare function resolveActiveCodexAccount(options?: {
|
|
35
|
+
selfHeal?: boolean;
|
|
36
|
+
}): ResolvedActiveAccount;
|
|
35
37
|
export declare function getCodexExecutionEnv(baseEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
36
38
|
export declare function prepareCodexAccount(label: string): CodexAccountManagerResult;
|
|
37
39
|
/** {@link prepareCodexAccount} without blocking the event loop on CLI probes. */
|
package/dist/codexProfiles.js
CHANGED
|
@@ -380,13 +380,15 @@ function resolveSidekickCodexHome() {
|
|
|
380
380
|
* isn't the current active pointer, the pointer is re-pointed so registry-keyed data
|
|
381
381
|
* (quota history, auto-switch) tracks reality too. Never creates or deletes profiles.
|
|
382
382
|
*/
|
|
383
|
-
function resolveActiveCodexAccount() {
|
|
383
|
+
function resolveActiveCodexAccount(options = {}) {
|
|
384
|
+
const selfHeal = options.selfHeal ?? true;
|
|
384
385
|
const identity = readAuthIdentityFromRaw(readFileOrNull(path.join(resolveSidekickCodexHome(), 'auth.json')));
|
|
385
386
|
if (identity && (identity.email || identity.workspaceId)) {
|
|
386
387
|
const match = findProfileForIdentity(identity);
|
|
387
388
|
if (match) {
|
|
388
389
|
const active = (0, accountRegistry_1.getActiveSavedAccount)('codex');
|
|
389
|
-
|
|
390
|
+
// See resolveActiveClaudeAccount: hot paths opt out of the repair write.
|
|
391
|
+
if (selfHeal && (!active || active.id !== match.id)) {
|
|
390
392
|
// Self-heal is best-effort: a registry write failure (read-only/full
|
|
391
393
|
// disk) must never break display, extension activation, or the quota
|
|
392
394
|
// watcher's hot path. We still return the correct live identity below.
|
package/dist/codexQuota.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export interface CodexQuotaApiOptions {
|
|
|
35
35
|
signal?: AbortSignal;
|
|
36
36
|
timeoutMs?: number;
|
|
37
37
|
}
|
|
38
|
+
/** Stamp a Codex quota sample with its runtime provider, projections, and account identity. */
|
|
39
|
+
export declare function enrichCodexQuota(state: QuotaState, account: SavedAccountProfile | null): ProviderQuotaState<'codex'>;
|
|
38
40
|
export declare function quotaFromCodexRateLimits(rateLimits: CodexRateLimits | null | undefined, source?: 'api' | 'session' | 'cache', capturedAt?: string): QuotaState | null;
|
|
39
41
|
export declare function readLatestCodexQuotaFromRollouts(sessionPaths: string[], options?: {
|
|
40
42
|
source?: 'session' | 'cache';
|