@oh-my-pi/omp-stats 18.11.3 → 18.12.1

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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.12.0] - 2026-10-17
6
+
7
+ ### Fixed
8
+
9
+ - Fixed usage stats pricing Google Antigravity and MiniMax Token Plan models at $0 when their catalog rows carry no price; they now use the catalog's pricing peer, as `xai-oauth` already did ([#16092](https://github.com/can1357/oh-my-pi/pull/16092) by [@H4vC](https://github.com/H4vC))
10
+
5
11
  ## [18.11.0] - 2026-10-14
6
12
 
7
13
  ### Fixed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/omp-stats",
4
- "version": "18.11.3",
4
+ "version": "18.12.1",
5
5
  "description": "Local observability dashboard for omp AI usage statistics",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": {
@@ -42,9 +42,9 @@
42
42
  "fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
43
43
  },
44
44
  "dependencies": {
45
- "@oh-my-pi/pi-ai": "18.11.3",
46
- "@oh-my-pi/pi-catalog": "18.11.3",
47
- "@oh-my-pi/pi-utils": "18.11.3",
45
+ "@oh-my-pi/pi-ai": "18.12.1",
46
+ "@oh-my-pi/pi-catalog": "18.12.1",
47
+ "@oh-my-pi/pi-utils": "18.12.1",
48
48
  "lucide-react": "^1.24.0",
49
49
  "react": "19.2.7",
50
50
  "react-dom": "19.2.7"
package/src/db.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import * as fs from "node:fs/promises";
3
3
  import type { ServiceTier, Usage } from "@oh-my-pi/pi-ai";
4
+ import { pricingPeerFor } from "@oh-my-pi/pi-catalog/compat/behavior";
4
5
  import {
5
6
  calculateUncachedInputCost,
6
7
  calculateUsageCost,
@@ -386,9 +387,16 @@ function getCatalogCost(provider: string, modelId: string): ModelCost | null {
386
387
  return primaryCost;
387
388
  }
388
389
 
389
- const fallbackProvider = provider === "openai-codex" ? "openai" : provider === "xai-oauth" ? "xai" : null;
390
- if (fallbackProvider) {
391
- const fallbackCost = getBundledModelCost(fallbackProvider, modelId);
390
+ // openai-codex has no catalog pricing-peer row (its bundled rows carry
391
+ // their own prices); keep its first-party fallback here.
392
+ const peer = pricingPeerFor(provider, modelId);
393
+ const fallbacks = peer
394
+ ? peer.peers.map(peerProvider => [peerProvider, peer.peerId] as const)
395
+ : provider === "openai-codex"
396
+ ? [["openai", modelId] as const]
397
+ : [];
398
+ for (const [fallbackProvider, fallbackId] of fallbacks) {
399
+ const fallbackCost = getBundledModelCost(fallbackProvider, fallbackId);
392
400
  if (fallbackCost && hasBillableCost(fallbackCost)) {
393
401
  return fallbackCost;
394
402
  }
package/src/trace.ts CHANGED
@@ -11,6 +11,7 @@
11
11
 
12
12
  import * as fs from "node:fs/promises";
13
13
  import * as path from "node:path";
14
+ import { pricingPeerFor } from "@oh-my-pi/pi-catalog/compat/behavior";
14
15
  import { getBundledModel, type GeneratedProvider } from "@oh-my-pi/pi-catalog/models";
15
16
  import { getSessionsDir, isEnoent } from "@oh-my-pi/pi-utils";
16
17
  import { initDb, isScheduledCatalogModel } from "./db";
@@ -393,11 +394,13 @@ function scanTranscript(
393
394
  if (totalTokens > 0 && (costTotal === undefined || costTotal === 0)) {
394
395
  const provider = typeof msg.provider === "string" ? msg.provider : "";
395
396
  const model = typeof msg.model === "string" ? msg.model : "";
396
- if (provider === "xai-oauth" && model) {
397
- const ref = getBundledModel("xai" as GeneratedProvider, model)?.cost;
398
- if (!(ref && (ref.input !== 0 || ref.output !== 0 || ref.cacheRead !== 0 || ref.cacheWrite !== 0))) {
399
- unpricedRequests++;
400
- }
397
+ const peer = provider && model ? pricingPeerFor(provider, model) : undefined;
398
+ if (peer) {
399
+ const priced = peer.peers.some(peerProvider => {
400
+ const ref = getBundledModel(peerProvider as GeneratedProvider, peer.peerId)?.cost;
401
+ return ref && (ref.input !== 0 || ref.output !== 0 || ref.cacheRead !== 0 || ref.cacheWrite !== 0);
402
+ });
403
+ if (!priced) unpricedRequests++;
401
404
  } else if (costObj == null && provider && model) {
402
405
  const hasTimestamp =
403
406
  (typeof msg.timestamp === "number" && Number.isFinite(msg.timestamp) && msg.timestamp > 0) ||