Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 7cf9a63

Browse files
committed
minimally functional usage page
1 parent 62cd2da commit 7cf9a63

File tree

4 files changed

+201
-4
lines changed

4 files changed

+201
-4
lines changed

admin/assets/javascripts/discourse/routes/admin-plugins-show-discourse-ai-usage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ export default class DiscourseAiUsageRoute extends DiscourseRoute {
66
@service store;
77

88
model() {
9-
ajax("/admin/plugins/discourse-ai/ai-usage.json");
9+
return ajax("/admin/plugins/discourse-ai/ai-usage.json");
1010
}
1111
}

app/serializers/ai_usage_serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class AiUsageSerializer < ApplicationSerializer
44
attributes :data, :features, :models, :summary
55

66
def data
7-
object.tokens_by_period.to_json
7+
object.tokens_by_period.map {|key, value| [key, value]}
88
end
99

1010
def features
Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,196 @@
11
import Component from "@glimmer/component";
2+
import { tracked } from "@glimmer/tracking";
3+
import { array } from "@ember/helper";
4+
import { action } from "@ember/object";
5+
import { service } from "@ember/service";
6+
import DatePicker from "discourse/components/date-picker";
7+
import { ajax } from "discourse/lib/ajax";
8+
import i18n from "discourse-common/helpers/i18n";
9+
import Chart from "admin/components/chart";
10+
import ComboBox from "select-kit/components/combo-box";
211

312
export default class AiUsage extends Component {
4-
hello() {}
13+
@service store;
14+
@tracked startDate = moment().subtract(30, "days").toDate();
15+
@tracked endDate = new Date();
16+
@tracked data = this.args.model;
17+
@tracked selectedFeature;
18+
@tracked selectedModel;
19+
@tracked period = "day";
20+
21+
constructor() {
22+
super(...arguments);
23+
console.log(this.args.model);
24+
console.log(this.data);
25+
}
26+
27+
@action
28+
async fetchData() {
29+
const response = await ajax("/admin/plugins/discourse-ai/ai-usage.json", {
30+
data: {
31+
start_date: moment(this.startDate).format("YYYY-MM-DD"),
32+
end_date: moment(this.endDate).format("YYYY-MM-DD"),
33+
feature: this.selectedFeature,
34+
model: this.selectedModel,
35+
period: this.period,
36+
},
37+
});
38+
this.data = response;
39+
}
40+
41+
@action
42+
async onDateChange() {
43+
await this.fetchData();
44+
}
45+
46+
@action
47+
async onFilterChange() {
48+
await this.fetchData();
49+
}
50+
51+
get chartConfig() {
52+
console.log("here");
53+
if (!this.data?.data) {
54+
return;
55+
}
56+
57+
const x = {
58+
type: "line",
59+
data: {
60+
labels: this.data.data.map(pair => pair[0]),
61+
datasets: [
62+
{
63+
label: "Tokens",
64+
data: this.data.data.map(pair => pair[1]),
65+
fill: false,
66+
borderColor: "rgb(75, 192, 192)",
67+
tension: 0.1,
68+
},
69+
],
70+
},
71+
options: {
72+
responsive: true,
73+
scales: {
74+
y: {
75+
beginAtZero: true,
76+
},
77+
},
78+
},
79+
};
80+
81+
console.log(x);
82+
return x;
83+
}
84+
585
<template>
6-
testing
86+
<div class="ai-usage">
87+
<div class="ai-usage__filters">
88+
<div class="ai-usage__filters-dates">
89+
<DatePicker
90+
@value={{this.startDate}}
91+
@onChange={{this.onDateChange}}
92+
class="ai-usage__date-picker"
93+
/>
94+
<DatePicker
95+
@value={{this.endDate}}
96+
@onChange={{this.onDateChange}}
97+
class="ai-usage__date-picker"
98+
/>
99+
</div>
100+
101+
<div class="ai-usage__filters-period">
102+
<label class="ai-usage__period-label">
103+
{{i18n "discourse_ai.usage.period"}}
104+
</label>
105+
<ComboBox
106+
@value={{this.period}}
107+
@content={{array "hour" "day" "month"}}
108+
@onChange={{this.onFilterChange}}
109+
class="ai-usage__period-selector"
110+
/>
111+
</div>
112+
113+
{{#if this.data}}
114+
<div class="ai-usage__summary">
115+
<h3 class="ai-usage__summary-title">
116+
{{i18n "discourse_ai.usage.summary"}}
117+
</h3>
118+
<div class="ai-usage__summary-tokens">
119+
{{i18n "discourse_ai.usage.total_tokens"}}:
120+
{{this.data.summary.total_tokens}}
121+
</div>
122+
</div>
123+
124+
<div class="ai-usage__charts">
125+
<div class="ai-usage__chart-container">
126+
<h3 class="ai-usage__chart-title">
127+
{{i18n "discourse_ai.usage.tokens_over_time"}}
128+
</h3>
129+
<Chart @chartConfig={{this.chartConfig}} class="ai-usage__chart" />
130+
</div>
131+
132+
<div class="ai-usage__breakdowns">
133+
<div class="ai-usage__features">
134+
<h3 class="ai-usage__features-title">
135+
{{i18n "discourse_ai.usage.features_breakdown"}}
136+
</h3>
137+
<table class="ai-usage__features-table">
138+
<thead>
139+
<tr>
140+
<th>{{i18n "discourse_ai.usage.feature"}}</th>
141+
<th>{{i18n "discourse_ai.usage.usage_count"}}</th>
142+
<th>{{i18n "discourse_ai.usage.total_tokens"}}</th>
143+
</tr>
144+
</thead>
145+
<tbody>
146+
{{#each this.data.features as |feature|}}
147+
<tr class="ai-usage__features-row">
148+
<td
149+
class="ai-usage__features-cell"
150+
>{{feature.feature_name}}</td>
151+
<td
152+
class="ai-usage__features-cell"
153+
>{{feature.usage_count}}</td>
154+
<td
155+
class="ai-usage__features-cell"
156+
>{{feature.total_tokens}}</td>
157+
</tr>
158+
{{/each}}
159+
</tbody>
160+
</table>
161+
</div>
162+
163+
<div class="ai-usage__models">
164+
<h3 class="ai-usage__models-title">
165+
{{i18n "discourse_ai.usage.models_breakdown"}}
166+
</h3>
167+
<table class="ai-usage__models-table">
168+
<thead>
169+
<tr>
170+
<th>{{i18n "discourse_ai.usage.model"}}</th>
171+
<th>{{i18n "discourse_ai.usage.usage_count"}}</th>
172+
<th>{{i18n "discourse_ai.usage.total_tokens"}}</th>
173+
</tr>
174+
</thead>
175+
<tbody>
176+
{{#each this.data.models as |model|}}
177+
<tr class="ai-usage__models-row">
178+
<td class="ai-usage__models-cell">{{model.llm}}</td>
179+
<td
180+
class="ai-usage__models-cell"
181+
>{{model.usage_count}}</td>
182+
<td
183+
class="ai-usage__models-cell"
184+
>{{model.total_tokens}}</td>
185+
</tr>
186+
{{/each}}
187+
</tbody>
188+
</table>
189+
</div>
190+
</div>
191+
</div>
192+
{{/if}}
193+
</div>
194+
</div>
7195
</template>
8196
}

config/locales/client.en.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ en:
128128

129129
usage:
130130
short_title: "Usage"
131+
summary: "Summary"
132+
total_tokens: "Total tokens"
133+
tokens_over_time: "Tokens over time"
134+
features_breakdown: "Usage per feature"
135+
feature: "Feature"
136+
usage_count: "Usage Count"
137+
model: "Model"
138+
models_breakdown: "Usage per model"
139+
period: "Period"
131140

132141
ai_persona:
133142
tool_strategies:

0 commit comments

Comments
 (0)