pi-cache-optimizer 2.6.11 → 2.6.13
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/index.ts +69 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1717,6 +1717,51 @@ function keyForModelExt(model: { provider: string; id: string }): string {
|
|
|
1717
1717
|
return `${model.provider}/${model.id}`;
|
|
1718
1718
|
}
|
|
1719
1719
|
|
|
1720
|
+
/**
|
|
1721
|
+
* For direct (non-virtual-routing) providers, the upstream API may normalize or
|
|
1722
|
+
* rename the model id echoed in its response (e.g. a request to
|
|
1723
|
+
* `zai-org/GLM-5.2-FP8` returns a message whose `model` field is
|
|
1724
|
+
* `GLM5.2-FP8`). Writing stats under the echoed name fragments the bucket
|
|
1725
|
+
* away from the active-model key the footer reads (`totalsByModel[ctx.model]`),
|
|
1726
|
+
* so the footer shows 0% even when the backend is hitting cache.
|
|
1727
|
+
*
|
|
1728
|
+
* When the response-derived statsModel differs from the active context model
|
|
1729
|
+
* only in name (same provider + same cache adapter), consolidate stats back to
|
|
1730
|
+
* the active model identity. Virtual routing providers are excluded — their
|
|
1731
|
+
* message-local metadata is authoritative for router correctness (spec:
|
|
1732
|
+
* `message_end` MUST prefer assistant message metadata).
|
|
1733
|
+
*
|
|
1734
|
+
* Never merges across providers or across adapters, so genuinely different
|
|
1735
|
+
* models are never combined.
|
|
1736
|
+
*/
|
|
1737
|
+
function consolidateDirectProviderStatsModel(
|
|
1738
|
+
statsModel: PiModel | undefined,
|
|
1739
|
+
ctxModel: PiModel | undefined,
|
|
1740
|
+
ctx?: Pick<ExtensionContext, "sessionManager">,
|
|
1741
|
+
): PiModel | undefined {
|
|
1742
|
+
if (!statsModel || !ctxModel) return statsModel;
|
|
1743
|
+
// Virtual routing providers keep message-local stats identity.
|
|
1744
|
+
if (isVirtualRoutingModel(ctxModel, ctx)) return statsModel;
|
|
1745
|
+
// Only consolidate within the same provider.
|
|
1746
|
+
if (statsModel.provider !== ctxModel.provider) return statsModel;
|
|
1747
|
+
// Only consolidate when both resolve to the same cache adapter object, so
|
|
1748
|
+
// genuinely different models sharing a provider (or sharing the same adapter
|
|
1749
|
+
// family id, e.g. GPT and GLM both report family id "openai") are never
|
|
1750
|
+
// merged. `selectAdapterForModel` returns the precise adapter object, so
|
|
1751
|
+
// object identity is the correct criterion.
|
|
1752
|
+
const statsAdapter = selectAdapterForModel(statsModel);
|
|
1753
|
+
const ctxAdapter = selectAdapterForModel(ctxModel);
|
|
1754
|
+
if (!statsAdapter || !ctxAdapter || statsAdapter !== ctxAdapter) return statsModel;
|
|
1755
|
+
// No drift — nothing to consolidate.
|
|
1756
|
+
if (statsModel.id === ctxModel.id) return statsModel;
|
|
1757
|
+
// Consolidate: pin stats to the active-model identity the footer reads.
|
|
1758
|
+
return {
|
|
1759
|
+
...statsModel,
|
|
1760
|
+
id: ctxModel.id,
|
|
1761
|
+
name: ctxModel.name || ctxModel.id,
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1720
1765
|
function usageRecordFromAssistant(message: unknown): UnknownRecord | undefined {
|
|
1721
1766
|
return asRecord(getAssistantRecord(message)?.usage);
|
|
1722
1767
|
}
|
|
@@ -5715,6 +5760,7 @@ export const __internals_for_tests = {
|
|
|
5715
5760
|
getAssistantMessageModelTokenValues,
|
|
5716
5761
|
getCompat,
|
|
5717
5762
|
modelKey,
|
|
5763
|
+
consolidateDirectProviderStatsModel,
|
|
5718
5764
|
// Platform-friendly path helpers
|
|
5719
5765
|
getModelsJsonDisplayPath,
|
|
5720
5766
|
buildProviderCompatOverride,
|
|
@@ -6481,12 +6527,34 @@ export default function (pi: ExtensionAPI) {
|
|
|
6481
6527
|
const adapter = selectAdapterForAssistantMessage(event.message, ctx.model);
|
|
6482
6528
|
if (!adapter) return;
|
|
6483
6529
|
|
|
6530
|
+
// Skip stats for error/aborted messages (network retries, user aborts).
|
|
6531
|
+
// Pi's auto-retry emits message_end for the failed attempt before
|
|
6532
|
+
// removing it and retrying. The error message carries zero-usage fields
|
|
6533
|
+
// ({ input: 0, cacheRead: 0, cacheWrite: 0 }) that normalizeUsage
|
|
6534
|
+
// returns as a valid (non-undefined) snapshot, which would inflate
|
|
6535
|
+
// totalRequests and skew cache hit-rate accuracy. The final successful
|
|
6536
|
+
// response is emitted as a separate message_end with real usage data.
|
|
6537
|
+
const msgRecord = asRecord(event.message);
|
|
6538
|
+
if (msgRecord?.stopReason === "error" || msgRecord?.stopReason === "aborted") {
|
|
6539
|
+
return;
|
|
6540
|
+
}
|
|
6541
|
+
|
|
6484
6542
|
const usage = adapter.normalizeUsage(event.message);
|
|
6485
6543
|
|
|
6486
6544
|
// Completed message metadata is request-local and authoritative for virtual
|
|
6487
6545
|
// routing providers. Use it whenever it supplies provider/model identity;
|
|
6488
6546
|
// fall back to the active context model for direct providers.
|
|
6489
|
-
|
|
6547
|
+
let statsModel = modelFromAssistantMessage(event.message, ctx.model) ?? ctx.model;
|
|
6548
|
+
// For direct (non-virtual-routing) providers, the upstream API may echo a
|
|
6549
|
+
// normalized/renamed model id in its response (e.g. request
|
|
6550
|
+
// `zai-org/GLM-5.2-FP8` but the message carries `GLM5.2-FP8`). Writing
|
|
6551
|
+
// stats under the echoed name fragments the bucket away from the
|
|
6552
|
+
// active-model key the footer reads, showing 0% even when the backend is
|
|
6553
|
+
// hitting cache. When the response model drifts from the active model only
|
|
6554
|
+
// in name (same provider, same cache adapter), consolidate stats back to
|
|
6555
|
+
// the active model id. Virtual routing providers keep message-local
|
|
6556
|
+
// identity (router correctness).
|
|
6557
|
+
statsModel = consolidateDirectProviderStatsModel(statsModel, ctx.model, ctx);
|
|
6490
6558
|
let routedModelChanged = false;
|
|
6491
6559
|
if (isVirtualRoutingModel(ctx.model, ctx) && statsModel && !isVirtualRoutingModel(statsModel, ctx)) {
|
|
6492
6560
|
const nextRoutedModel: PersistedRoutedModelRef = {
|
package/package.json
CHANGED