ec-web 0.0.25 → 0.0.26
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/LICENSE +21 -21
- package/README.md +17 -17
- package/dist/index.js +0 -0
- package/dist/paths.js +8 -1
- package/dist/server.js +7 -5
- package/dist/sources/aid.js +28 -13
- package/dist/sources/basic-settings.js +7 -27
- package/dist/sources/relation-roles.js +23 -9
- package/dist/sources/role-definitions.js +6 -5
- package/dist/sources/session-codex.js +11 -11
- package/dist/sources/stats.js +92 -92
- package/dist/sources/types.js +1 -0
- package/dist/static/app.js +11691 -11691
- package/dist/static/index.html +427 -427
- package/dist/static/style.css +4899 -4899
- package/dist/static/vendor/echarts-5.6.0.min.js +45 -45
- package/ecweb-wrapper.cjs +67 -67
- package/package.json +35 -35
package/dist/sources/stats.js
CHANGED
|
@@ -46,41 +46,41 @@ export function queryStatsForDashboard() {
|
|
|
46
46
|
const h24ago = Date.now() - 24 * 60 * 60 * 1000;
|
|
47
47
|
try {
|
|
48
48
|
// Today summary with cost
|
|
49
|
-
const todayRow = db.prepare(`
|
|
50
|
-
SELECT
|
|
51
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
52
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
53
|
-
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
54
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
55
|
-
COUNT(*) AS call_count,
|
|
56
|
-
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
57
|
-
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
58
|
-
FROM usage_events WHERE ts >= ?
|
|
49
|
+
const todayRow = db.prepare(`
|
|
50
|
+
SELECT
|
|
51
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
52
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
53
|
+
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
54
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
55
|
+
COUNT(*) AS call_count,
|
|
56
|
+
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
57
|
+
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
58
|
+
FROM usage_events WHERE ts >= ?
|
|
59
59
|
`).get(todayStart);
|
|
60
60
|
const totalIn = (todayRow.input_tokens ?? 0) + (todayRow.cache_read_tokens ?? 0);
|
|
61
61
|
const hitRate = totalIn > 0 ? (todayRow.cache_read_tokens ?? 0) / totalIn : 0;
|
|
62
62
|
// Hourly (last 24h)
|
|
63
|
-
const hourly = db.prepare(`
|
|
64
|
-
SELECT
|
|
65
|
-
strftime('%Y-%m-%d %H:00', ts/1000, 'unixepoch', 'localtime') AS hour,
|
|
66
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
67
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
68
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
69
|
-
COUNT(*) AS call_count
|
|
70
|
-
FROM usage_events WHERE ts >= ?
|
|
71
|
-
GROUP BY hour ORDER BY hour
|
|
63
|
+
const hourly = db.prepare(`
|
|
64
|
+
SELECT
|
|
65
|
+
strftime('%Y-%m-%d %H:00', ts/1000, 'unixepoch', 'localtime') AS hour,
|
|
66
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
67
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
68
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
69
|
+
COUNT(*) AS call_count
|
|
70
|
+
FROM usage_events WHERE ts >= ?
|
|
71
|
+
GROUP BY hour ORDER BY hour
|
|
72
72
|
`).all(h24ago);
|
|
73
73
|
// Top models (today)
|
|
74
|
-
const top_models = db.prepare(`
|
|
75
|
-
SELECT model, SUM(input_tokens+output_tokens) AS total_tokens, COUNT(*) AS call_count
|
|
76
|
-
FROM usage_events WHERE ts >= ?
|
|
77
|
-
GROUP BY model ORDER BY total_tokens DESC LIMIT 10
|
|
74
|
+
const top_models = db.prepare(`
|
|
75
|
+
SELECT model, SUM(input_tokens+output_tokens) AS total_tokens, COUNT(*) AS call_count
|
|
76
|
+
FROM usage_events WHERE ts >= ?
|
|
77
|
+
GROUP BY model ORDER BY total_tokens DESC LIMIT 10
|
|
78
78
|
`).all(todayStart);
|
|
79
79
|
// Top peers (today)
|
|
80
|
-
const top_peers = db.prepare(`
|
|
81
|
-
SELECT peer_key, SUM(input_tokens+output_tokens) AS total_tokens, COUNT(*) AS call_count
|
|
82
|
-
FROM usage_events WHERE ts >= ?
|
|
83
|
-
GROUP BY peer_key ORDER BY total_tokens DESC LIMIT 5
|
|
80
|
+
const top_peers = db.prepare(`
|
|
81
|
+
SELECT peer_key, SUM(input_tokens+output_tokens) AS total_tokens, COUNT(*) AS call_count
|
|
82
|
+
FROM usage_events WHERE ts >= ?
|
|
83
|
+
GROUP BY peer_key ORDER BY total_tokens DESC LIMIT 5
|
|
84
84
|
`).all(todayStart);
|
|
85
85
|
return {
|
|
86
86
|
today: { ...todayRow, cache_hit_rate: hitRate },
|
|
@@ -124,16 +124,16 @@ export function queryStatsExplorer(params) {
|
|
|
124
124
|
}
|
|
125
125
|
const where = conds.length ? 'WHERE ' + conds.join(' AND ') : '';
|
|
126
126
|
try {
|
|
127
|
-
return db.prepare(`
|
|
128
|
-
SELECT
|
|
129
|
-
strftime('${strfmt}', ts/1000, 'unixepoch', 'localtime') AS period,
|
|
130
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
131
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
132
|
-
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
133
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
134
|
-
COUNT(*) AS call_count
|
|
135
|
-
FROM usage_events ${where}
|
|
136
|
-
GROUP BY period ORDER BY period
|
|
127
|
+
return db.prepare(`
|
|
128
|
+
SELECT
|
|
129
|
+
strftime('${strfmt}', ts/1000, 'unixepoch', 'localtime') AS period,
|
|
130
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
131
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
132
|
+
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
133
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
134
|
+
COUNT(*) AS call_count
|
|
135
|
+
FROM usage_events ${where}
|
|
136
|
+
GROUP BY period ORDER BY period
|
|
137
137
|
`).all(...p);
|
|
138
138
|
}
|
|
139
139
|
finally {
|
|
@@ -162,14 +162,14 @@ export function queryStatsByPeer(params) {
|
|
|
162
162
|
const where = conds.length ? 'WHERE ' + conds.join(' AND ') : '';
|
|
163
163
|
const limit = params.limit ?? 50;
|
|
164
164
|
try {
|
|
165
|
-
const rows = db.prepare(`
|
|
166
|
-
SELECT peer_key, peer_type,
|
|
167
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
168
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
169
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
170
|
-
COUNT(*) AS call_count
|
|
171
|
-
FROM usage_events ${where}
|
|
172
|
-
GROUP BY peer_key ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC LIMIT ${limit}
|
|
165
|
+
const rows = db.prepare(`
|
|
166
|
+
SELECT peer_key, peer_type,
|
|
167
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
168
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
169
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
170
|
+
COUNT(*) AS call_count
|
|
171
|
+
FROM usage_events ${where}
|
|
172
|
+
GROUP BY peer_key ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC LIMIT ${limit}
|
|
173
173
|
`).all(...p);
|
|
174
174
|
// 为每个peer添加名称和详细信息
|
|
175
175
|
return rows.map((row) => {
|
|
@@ -212,34 +212,34 @@ export function queryStatsOverview(params) {
|
|
|
212
212
|
}
|
|
213
213
|
const where = conds.length ? 'WHERE ' + conds.join(' AND ') : '';
|
|
214
214
|
// Token and cost aggregation with filters
|
|
215
|
-
const allRow = db.prepare(`
|
|
216
|
-
SELECT
|
|
217
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
218
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
219
|
-
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
220
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
221
|
-
COUNT(*) AS call_count,
|
|
222
|
-
COALESCE(SUM(cost_official_usd),0) AS cost_official_usd,
|
|
223
|
-
COALESCE(SUM(cost_official_cny),0) AS cost_official_cny,
|
|
224
|
-
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
225
|
-
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
226
|
-
FROM usage_events ${where}
|
|
215
|
+
const allRow = db.prepare(`
|
|
216
|
+
SELECT
|
|
217
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
218
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
219
|
+
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
220
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
221
|
+
COUNT(*) AS call_count,
|
|
222
|
+
COALESCE(SUM(cost_official_usd),0) AS cost_official_usd,
|
|
223
|
+
COALESCE(SUM(cost_official_cny),0) AS cost_official_cny,
|
|
224
|
+
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
225
|
+
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
226
|
+
FROM usage_events ${where}
|
|
227
227
|
`).get(...p);
|
|
228
228
|
// By agent aggregation with filters
|
|
229
|
-
const byAgentRows = db.prepare(`
|
|
230
|
-
SELECT agent_aid,
|
|
231
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
232
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
233
|
-
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
234
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
235
|
-
COUNT(*) AS call_count,
|
|
236
|
-
COALESCE(SUM(cost_official_usd),0) AS cost_official_usd,
|
|
237
|
-
COALESCE(SUM(cost_official_cny),0) AS cost_official_cny,
|
|
238
|
-
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
239
|
-
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
240
|
-
FROM usage_events ${where}
|
|
241
|
-
GROUP BY agent_aid
|
|
242
|
-
ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC
|
|
229
|
+
const byAgentRows = db.prepare(`
|
|
230
|
+
SELECT agent_aid,
|
|
231
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
232
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
233
|
+
COALESCE(SUM(cache_creation_tokens),0) AS cache_creation_tokens,
|
|
234
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
235
|
+
COUNT(*) AS call_count,
|
|
236
|
+
COALESCE(SUM(cost_official_usd),0) AS cost_official_usd,
|
|
237
|
+
COALESCE(SUM(cost_official_cny),0) AS cost_official_cny,
|
|
238
|
+
COALESCE(SUM(cost_gateway_usd),0) AS cost_usd,
|
|
239
|
+
COALESCE(SUM(cost_gateway_cny),0) AS cost_cny
|
|
240
|
+
FROM usage_events ${where}
|
|
241
|
+
GROUP BY agent_aid
|
|
242
|
+
ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC
|
|
243
243
|
`).all(...p);
|
|
244
244
|
// 为每个agent添加名称
|
|
245
245
|
const byAgentWithNames = byAgentRows.map((row) => ({
|
|
@@ -303,14 +303,14 @@ export function queryStatsByAgent(params) {
|
|
|
303
303
|
const where = conds.length ? 'WHERE ' + conds.join(' AND ') : '';
|
|
304
304
|
const limit = params.limit ?? 50;
|
|
305
305
|
try {
|
|
306
|
-
const rows = db.prepare(`
|
|
307
|
-
SELECT agent_aid,
|
|
308
|
-
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
309
|
-
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
310
|
-
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
311
|
-
COUNT(*) AS call_count
|
|
312
|
-
FROM usage_events ${where}
|
|
313
|
-
GROUP BY agent_aid ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC LIMIT ${limit}
|
|
306
|
+
const rows = db.prepare(`
|
|
307
|
+
SELECT agent_aid,
|
|
308
|
+
COALESCE(SUM(input_tokens),0) AS input_tokens,
|
|
309
|
+
COALESCE(SUM(output_tokens),0) AS output_tokens,
|
|
310
|
+
COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens,
|
|
311
|
+
COUNT(*) AS call_count
|
|
312
|
+
FROM usage_events ${where}
|
|
313
|
+
GROUP BY agent_aid ORDER BY (COALESCE(SUM(input_tokens),0) + COALESCE(SUM(output_tokens),0)) DESC LIMIT ${limit}
|
|
314
314
|
`).all(...p);
|
|
315
315
|
// 为每个agent添加名称
|
|
316
316
|
return rows.map((row) => ({
|
|
@@ -353,15 +353,15 @@ export function queryUsageDetail(params) {
|
|
|
353
353
|
const countRow = db.prepare(`SELECT COUNT(*) as total FROM usage_events ${where}`).get(...p);
|
|
354
354
|
const total = countRow?.total || 0;
|
|
355
355
|
// 获取数据
|
|
356
|
-
const data = db.prepare(`
|
|
357
|
-
SELECT ts, agent_aid, peer_key, model,
|
|
358
|
-
input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens,
|
|
359
|
-
COALESCE(cost_official_usd, 0) AS cost_official_usd,
|
|
360
|
-
COALESCE(cost_official_cny, 0) AS cost_official_cny,
|
|
361
|
-
COALESCE(cost_gateway_usd, 0) AS cost_gateway_usd,
|
|
362
|
-
COALESCE(cost_gateway_cny, 0) AS cost_gateway_cny
|
|
363
|
-
FROM usage_events ${where}
|
|
364
|
-
ORDER BY ts DESC LIMIT ${limit} OFFSET ${offset}
|
|
356
|
+
const data = db.prepare(`
|
|
357
|
+
SELECT ts, agent_aid, peer_key, model,
|
|
358
|
+
input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens,
|
|
359
|
+
COALESCE(cost_official_usd, 0) AS cost_official_usd,
|
|
360
|
+
COALESCE(cost_official_cny, 0) AS cost_official_cny,
|
|
361
|
+
COALESCE(cost_gateway_usd, 0) AS cost_gateway_usd,
|
|
362
|
+
COALESCE(cost_gateway_cny, 0) AS cost_gateway_cny
|
|
363
|
+
FROM usage_events ${where}
|
|
364
|
+
ORDER BY ts DESC LIMIT ${limit} OFFSET ${offset}
|
|
365
365
|
`).all(...p);
|
|
366
366
|
// 为每条记录添加agent_name (需要从文件系统读取agent.md)
|
|
367
367
|
const dataWithNames = data.map((row) => ({
|
|
@@ -391,10 +391,10 @@ export function queryUsedModels(params) {
|
|
|
391
391
|
}
|
|
392
392
|
const where = conds.length ? 'WHERE ' + conds.join(' AND ') : '';
|
|
393
393
|
try {
|
|
394
|
-
const rows = db.prepare(`
|
|
395
|
-
SELECT DISTINCT model
|
|
396
|
-
FROM usage_events ${where}
|
|
397
|
-
ORDER BY model
|
|
394
|
+
const rows = db.prepare(`
|
|
395
|
+
SELECT DISTINCT model
|
|
396
|
+
FROM usage_events ${where}
|
|
397
|
+
ORDER BY model
|
|
398
398
|
`).all(...p);
|
|
399
399
|
return rows.map((row) => row.model).filter(Boolean);
|
|
400
400
|
}
|
package/dist/sources/types.js
CHANGED
|
@@ -13,6 +13,7 @@ export function watchMenuAuth(params) {
|
|
|
13
13
|
return {
|
|
14
14
|
localDirect: auth?.localDirect === true,
|
|
15
15
|
actorAid: typeof auth?.actorAid === 'string' ? auth.actorAid : null,
|
|
16
|
+
daemonOwner: auth?.daemonOwner === true,
|
|
16
17
|
// This marker is injected by the ECWeb server, never read from browser
|
|
17
18
|
// request parameters. Authenticated ECWeb has daemon-owner authority.
|
|
18
19
|
canApprovePersistentFullAccess: auth?.canApprovePersistentFullAccess === true,
|