MCPcopy Index your code
hub / github.com/ChatLab/ChatLab / handler

Function handler

packages/tools/src/definitions/response-time-analysis.ts:24–103  ·  view source on GitHub ↗
(params: Record<string, unknown>, context: ToolExecutionContext)

Source from the content-addressed store, hash-verified

22}
23
24async function handler(params: Record<string, unknown>, context: ToolExecutionContext): Promise<ToolResult> {
25 const { locale } = context
26 const isZh = isChineseLocale(locale)
27 const days = (params.days as number) || 30
28 const topN = (params.top_n as number) || 10
29
30 const sql = `
31 SELECT msg.sender_id, COALESCE(m.group_nickname, m.account_name) AS name, msg.ts
32 FROM message msg
33 JOIN member m ON msg.sender_id = m.id
34 WHERE msg.type = 0
35 AND msg.ts > unixepoch('now', '-' || @days || ' days')
36 ORDER BY msg.ts ASC
37 `
38 const rows = await context.dataProvider!.executeParameterizedSql<MsgRow>(sql, { days })
39 if (!rows || rows.length < 2) {
40 const text = isZh
41 ? '该时间范围内消息不足,无法分析响应时间'
42 : 'Not enough messages in this time range to analyze response time'
43 return { content: text, data: null }
44 }
45
46 const responseTimes = new Map<number, { name: string; times: number[] }>()
47
48 for (let i = 1; i < rows.length; i++) {
49 const prev = rows[i - 1]
50 const curr = rows[i]
51 if (curr.sender_id === prev.sender_id) continue
52
53 const gap = curr.ts - prev.ts
54 if (gap < 5 || gap > 1800) continue
55
56 if (!responseTimes.has(curr.sender_id)) {
57 responseTimes.set(curr.sender_id, { name: curr.name, times: [] })
58 }
59 responseTimes.get(curr.sender_id)!.times.push(gap)
60 }
61
62 const stats = [...responseTimes.entries()]
63 .map(([id, { name, times }]) => {
64 times.sort((a, b) => a - b)
65 const avg = Math.round(times.reduce((s, t) => s + t, 0) / times.length)
66 const median = times[Math.floor(times.length / 2)]
67 return { id, name, avgSeconds: avg, medianSeconds: median, responseCount: times.length }
68 })
69 .filter((s) => s.responseCount >= 3)
70 .sort((a, b) => a.medianSeconds - b.medianSeconds)
71 .slice(0, topN)
72
73 if (stats.length === 0) {
74 const text = isZh ? '没有足够的响应数据进行分析' : 'Not enough response data for analysis'
75 return { content: text, data: null }
76 }
77
78 const formatTime = (s: number) => {
79 if (s < 60) return isZh ? `${s}秒` : `${s}s`
80 const m = Math.floor(s / 60)
81 const sec = s % 60

Callers

nothing calls this directly

Calls 4

isChineseLocaleFunction · 0.90
setMethod · 0.80
formatTimeFunction · 0.70
getMethod · 0.65

Tested by

no test coverage detected