|
5 | 5 | RSpec.describe DiscourseAi::Admin::AiUsageController do |
6 | 6 | fab!(:admin) |
7 | 7 | fab!(:user) |
| 8 | + fab!(:llm_model) |
8 | 9 | let(:usage_report_path) { "/admin/plugins/discourse-ai/ai-usage-report.json" } |
9 | 10 |
|
10 | 11 | before { SiteSetting.discourse_ai_enabled = true } |
|
35 | 36 | ) |
36 | 37 | end |
37 | 38 |
|
| 39 | + fab!(:log3) do |
| 40 | + AiApiAuditLog.create!( |
| 41 | + provider_id: 1, |
| 42 | + feature_name: "ai_helper", |
| 43 | + language_model: llm_model.name, |
| 44 | + request_tokens: 300, |
| 45 | + response_tokens: 150, |
| 46 | + cached_tokens: 50, |
| 47 | + created_at: 3.days.ago, |
| 48 | + ) |
| 49 | + end |
| 50 | + |
38 | 51 | it "returns correct data structure" do |
39 | 52 | get usage_report_path |
40 | 53 |
|
|
55 | 68 | } |
56 | 69 |
|
57 | 70 | json = response.parsed_body |
58 | | - expect(json["summary"]["total_tokens"]).to eq(450) # sum of all tokens |
| 71 | + expect(json["summary"]["total_tokens"]).to eq(900) # sum of all tokens |
59 | 72 | end |
60 | 73 |
|
61 | 74 | it "filters by feature" do |
|
79 | 92 | expect(models.first["total_tokens"]).to eq(300) |
80 | 93 | end |
81 | 94 |
|
| 95 | + it "shows an estimated cost" do |
| 96 | + get usage_report_path, params: { model: llm_model.name } |
| 97 | + |
| 98 | + json = response.parsed_body |
| 99 | + summary = json["summary"] |
| 100 | + feature = json["features"].find { |f| f["feature_name"] == "ai_helper" } |
| 101 | + |
| 102 | + expected_input_spending = llm_model.input_cost * log3.request_tokens / 1_000_000.0 |
| 103 | + expected_cached_input_spending = |
| 104 | + llm_model.cached_input_cost * log3.cached_tokens / 1_000_000.0 |
| 105 | + expected_output_spending = llm_model.output_cost * log3.response_tokens / 1_000_000.0 |
| 106 | + expected_total_spending = |
| 107 | + expected_input_spending + expected_cached_input_spending + expected_output_spending |
| 108 | + |
| 109 | + expect(feature["input_spending"]).to eq(expected_input_spending.to_s) |
| 110 | + expect(feature["output_spending"]).to eq(expected_output_spending.to_s) |
| 111 | + expect(feature["cached_input_spending"]).to eq(expected_cached_input_spending.to_s) |
| 112 | + expect(summary["total_spending"]).to eq(expected_total_spending.round(2)) |
| 113 | + end |
| 114 | + |
82 | 115 | it "handles different period groupings" do |
83 | 116 | get usage_report_path, params: { period: "hour" } |
84 | 117 | expect(response.status).to eq(200) |
|
0 commit comments