@acarmisc/backstage-plugin-litellm-backend 0.1.10 → 0.1.11

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/dist/index.cjs.js CHANGED
@@ -5683,13 +5683,26 @@ var LiteLLMClient = class {
5683
5683
  total_tokens: 0,
5684
5684
  prompt_tokens: 0,
5685
5685
  completion_tokens: 0,
5686
+ api_requests: 0,
5687
+ successful_requests: 0,
5688
+ failed_requests: 0,
5686
5689
  usage_by_model: {},
5687
- daily_usage: []
5690
+ usage_by_key: {},
5691
+ daily_usage: [],
5692
+ daily_by_model: []
5688
5693
  };
5689
5694
  }
5690
5695
  /**
5691
5696
  * Transforms LiteLLM's SpendAnalyticsPaginatedResponse into the flatter
5692
5697
  * UsageMetrics shape consumed by the frontend charts.
5698
+ *
5699
+ * Source shape (per result row):
5700
+ * { date, metrics, breakdown: { models: { [name]: { metrics, api_key_breakdown: { [keyHash]: { metrics, metadata } } } } } }
5701
+ *
5702
+ * We fan that out into three views the UI consumes:
5703
+ * - daily_usage → spend + request trends over time
5704
+ * - usage_by_model → which models drove cost / traffic
5705
+ * - usage_by_key → which keys drove cost / traffic (with key_alias + team_id from metadata)
5693
5706
  */
5694
5707
  transformDailyActivity(response) {
5695
5708
  const results = Array.isArray(response?.results) ? response.results : [];
@@ -5699,24 +5712,69 @@ var LiteLLMClient = class {
5699
5712
  spend: r.metrics?.spend ?? 0,
5700
5713
  total_tokens: r.metrics?.total_tokens ?? 0,
5701
5714
  prompt_tokens: r.metrics?.prompt_tokens ?? 0,
5702
- completion_tokens: r.metrics?.completion_tokens ?? 0
5715
+ completion_tokens: r.metrics?.completion_tokens ?? 0,
5716
+ api_requests: r.metrics?.api_requests ?? 0,
5717
+ successful_requests: r.metrics?.successful_requests ?? 0,
5718
+ failed_requests: r.metrics?.failed_requests ?? 0
5703
5719
  })).sort((a, b) => a.date.localeCompare(b.date));
5704
5720
  const usage_by_model = {};
5721
+ const usage_by_key = {};
5722
+ const daily_by_model = [];
5723
+ const emptyModelBucket = () => ({
5724
+ total_spend: 0,
5725
+ total_tokens: 0,
5726
+ prompt_tokens: 0,
5727
+ completion_tokens: 0,
5728
+ api_requests: 0,
5729
+ successful_requests: 0,
5730
+ failed_requests: 0
5731
+ });
5705
5732
  for (const r of results) {
5706
5733
  const models = r.breakdown?.models ?? {};
5707
5734
  for (const [name, entry] of Object.entries(models)) {
5708
5735
  const m = entry?.metrics ?? {};
5709
- const bucket = usage_by_model[name] ?? {
5710
- total_spend: 0,
5711
- total_tokens: 0,
5712
- prompt_tokens: 0,
5713
- completion_tokens: 0
5714
- };
5736
+ const bucket = usage_by_model[name] ?? emptyModelBucket();
5715
5737
  bucket.total_spend += m.spend ?? 0;
5716
5738
  bucket.total_tokens += m.total_tokens ?? 0;
5717
5739
  bucket.prompt_tokens += m.prompt_tokens ?? 0;
5718
5740
  bucket.completion_tokens += m.completion_tokens ?? 0;
5741
+ bucket.api_requests += m.api_requests ?? 0;
5742
+ bucket.successful_requests += m.successful_requests ?? 0;
5743
+ bucket.failed_requests += m.failed_requests ?? 0;
5719
5744
  usage_by_model[name] = bucket;
5745
+ daily_by_model.push({
5746
+ date: r.date,
5747
+ model: name,
5748
+ spend: m.spend ?? 0,
5749
+ prompt_tokens: m.prompt_tokens ?? 0,
5750
+ completion_tokens: m.completion_tokens ?? 0,
5751
+ total_tokens: m.total_tokens ?? 0,
5752
+ api_requests: m.api_requests ?? 0,
5753
+ successful_requests: m.successful_requests ?? 0,
5754
+ failed_requests: m.failed_requests ?? 0
5755
+ });
5756
+ const keyMap = entry?.api_key_breakdown ?? {};
5757
+ for (const [keyHash, keyEntry] of Object.entries(keyMap)) {
5758
+ const km = keyEntry?.metrics ?? {};
5759
+ const kmeta = keyEntry?.metadata ?? {};
5760
+ const kb = usage_by_key[keyHash] ?? {
5761
+ key_alias: kmeta.key_alias,
5762
+ team_id: kmeta.team_id ?? null,
5763
+ models: [],
5764
+ ...emptyModelBucket()
5765
+ };
5766
+ if (!kb.key_alias && kmeta.key_alias) kb.key_alias = kmeta.key_alias;
5767
+ if (kb.team_id == null && kmeta.team_id) kb.team_id = kmeta.team_id;
5768
+ if (!kb.models.includes(name)) kb.models.push(name);
5769
+ kb.total_spend += km.spend ?? 0;
5770
+ kb.total_tokens += km.total_tokens ?? 0;
5771
+ kb.prompt_tokens += km.prompt_tokens ?? 0;
5772
+ kb.completion_tokens += km.completion_tokens ?? 0;
5773
+ kb.api_requests += km.api_requests ?? 0;
5774
+ kb.successful_requests += km.successful_requests ?? 0;
5775
+ kb.failed_requests += km.failed_requests ?? 0;
5776
+ usage_by_key[keyHash] = kb;
5777
+ }
5720
5778
  }
5721
5779
  }
5722
5780
  return {
@@ -5724,8 +5782,13 @@ var LiteLLMClient = class {
5724
5782
  total_tokens: meta.total_tokens ?? 0,
5725
5783
  prompt_tokens: meta.total_prompt_tokens ?? 0,
5726
5784
  completion_tokens: meta.total_completion_tokens ?? 0,
5785
+ api_requests: meta.total_api_requests ?? 0,
5786
+ successful_requests: meta.total_successful_requests ?? 0,
5787
+ failed_requests: meta.total_failed_requests ?? 0,
5727
5788
  usage_by_model,
5728
- daily_usage
5789
+ usage_by_key,
5790
+ daily_usage,
5791
+ daily_by_model
5729
5792
  };
5730
5793
  }
5731
5794
  async getUsage(startDate, endDate, userId, _groupBy) {