@kenhkl/agent-moss 0.12.3 → 0.12.5
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/cli.js +12 -5
- package/dist/cli.js.map +1 -1
- package/dist/engine/coordinator.d.ts +3 -3
- package/dist/engine/coordinator.js +10 -4
- package/dist/engine/coordinator.js.map +1 -1
- package/dist/rules/l1_rules.json +6 -0
- package/dist/server.js +12 -5
- package/dist/server.js.map +1 -1
- package/dist/static/index.html +39 -3
- package/package.json +1 -1
package/dist/static/index.html
CHANGED
|
@@ -991,6 +991,7 @@ let tokenStatsDays = 7;
|
|
|
991
991
|
let tokenRefreshTimer = null;
|
|
992
992
|
let trendChartInstance = null;
|
|
993
993
|
function render_token() {
|
|
994
|
+
tokenRecentPage = 1; // 切到 Token 页时重置最近调用分页到第 1 页
|
|
994
995
|
el('page-token').innerHTML = `
|
|
995
996
|
<div class="ag-card">
|
|
996
997
|
<div class="ag-section-title">${t('Token 用量详细统计', 'Detailed Token Statistics')
|
|
@@ -1132,22 +1133,57 @@ function renderTokenTrend(data) {
|
|
|
1132
1133
|
})),
|
|
1133
1134
|
}, true);
|
|
1134
1135
|
}
|
|
1136
|
+
// Token 最近调用分页状态
|
|
1137
|
+
let tokenRecentPage = 1;
|
|
1138
|
+
const TOKEN_RECENT_PAGE_SIZE = 10;
|
|
1139
|
+
let tokenRecentTotal = 0; // 最近调用总条数(供跳转页时计算总页数)
|
|
1135
1140
|
async function loadTokenRecent() {
|
|
1136
1141
|
const recentEl = el('token-recent');
|
|
1137
1142
|
if (!recentEl) return;
|
|
1138
1143
|
try {
|
|
1139
|
-
const
|
|
1144
|
+
const offset = (tokenRecentPage - 1) * TOKEN_RECENT_PAGE_SIZE;
|
|
1145
|
+
const data = await api(`token-stats/recent?limit=${TOKEN_RECENT_PAGE_SIZE}&offset=${offset}`);
|
|
1146
|
+
const records = Array.isArray(data) ? data : (data?.records || []);
|
|
1147
|
+
const total = Array.isArray(data) ? records.length : (data?.total ?? records.length);
|
|
1148
|
+
tokenRecentTotal = total; // 供跳转页时计算总页数
|
|
1140
1149
|
if (!records || records.length === 0) { recentEl.innerHTML = `<div class="ag-empty">${t('暂无记录', 'No records yet')}</div>`; return; }
|
|
1141
1150
|
let html = '<table class="ag-table"><tr><th>' + t('时间', 'Time') + '</th><th>' + t('步骤', 'Step') + '</th><th>' + t('模型', 'Model') + '</th><th>' + t('输入', 'Input') + '</th><th>' + t('输出', 'Output') + '</th><th>' + t('总计', 'Total') + '</th></tr>';
|
|
1142
1151
|
for (const r of records.reverse()) {
|
|
1143
1152
|
const stepName = r.step === 'L3_security_judge' ? t('L3 安全判断', 'L3 Security Judge') : r.step === 'step2_policy_gen' ? t('策略生成', 'Policy Generation') : escapeHtml(r.step);
|
|
1144
|
-
|
|
1145
|
-
|
|
1153
|
+
// timestamp 是 UTC ISO(带 Z),转本地时区显示
|
|
1154
|
+
let ts = '';
|
|
1155
|
+
try { ts = r.timestamp ? new Date(r.timestamp).toLocaleString() : ''; } catch { ts = r.timestamp || ''; }
|
|
1156
|
+
html += '<tr><td>' + escapeHtml(ts) + '</td><td>' + stepName + '</td><td style="color:var(--ag-text-secondary)">' + escapeHtml(r.model || '') + '</td><td>' + r.prompt_tokens + '</td><td>' + r.completion_tokens + '</td><td><strong>' + r.total_tokens + '</strong></td></tr>';
|
|
1146
1157
|
}
|
|
1147
1158
|
html += '</table>';
|
|
1159
|
+
// 分页控制条:上一页 / 页码显示 / 输入页码跳转 / 下一页
|
|
1160
|
+
const totalPages = Math.max(1, Math.ceil(total / TOKEN_RECENT_PAGE_SIZE));
|
|
1161
|
+
html += `<div style="margin-top:10px;display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap">
|
|
1162
|
+
<button class="ag-btn ag-btn-sm" onclick="tokenRecentPage<=1?null:loadTokenRecentPage(${tokenRecentPage - 1})" ${tokenRecentPage <= 1 ? 'disabled' : ''}>${t('上一页', 'Prev')}</button>
|
|
1163
|
+
<span style="font-size:var(--fs-md);color:var(--ag-text-secondary)">${t('第 ', 'Page ')}${tokenRecentPage} / ${totalPages}${t('(共 ', ' (total ')}${total}${t(' 条)', ')')}</span>
|
|
1164
|
+
<input id="token-recent-goto" type="number" min="1" max="${totalPages}" value="${tokenRecentPage}" style="width:60px;padding:3px 6px;font-size:var(--fs-md);border:1px solid var(--ag-input-border);border-radius:6px;background:var(--ag-input-bg);color:var(--ag-text);" placeholder="${tokenRecentPage}">
|
|
1165
|
+
<button class="ag-btn ag-btn-sm" onclick="goTokenRecentPage()">${t('跳转', 'Go')}</button>
|
|
1166
|
+
<button class="ag-btn ag-btn-sm" onclick="tokenRecentPage>=${totalPages}?null:loadTokenRecentPage(${tokenRecentPage + 1})" ${tokenRecentPage >= totalPages ? 'disabled' : ''}>${t('下一页', 'Next')}</button>
|
|
1167
|
+
</div>`;
|
|
1148
1168
|
recentEl.innerHTML = html;
|
|
1149
1169
|
} catch (e) { recentEl.innerHTML = `<div class="ag-empty">${t('加载失败', 'Load failed')}</div>`; }
|
|
1150
1170
|
}
|
|
1171
|
+
function loadTokenRecentPage(page) {
|
|
1172
|
+
tokenRecentPage = page;
|
|
1173
|
+
loadTokenRecent();
|
|
1174
|
+
}
|
|
1175
|
+
/** 跳转到用户输入的页码 */
|
|
1176
|
+
async function goTokenRecentPage() {
|
|
1177
|
+
const input = el('token-recent-goto');
|
|
1178
|
+
if (!input) return;
|
|
1179
|
+
const page = parseInt(input.value, 10);
|
|
1180
|
+
if (!page || page < 1) { showToast(t('页码无效', 'Invalid page number'), 'error'); return; }
|
|
1181
|
+
// 计算总页数,超出则跳到最后一页
|
|
1182
|
+
const totalPages = Math.max(1, Math.ceil(tokenRecentTotal / TOKEN_RECENT_PAGE_SIZE));
|
|
1183
|
+
const target = Math.min(page, totalPages);
|
|
1184
|
+
tokenRecentPage = target;
|
|
1185
|
+
loadTokenRecent();
|
|
1186
|
+
}
|
|
1151
1187
|
async function resetTokenStats() {
|
|
1152
1188
|
if (!confirm(t('确定清除所有 Token 统计数据?', 'Clear all Token statistics?'))) return;
|
|
1153
1189
|
try { await apiPost('token-stats/reset'); showToast(t('Token 统计已清除', 'Token statistics cleared')); loadTokenStats(7); }
|