summaryrefslogtreecommitdiff
path: root/frontend/src/pages/UsagePage.svelte
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
commit5c0ba37eda80d39e6ceca59bb1d5f4942f858995 (patch)
tree948723f9cedf7ccb0707fa6ee516bd30fe20fd10 /frontend/src/pages/UsagePage.svelte
downloadstrategy-lab-5c0ba37eda80d39e6ceca59bb1d5f4942f858995.tar.gz
chore: establish Strategy Lab source baseline (development, not release)
Diffstat (limited to 'frontend/src/pages/UsagePage.svelte')
-rw-r--r--frontend/src/pages/UsagePage.svelte84
1 files changed, 84 insertions, 0 deletions
diff --git a/frontend/src/pages/UsagePage.svelte b/frontend/src/pages/UsagePage.svelte
new file mode 100644
index 0000000..88dd8a5
--- /dev/null
+++ b/frontend/src/pages/UsagePage.svelte
@@ -0,0 +1,84 @@
+<script lang="ts">
+ import Page from '../components/Page.svelte';
+ import Status from '../components/Status.svelte';
+ import { getAIUsage } from '../lib/client';
+ import { extractStatusMessage } from '../lib/state';
+ import { fmtDateTime, fmtNum } from '../lib/format';
+ import type { AIUsage } from '../lib/types';
+
+ let usage = $state<AIUsage | null>(null);
+ let busy = $state(true);
+ let error = $state<string | null>(null);
+
+ $effect(() => {
+ void load();
+ });
+
+ async function load() {
+ busy = true;
+ error = null;
+ try {
+ usage = await getAIUsage();
+ } catch (e) {
+ error = extractStatusMessage(e);
+ } finally {
+ busy = false;
+ }
+ }
+</script>
+
+<Page title="AI 用量" subtitle="内部 POC 阶段的用量计量与限额参考。不含报价或计费">
+ <div class="stack">
+ <Status busy={busy} error={error} busyText="正在载入用量…" empty={null} />
+ {#if usage}
+ <div class="card">
+ <div class="row spaced">
+ <div>
+ <div class="mlabel">模型请求</div>
+ <div class="mvalue">{usage.totals?.requests ?? usage.items.length}</div>
+ </div>
+ <div>
+ <div class="mlabel">输入 tokens</div>
+ <div class="mvalue">{usage.totals?.input_tokens ?? '—'}</div>
+ </div>
+ <div>
+ <div class="mlabel">输出 tokens</div>
+ <div class="mvalue">{usage.totals?.output_tokens ?? '—'}</div>
+ </div>
+ </div>
+ {#if usage.internal_poc}
+ <p class="hint">内部 POC:请在当前配额内使用,不对实际价格负责;接受模型输出的决策需重新人工复核。</p>
+ {/if}
+ </div>
+
+ {#if usage.items.length > 0}
+ <div class="card" style="padding:0.4rem 0.6rem">
+ <table class="data">
+ <thead>
+ <tr>
+ <th>时间</th>
+ <th>模型</th>
+ <th>输入</th>
+ <th>输出</th>
+ <th>状态</th>
+ </tr>
+ </thead>
+ <tbody>
+ {#each usage.items as it, i (it.id)}
+ <tr>
+ <td>{fmtDateTime(it.created_at)}</td>
+ <td>{it.model}</td>
+ <td class="num">{it.input_tokens ?? '—'}</td>
+ <td class="num">{it.output_tokens ?? '—'}</td>
+ <td class="badge">{it.status ?? '—'}</td>
+ </tr>
+ {/each}
+ </tbody>
+ </table>
+ </div>
+ {:else}
+ <Status busy={false} empty="尚未使用 AI 建议" emptyHint="在项目「策略」标签发起一次 AI 修改,记录会出现在这里" />
+ {/if}
+ {/if}
+ </div>
+</Page>