Version 1.2.2. Added usage overview. Shows token used and cost in $.

This commit is contained in:
2026-04-15 10:00:39 +02:00
parent 752691fe54
commit d4c6420481
18 changed files with 1657 additions and 86 deletions

View File

@@ -16,7 +16,7 @@
<img src="{{ logo_url }}" alt="logo" class="sidebar-logo-img">
<div class="sidebar-logo-text">
<div class="sidebar-logo-name">{{ brand_name }}</div>
<div class="sidebar-logo-app">oAI-Web <span class="sidebar-logo-version">v1.2.1</span></div>
<div class="sidebar-logo-app">oAI-Web <span class="sidebar-logo-version">v1.2.2</span></div>
</div>
</div>
@@ -44,6 +44,12 @@
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M20.188 10.934a8.002 8.002 0 0 1 0 2.132M3.812 13.066a8.002 8.002 0 0 1 0-2.132M15.536 17.121a8 8 0 0 1-1.506.643M9.97 6.236A8 8 0 0 1 11.5 6M17.657 7.757a8 8 0 0 1 .879 1.506M6.343 16.243a8 8 0 0 1-.879-1.506M17.121 15.536a8 8 0 0 1-1.506.879M8.464 6.879A8 8 0 0 1 9.97 6.236"/></svg>
Monitors
</a>
{% if can_view_usage %}
<a class="nav-item" data-page="/usage" href="/usage">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>
Usage
</a>
{% endif %}
<a class="nav-item" data-page="/audit" href="/audit">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
Audit Log

View File

@@ -43,6 +43,7 @@
<button type="button" class="tab-btn" id="ustab-brain" onclick="switchUserTab('brain')">2nd Brain</button>
<button type="button" class="tab-btn" id="ustab-pushover" onclick="switchUserTab('pushover')">Pushover</button>
<button type="button" class="tab-btn" id="ustab-webhooks" onclick="switchUserTab('webhooks')">Webhooks</button>
<button type="button" class="tab-btn" id="ustab-browser" onclick="switchUserTab('browser')">Browser</button>
<button type="button" class="tab-btn" id="ustab-mfa" onclick="switchUserTab('mfa')">Profile</button>
</div>
{% endif %}
@@ -417,6 +418,39 @@
</form>
</section>
<div style="border-top:1px solid var(--border);margin-bottom:36px"></div>
<!-- Browser trusted domains -->
<section>
<h2 class="settings-section-title">Browser Trusted Domains</h2>
<p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">
Domains where browser <em>interaction</em> operations (click, fill, select, press) run without
asking for confirmation. Subdomains are automatically included.
Each user manages their own list.
</p>
<div class="table-wrap" style="margin-bottom:16px">
<table>
<thead>
<tr><th>Domain</th><th>Note</th><th>Actions</th></tr>
</thead>
<tbody id="browser-trusted-list">
<tr><td colspan="3" style="text-align:center;color:var(--text-dim)">Loading…</td></tr>
</tbody>
</table>
</div>
<form id="browser-trusted-form" style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;max-width:560px">
<div class="form-group" style="flex:1;min-width:160px;margin-bottom:0">
<label>Add domain</label>
<input type="text" id="bt-domain" class="form-input" placeholder="example.com" required autocomplete="off">
</div>
<div class="form-group" style="flex:2;min-width:180px;margin-bottom:0">
<label>Note <span style="color:var(--text-dim)">(optional)</span></label>
<input type="text" id="bt-note" class="form-input" placeholder="e.g. Work intranet">
</div>
<button type="submit" class="btn btn-primary" style="margin-bottom:0">Add</button>
</form>
</section>
</div><!-- /spane-whitelists -->
<!-- ══════════════════════════════════════════════════════════
@@ -1696,6 +1730,37 @@
<!-- ══════════════════════════════════════════════════════════
USER SETTINGS: Profile
═══════════════════════════════════════════════════════════ -->
<div id="uspane-browser" style="display:none">
<section>
<h2 class="settings-section-title">Browser Trusted Domains</h2>
<p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">
Domains where browser <em>interaction</em> operations (click, fill, select, press) run
without asking for confirmation each time. Subdomains are automatically included.
</p>
<div class="table-wrap" style="margin-bottom:16px">
<table>
<thead>
<tr><th>Domain</th><th>Note</th><th>Actions</th></tr>
</thead>
<tbody id="my-browser-trusted-list">
<tr><td colspan="3" style="text-align:center;color:var(--text-dim)">Loading…</td></tr>
</tbody>
</table>
</div>
<form id="my-browser-trusted-form" style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;max-width:560px">
<div class="form-group" style="flex:1;min-width:160px;margin-bottom:0">
<label>Add domain</label>
<input type="text" id="my-bt-domain" class="form-input" placeholder="example.com" required autocomplete="off">
</div>
<div class="form-group" style="flex:2;min-width:180px;margin-bottom:0">
<label>Note <span style="color:var(--text-dim)">(optional)</span></label>
<input type="text" id="my-bt-note" class="form-input" placeholder="e.g. Work intranet">
</div>
<button type="submit" class="btn btn-primary" style="margin-bottom:0">Add</button>
</form>
</section>
</div><!-- /uspane-browser -->
<div id="uspane-mfa" style="display:none">
<!-- Theme picker -->

View File

@@ -0,0 +1,95 @@
{% extends "base.html" %}
{% block title %}{{ agent_name }} — Usage{% endblock %}
{% block content %}
<div class="page" id="usage-container">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:24px">
<h1>Usage</h1>
<!-- Time range filter -->
<div style="display:flex;gap:6px">
<button class="btn" id="usage-range-today" type="button" onclick="setUsageRange('today')">Today</button>
<button class="btn" id="usage-range-7d" type="button" onclick="setUsageRange('7d')" style="background:var(--accent);color:#fff;border-color:var(--accent)">7 days</button>
<button class="btn" id="usage-range-30d" type="button" onclick="setUsageRange('30d')">30 days</button>
<button class="btn" id="usage-range-all" type="button" onclick="setUsageRange('all')">All time</button>
</div>
</div>
<!-- Summary cards -->
<div id="usage-cards" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:16px;margin-bottom:32px">
<div class="stat-card">
<div class="stat-label">Runs</div>
<div class="stat-value" id="u-total-runs"></div>
</div>
<div class="stat-card">
<div class="stat-label">Input tokens</div>
<div class="stat-value" id="u-input-tokens"></div>
</div>
<div class="stat-card">
<div class="stat-label">Output tokens</div>
<div class="stat-value" id="u-output-tokens"></div>
</div>
<div class="stat-card">
<div class="stat-label">Total tokens</div>
<div class="stat-value" id="u-total-tokens"></div>
</div>
<div class="stat-card">
<div class="stat-label">Est. cost</div>
<div class="stat-value" id="u-cost"></div>
</div>
</div>
<!-- Per-agent breakdown -->
<h2 style="font-size:14px;color:var(--text-dim);font-weight:500;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:12px">
By agent
</h2>
<div class="table-wrap">
<table id="usage-table">
<thead>
<tr>
<th style="text-align:left">Agent</th>
<th style="text-align:left">Model</th>
<th style="text-align:right">Runs</th>
<th style="text-align:right">Input</th>
<th style="text-align:right">Output</th>
<th style="text-align:right">Total tokens</th>
<th style="text-align:right">Est. cost</th>
<th style="min-width:120px"></th>
</tr>
</thead>
<tbody id="usage-tbody">
<tr><td colspan="8" style="text-align:center;color:var(--text-dim);padding:32px">Loading…</td></tr>
</tbody>
</table>
</div>
<!-- Chat sessions summary -->
<h2 style="font-size:14px;color:var(--text-dim);font-weight:500;text-transform:uppercase;letter-spacing:0.5px;margin:32px 0 12px">
Chat sessions
</h2>
<div id="usage-chat-section">
<div class="table-wrap">
<table>
<thead>
<tr>
<th style="text-align:left">Source</th>
<th style="text-align:right">Sessions</th>
<th style="text-align:right">Input</th>
<th style="text-align:right">Output</th>
<th style="text-align:right">Total tokens</th>
<th style="text-align:right">Est. cost</th>
</tr>
</thead>
<tbody id="usage-chat-tbody">
<tr><td colspan="6" style="text-align:center;color:var(--text-dim);padding:24px">Loading…</td></tr>
</tbody>
</table>
</div>
</div>
<p id="usage-no-cost-note" style="font-size:12px;color:var(--text-dim);margin-top:12px;display:none">
Cost estimates only available for runs recorded after the usage tracking feature was enabled.
Runs on free or unknown models show no cost.
</p>
</div>
{% endblock %}