@gracker/smartperfetto 1.0.20 → 1.0.21
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/agent/config/domainManifest.d.ts +5 -3
- package/dist/agent/config/domainManifest.d.ts.map +1 -1
- package/dist/agent/config/domainManifest.js +120 -5
- package/dist/agent/config/domainManifest.js.map +1 -1
- package/dist/agent/core/orchestratorTypes.d.ts +5 -0
- package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
- package/dist/agent/core/orchestratorTypes.js.map +1 -1
- package/dist/agent/scene/buildSmartChatReport.d.ts +13 -0
- package/dist/agent/scene/buildSmartChatReport.d.ts.map +1 -0
- package/dist/agent/scene/buildSmartChatReport.js +333 -0
- package/dist/agent/scene/buildSmartChatReport.js.map +1 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts +8 -4
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts.map +1 -1
- package/dist/agent/scene/sceneAnalysisJobRunner.js +78 -3
- package/dist/agent/scene/sceneAnalysisJobRunner.js.map +1 -1
- package/dist/agent/scene/sceneIntervalBuilder.d.ts +14 -5
- package/dist/agent/scene/sceneIntervalBuilder.d.ts.map +1 -1
- package/dist/agent/scene/sceneIntervalBuilder.js +578 -1
- package/dist/agent/scene/sceneIntervalBuilder.js.map +1 -1
- package/dist/agent/scene/sceneStage1Verifier.d.ts +8 -0
- package/dist/agent/scene/sceneStage1Verifier.d.ts.map +1 -0
- package/dist/agent/scene/sceneStage1Verifier.js +245 -0
- package/dist/agent/scene/sceneStage1Verifier.js.map +1 -0
- package/dist/agent/scene/sceneStoryService.d.ts +20 -2
- package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
- package/dist/agent/scene/sceneStoryService.js +238 -25
- package/dist/agent/scene/sceneStoryService.js.map +1 -1
- package/dist/agent/scene/smartCancelBridge.d.ts +13 -0
- package/dist/agent/scene/smartCancelBridge.d.ts.map +1 -0
- package/dist/agent/scene/smartCancelBridge.js +44 -0
- package/dist/agent/scene/smartCancelBridge.js.map +1 -0
- package/dist/agent/scene/smartDeepDiveDispatch.d.ts +15 -0
- package/dist/agent/scene/smartDeepDiveDispatch.d.ts.map +1 -0
- package/dist/agent/scene/smartDeepDiveDispatch.js +170 -0
- package/dist/agent/scene/smartDeepDiveDispatch.js.map +1 -0
- package/dist/agent/scene/types.d.ts +97 -6
- package/dist/agent/scene/types.d.ts.map +1 -1
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agentv3/strategyLoader.d.ts +3 -0
- package/dist/agentv3/strategyLoader.d.ts.map +1 -1
- package/dist/agentv3/strategyLoader.js +17 -4
- package/dist/agentv3/strategyLoader.js.map +1 -1
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -1
- package/dist/routes/agent/finalizeAgentDrivenSession.d.ts +67 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.d.ts.map +1 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.js +103 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.js.map +1 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.d.ts +42 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.d.ts.map +1 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.js +185 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.js.map +1 -0
- package/dist/routes/agentRoutes.d.ts.map +1 -1
- package/dist/routes/agentRoutes.js +285 -125
- package/dist/routes/agentRoutes.js.map +1 -1
- package/dist/scripts/verifyAgentSseScrolling.js +131 -8
- package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
- package/dist/services/sceneReport/sceneJobArtifactStore.d.ts +22 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.d.ts.map +1 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.js +65 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.js.map +1 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts +5 -3
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts.map +1 -1
- package/dist/services/sceneReport/sceneReportMemoryCache.js +15 -10
- package/dist/services/sceneReport/sceneReportMemoryCache.js.map +1 -1
- package/dist/services/sceneReport/sceneReportStore.d.ts +9 -4
- package/dist/services/sceneReport/sceneReportStore.d.ts.map +1 -1
- package/dist/services/sceneReport/sceneReportStore.js +27 -7
- package/dist/services/sceneReport/sceneReportStore.js.map +1 -1
- package/dist/services/traceProcessor/sqlSemaphore.d.ts +16 -0
- package/dist/services/traceProcessor/sqlSemaphore.d.ts.map +1 -0
- package/dist/services/traceProcessor/sqlSemaphore.js +63 -0
- package/dist/services/traceProcessor/sqlSemaphore.js.map +1 -0
- package/dist/types/dataContract.d.ts +1 -1
- package/dist/types/dataContract.d.ts.map +1 -1
- package/dist/types/dataContract.js +2 -0
- package/dist/types/dataContract.js.map +1 -1
- package/package.json +1 -1
- package/skills/README.md +13 -5
- package/skills/composite/device_state_snapshot.skill.yaml +204 -0
- package/skills/composite/scene_reconstruction.skill.yaml +5 -1
- package/strategies/scene-reconstruction-verifier.template.md +18 -0
- package/strategies/scrolling.strategy.md +5 -1
- package/strategies/smart.strategy.md +53 -0
- package/skills/atomic/device_state_snapshot.skill.yaml +0 -171
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2024-2026 Gracker (Chris)
|
|
3
|
+
# This file is part of SmartPerfetto. See LICENSE for details.
|
|
4
|
+
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# 设备环境状态快照(组合 Skill)
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# 采集指定窗口内的屏幕、电量、温度、频率、内存压力与 idle 状态。
|
|
9
|
+
|
|
10
|
+
name: device_state_snapshot
|
|
11
|
+
version: "2.0"
|
|
12
|
+
type: composite
|
|
13
|
+
category: system_context
|
|
14
|
+
tier: B
|
|
15
|
+
|
|
16
|
+
meta:
|
|
17
|
+
display_name: "设备环境状态快照"
|
|
18
|
+
description: "采集 trace 期间的设备环境信息(屏幕、电量、温度、CPU、内存、idle 窗口等)"
|
|
19
|
+
icon: "devices"
|
|
20
|
+
tags: [device, state, environment, context, composite]
|
|
21
|
+
|
|
22
|
+
prerequisites:
|
|
23
|
+
required_tables:
|
|
24
|
+
- slice
|
|
25
|
+
- counter
|
|
26
|
+
- counter_track
|
|
27
|
+
|
|
28
|
+
inputs:
|
|
29
|
+
- name: start_ts
|
|
30
|
+
type: timestamp
|
|
31
|
+
required: false
|
|
32
|
+
description: "分析起始时间戳(ns)"
|
|
33
|
+
- name: end_ts
|
|
34
|
+
type: timestamp
|
|
35
|
+
required: false
|
|
36
|
+
description: "分析结束时间戳(ns)"
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- id: environment_snapshot
|
|
40
|
+
type: atomic
|
|
41
|
+
name: "设备环境快照"
|
|
42
|
+
display:
|
|
43
|
+
level: summary
|
|
44
|
+
layer: overview
|
|
45
|
+
title: "设备环境状态"
|
|
46
|
+
columns:
|
|
47
|
+
- name: metric
|
|
48
|
+
label: "指标"
|
|
49
|
+
type: string
|
|
50
|
+
- name: value
|
|
51
|
+
label: "值"
|
|
52
|
+
type: string
|
|
53
|
+
- name: ts
|
|
54
|
+
label: "时间戳"
|
|
55
|
+
type: timestamp
|
|
56
|
+
unit: ns
|
|
57
|
+
clickAction: navigate_timeline
|
|
58
|
+
sql: |
|
|
59
|
+
WITH trace_bounds AS (
|
|
60
|
+
SELECT
|
|
61
|
+
COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
|
|
62
|
+
COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
|
|
63
|
+
),
|
|
64
|
+
screen_state AS (
|
|
65
|
+
SELECT
|
|
66
|
+
'screen_state' as metric,
|
|
67
|
+
CASE WHEN c.value > 0 THEN 'ON' ELSE 'OFF' END as value,
|
|
68
|
+
c.ts as ts
|
|
69
|
+
FROM counter c
|
|
70
|
+
JOIN counter_track ct ON c.track_id = ct.id
|
|
71
|
+
CROSS JOIN trace_bounds tb
|
|
72
|
+
WHERE (ct.name GLOB '*ScreenState*' OR ct.name GLOB '*screen_state*')
|
|
73
|
+
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
74
|
+
ORDER BY c.ts DESC
|
|
75
|
+
LIMIT 1
|
|
76
|
+
),
|
|
77
|
+
battery_info AS (
|
|
78
|
+
SELECT
|
|
79
|
+
'battery_level' as metric,
|
|
80
|
+
CAST(c.value AS TEXT) as value,
|
|
81
|
+
c.ts as ts
|
|
82
|
+
FROM counter c
|
|
83
|
+
JOIN counter_track ct ON c.track_id = ct.id
|
|
84
|
+
CROSS JOIN trace_bounds tb
|
|
85
|
+
WHERE (ct.name GLOB '*battery_level*' OR ct.name GLOB '*BatteryLevel*')
|
|
86
|
+
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
87
|
+
ORDER BY c.ts DESC
|
|
88
|
+
LIMIT 1
|
|
89
|
+
),
|
|
90
|
+
charging_info AS (
|
|
91
|
+
SELECT
|
|
92
|
+
'charging_state' as metric,
|
|
93
|
+
CASE WHEN c.value > 0 THEN 'CHARGING' ELSE 'NOT_CHARGING' END as value,
|
|
94
|
+
c.ts as ts
|
|
95
|
+
FROM counter c
|
|
96
|
+
JOIN counter_track ct ON c.track_id = ct.id
|
|
97
|
+
CROSS JOIN trace_bounds tb
|
|
98
|
+
WHERE (ct.name GLOB '*battery_status*' OR ct.name GLOB '*charging*' OR ct.name GLOB '*BatteryStatus*')
|
|
99
|
+
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
100
|
+
ORDER BY c.ts DESC
|
|
101
|
+
LIMIT 1
|
|
102
|
+
),
|
|
103
|
+
thermal_info AS (
|
|
104
|
+
SELECT
|
|
105
|
+
'thermal_zone' as metric,
|
|
106
|
+
ct.name || ': ' || CAST(ROUND(MAX(CASE WHEN c.value > 1000 THEN c.value / 1000.0 ELSE c.value END), 1) AS TEXT) || ' C' as value,
|
|
107
|
+
MAX(c.ts) as ts
|
|
108
|
+
FROM counter c
|
|
109
|
+
JOIN counter_track ct ON c.track_id = ct.id
|
|
110
|
+
CROSS JOIN trace_bounds tb
|
|
111
|
+
WHERE (ct.name GLOB '*thermal_zone*' OR ct.name GLOB '*Temperature*' OR ct.name GLOB '*temp*')
|
|
112
|
+
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
113
|
+
GROUP BY ct.name
|
|
114
|
+
ORDER BY MAX(c.value) DESC
|
|
115
|
+
LIMIT 5
|
|
116
|
+
),
|
|
117
|
+
memory_info AS (
|
|
118
|
+
SELECT
|
|
119
|
+
'memory_pressure' as metric,
|
|
120
|
+
ct.name || ': ' || CAST(ROUND(MAX(c.value), 0) AS TEXT) as value,
|
|
121
|
+
MAX(c.ts) as ts
|
|
122
|
+
FROM counter c
|
|
123
|
+
JOIN counter_track ct ON c.track_id = ct.id
|
|
124
|
+
CROSS JOIN trace_bounds tb
|
|
125
|
+
WHERE (ct.name GLOB '*mem.*pressure*' OR ct.name GLOB '*MemFree*' OR ct.name GLOB '*MemAvailable*' OR ct.name GLOB '*psi*mem*')
|
|
126
|
+
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
127
|
+
GROUP BY ct.name
|
|
128
|
+
ORDER BY MAX(c.value) DESC
|
|
129
|
+
LIMIT 5
|
|
130
|
+
)
|
|
131
|
+
SELECT metric, value, printf('%d', ts) as ts FROM screen_state
|
|
132
|
+
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM battery_info
|
|
133
|
+
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM charging_info
|
|
134
|
+
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM thermal_info
|
|
135
|
+
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM memory_info
|
|
136
|
+
save_as: environment_snapshot
|
|
137
|
+
synthesize:
|
|
138
|
+
role: overview
|
|
139
|
+
fields:
|
|
140
|
+
- key: metric
|
|
141
|
+
label: 指标
|
|
142
|
+
- key: value
|
|
143
|
+
label: 值
|
|
144
|
+
|
|
145
|
+
- id: idle_window_summary
|
|
146
|
+
type: atomic
|
|
147
|
+
name: "Idle 窗口摘要"
|
|
148
|
+
optional: true
|
|
149
|
+
display:
|
|
150
|
+
level: detail
|
|
151
|
+
layer: list
|
|
152
|
+
title: "Idle / 空闲窗口"
|
|
153
|
+
columns:
|
|
154
|
+
- name: start_ts
|
|
155
|
+
label: "开始"
|
|
156
|
+
type: timestamp
|
|
157
|
+
unit: ns
|
|
158
|
+
clickAction: navigate_timeline
|
|
159
|
+
- name: end_ts
|
|
160
|
+
label: "结束"
|
|
161
|
+
type: timestamp
|
|
162
|
+
unit: ns
|
|
163
|
+
clickAction: navigate_timeline
|
|
164
|
+
- name: dur_ms
|
|
165
|
+
label: "时长"
|
|
166
|
+
type: duration
|
|
167
|
+
unit: ms
|
|
168
|
+
- name: source
|
|
169
|
+
label: "来源"
|
|
170
|
+
type: string
|
|
171
|
+
sql: |
|
|
172
|
+
WITH trace_bounds AS (
|
|
173
|
+
SELECT
|
|
174
|
+
COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
|
|
175
|
+
COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
|
|
176
|
+
)
|
|
177
|
+
SELECT
|
|
178
|
+
printf('%d', s.ts) as start_ts,
|
|
179
|
+
printf('%d', s.ts + s.dur) as end_ts,
|
|
180
|
+
ROUND(s.dur / 1000000.0, 2) as dur_ms,
|
|
181
|
+
s.name as source
|
|
182
|
+
FROM slice s
|
|
183
|
+
CROSS JOIN trace_bounds tb
|
|
184
|
+
WHERE s.dur > 0
|
|
185
|
+
AND s.ts + s.dur > tb.t_start
|
|
186
|
+
AND s.ts < tb.t_end
|
|
187
|
+
AND (
|
|
188
|
+
s.name GLOB '*idle*'
|
|
189
|
+
OR s.name GLOB '*Idle*'
|
|
190
|
+
OR s.name GLOB '*suspend*'
|
|
191
|
+
OR s.name GLOB '*doze*'
|
|
192
|
+
)
|
|
193
|
+
ORDER BY s.dur DESC
|
|
194
|
+
LIMIT 20
|
|
195
|
+
save_as: idle_window_summary
|
|
196
|
+
synthesize:
|
|
197
|
+
role: list
|
|
198
|
+
fields:
|
|
199
|
+
- key: dur_ms
|
|
200
|
+
label: Idle 时长
|
|
201
|
+
format: "{{value}} ms"
|
|
202
|
+
|
|
203
|
+
output:
|
|
204
|
+
format: structured
|
|
@@ -573,6 +573,9 @@ steps:
|
|
|
573
573
|
- name: gesture_id
|
|
574
574
|
label: "手势ID"
|
|
575
575
|
type: number
|
|
576
|
+
- name: app_package
|
|
577
|
+
label: "前台应用"
|
|
578
|
+
type: string
|
|
576
579
|
- name: category
|
|
577
580
|
label: "类别"
|
|
578
581
|
type: string
|
|
@@ -633,6 +636,7 @@ steps:
|
|
|
633
636
|
ELSE ''
|
|
634
637
|
END AS event,
|
|
635
638
|
gesture_id,
|
|
639
|
+
app AS app_package,
|
|
636
640
|
'scroll_start' AS category,
|
|
637
641
|
'💡 此时刻手指已移动足够距离,系统开始响应滑动' AS explanation
|
|
638
642
|
FROM scroll_starts
|
|
@@ -2785,4 +2789,4 @@ steps:
|
|
|
2785
2789
|
|
|
2786
2790
|
output:
|
|
2787
2791
|
format: layered
|
|
2788
|
-
default_expanded: [L1, L2]
|
|
2792
|
+
default_expanded: [L1, L2]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
2
|
+
<!-- Copyright (C) 2024-2026 Gracker (Chris) -->
|
|
3
|
+
<!-- This file is part of SmartPerfetto. See LICENSE for details. -->
|
|
4
|
+
|
|
5
|
+
你是 Android Perfetto trace 的场景还原复核器。请检查下面的 Smart 场景时间线是否存在明显的拆分、合并、类型或归因问题。
|
|
6
|
+
|
|
7
|
+
只能基于输入证据判断,不要创造没有证据的场景。不要输出长报告。
|
|
8
|
+
|
|
9
|
+
请只输出 JSON,格式:{"status":"passed|needs_review","summary":"一句中文复核意见"}。
|
|
10
|
+
|
|
11
|
+
deterministic_summary:
|
|
12
|
+
{{deterministicSummary}}
|
|
13
|
+
|
|
14
|
+
deterministic_issues:
|
|
15
|
+
{{deterministicIssues}}
|
|
16
|
+
|
|
17
|
+
scenes:
|
|
18
|
+
{{scenes}}
|
|
@@ -107,7 +107,7 @@ phase_hints:
|
|
|
107
107
|
critical: false
|
|
108
108
|
- id: conclusion
|
|
109
109
|
keywords: ['结论', 'conclusion', '输出', 'output', '报告', 'report', '总结']
|
|
110
|
-
constraints: '输出必须包含:全帧根因分布表(按 reason_code 聚合)+ 代表帧分析(含四象限+频率+根因推理链)+ 按优先级排序的优化建议。每个 CRITICAL/HIGH
|
|
110
|
+
constraints: '输出必须包含:全帧根因分布表(按 reason_code 聚合)+ 代表帧分析(含四象限+频率+根因推理链)+ 按优先级排序的优化建议。每个 CRITICAL/HIGH 必须有量化证据+因果链。若深钻证据纠正了 batch reason_code(例如 lock_binder_wait 但 binder_overlap_ms=0,render_slices_json 指向 cache_miss/makePipeline/shader 编译),最终结论必须使用纠正后的根因命名,并明确标注原 reason_code 为误分类。'
|
|
111
111
|
critical_tools: []
|
|
112
112
|
critical: false
|
|
113
113
|
|
|
@@ -347,6 +347,10 @@ Phase 1 的 `batch_frame_root_cause` 已包含每帧的**完整统计数据**(
|
|
|
347
347
|
- **reason_code 为 unknown 且帧数 >5%**:必须对至少 1 帧调用 jank_frame_detail 获取更多线索,不能在分布表中仅标记"未分类"就跳过
|
|
348
348
|
- reason_code 与实际数据矛盾时(如 `lock_binder_wait` 但 Binder 耗时 0ms):应在结论中标注可能的误分类原因
|
|
349
349
|
|
|
350
|
+
如果深钻结果已给出更具体的根因,不要在最终报告继续把原始 `reason_code` 当作根因名称。典型例子:
|
|
351
|
+
- `lock_binder_wait` 但 `binder_overlap_ms=0`,且 `render_slices_json` 出现 `cache_miss: makePipeline` / shader 编译 / Vulkan finish frame / `postAndWait`,最终根因应写成 **shader_compile + sync_wait** 或等价机制,并说明 `lock_binder_wait` 是批量分类误判。
|
|
352
|
+
- `workload_heavy` 但 `main_slices_json` 明确指向应用自定义方法,最终根因应写具体方法名和所处阶段,例如 `CustomScroll_longFrameLoad` 在 ANIMATION 回调同步执行,而不是只写 "workload_heavy"。
|
|
353
|
+
|
|
350
354
|
`frame_blocking_calls` 是 Phase 1.9 的帧内阻塞证据补充,不占 `jank_frame_detail` 的 2 帧上限。遇到 Binder/IO/futex/锁相关根因时,优先用它确认阻塞调用是否真的与掉帧帧重叠。
|
|
351
355
|
|
|
352
356
|
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
Copyright (C) 2024-2026 Gracker (Chris)
|
|
4
|
+
This file is part of SmartPerfetto. See LICENSE for details.
|
|
5
|
+
-->
|
|
6
|
+
---
|
|
7
|
+
scene: smart
|
|
8
|
+
strategy_kind: contract_only
|
|
9
|
+
priority: 5
|
|
10
|
+
effort: high
|
|
11
|
+
keywords:
|
|
12
|
+
- smart
|
|
13
|
+
- 智能
|
|
14
|
+
- mixed trace
|
|
15
|
+
- 场景混合
|
|
16
|
+
required_capabilities: []
|
|
17
|
+
optional_capabilities: []
|
|
18
|
+
final_report_contract:
|
|
19
|
+
required_sections:
|
|
20
|
+
- id: scene_timeline
|
|
21
|
+
label: 场景时间线
|
|
22
|
+
description: 按时间顺序列出 trace 中检测到的关键用户操作和设备状态场景。
|
|
23
|
+
pattern_groups:
|
|
24
|
+
- ["场景时间线", "timeline", "时间线"]
|
|
25
|
+
- ["冷启动", "热启动", "滑动", "点击", "返回", "Home", "亮屏", "熄屏", "ANR"]
|
|
26
|
+
- id: per_scene_summary
|
|
27
|
+
label: 分场景摘要
|
|
28
|
+
description: 对每个被深度分析的场景给出关键指标、结论和证据引用。
|
|
29
|
+
pattern_groups:
|
|
30
|
+
- ["分场景", "逐场景", "per-scene"]
|
|
31
|
+
- ["证据", "指标", "耗时", "延迟", "帧"]
|
|
32
|
+
- id: cross_scene_narrative
|
|
33
|
+
label: 跨场景叙事
|
|
34
|
+
description: 总结多个场景之间的关联、共同瓶颈或前后影响。
|
|
35
|
+
pattern_groups:
|
|
36
|
+
- ["跨场景", "整体", "关联", "链路"]
|
|
37
|
+
- ["原因", "影响", "共同", "瓶颈"]
|
|
38
|
+
- id: bottleneck_ranking
|
|
39
|
+
label: 瓶颈排序
|
|
40
|
+
description: 按影响范围、严重度和可行动性给出优化优先级。
|
|
41
|
+
pattern_groups:
|
|
42
|
+
- ["瓶颈排序", "优先级", "ranking"]
|
|
43
|
+
- ["P0", "P1", "优先", "建议"]
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
# Smart Analysis Contract
|
|
47
|
+
|
|
48
|
+
This strategy is intentionally contract-only. It must not be injected as a
|
|
49
|
+
normal scene strategy and must not participate in scene classification.
|
|
50
|
+
|
|
51
|
+
Smart Analysis Mode combines Scene Story detection with profile-specific
|
|
52
|
+
deep-dive routes, then projects the resulting scene report into a readable chat
|
|
53
|
+
summary and the standard HTML report chain.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
# Copyright (C) 2024-2026 Gracker (Chris)
|
|
3
|
-
# This file is part of SmartPerfetto. See LICENSE for details.
|
|
4
|
-
|
|
5
|
-
# =============================================================================
|
|
6
|
-
# 设备环境状态快照(原子 Skill)
|
|
7
|
-
# =============================================================================
|
|
8
|
-
# 采集 trace 期间的设备环境信息:屏幕状态、电量、温度、CPU 频率、内存压力等。
|
|
9
|
-
|
|
10
|
-
name: device_state_snapshot
|
|
11
|
-
version: "1.0"
|
|
12
|
-
type: atomic
|
|
13
|
-
category: system_context
|
|
14
|
-
tier: B
|
|
15
|
-
|
|
16
|
-
meta:
|
|
17
|
-
display_name: "设备环境状态快照"
|
|
18
|
-
description: "采集 trace 期间的设备环境信息(屏幕、电量、温度、CPU、内存等)"
|
|
19
|
-
icon: "devices"
|
|
20
|
-
tags: [device, state, environment, context, atomic]
|
|
21
|
-
|
|
22
|
-
prerequisites:
|
|
23
|
-
required_tables:
|
|
24
|
-
- counter
|
|
25
|
-
- counter_track
|
|
26
|
-
|
|
27
|
-
inputs:
|
|
28
|
-
- name: start_ts
|
|
29
|
-
type: timestamp
|
|
30
|
-
required: false
|
|
31
|
-
description: "分析起始时间戳(ns)"
|
|
32
|
-
- name: end_ts
|
|
33
|
-
type: timestamp
|
|
34
|
-
required: false
|
|
35
|
-
description: "分析结束时间戳(ns)"
|
|
36
|
-
|
|
37
|
-
display:
|
|
38
|
-
level: summary
|
|
39
|
-
layer: overview
|
|
40
|
-
title: "设备环境状态"
|
|
41
|
-
columns:
|
|
42
|
-
- name: metric
|
|
43
|
-
label: "指标"
|
|
44
|
-
type: string
|
|
45
|
-
- name: value
|
|
46
|
-
label: "值"
|
|
47
|
-
type: string
|
|
48
|
-
- name: ts
|
|
49
|
-
label: "时间戳"
|
|
50
|
-
type: timestamp
|
|
51
|
-
unit: ns
|
|
52
|
-
clickAction: navigate_timeline
|
|
53
|
-
|
|
54
|
-
sql: |
|
|
55
|
-
WITH trace_bounds AS (
|
|
56
|
-
SELECT
|
|
57
|
-
COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
|
|
58
|
-
COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
|
|
59
|
-
),
|
|
60
|
-
screen_state AS (
|
|
61
|
-
SELECT
|
|
62
|
-
'screen_state' as metric,
|
|
63
|
-
CASE WHEN c.value > 0 THEN 'ON' ELSE 'OFF' END as value,
|
|
64
|
-
c.ts as ts
|
|
65
|
-
FROM counter c
|
|
66
|
-
JOIN counter_track ct ON c.track_id = ct.id
|
|
67
|
-
WHERE ct.name GLOB '*ScreenState*' OR ct.name GLOB '*screen_state*'
|
|
68
|
-
ORDER BY c.ts DESC
|
|
69
|
-
LIMIT 1
|
|
70
|
-
),
|
|
71
|
-
battery_info AS (
|
|
72
|
-
SELECT
|
|
73
|
-
'battery_level' as metric,
|
|
74
|
-
CAST(c.value AS TEXT) as value,
|
|
75
|
-
c.ts as ts
|
|
76
|
-
FROM counter c
|
|
77
|
-
JOIN counter_track ct ON c.track_id = ct.id
|
|
78
|
-
WHERE ct.name GLOB '*battery_level*' OR ct.name GLOB '*BatteryLevel*'
|
|
79
|
-
ORDER BY c.ts DESC
|
|
80
|
-
LIMIT 1
|
|
81
|
-
),
|
|
82
|
-
charging_info AS (
|
|
83
|
-
SELECT
|
|
84
|
-
'charging_state' as metric,
|
|
85
|
-
CASE WHEN c.value > 0 THEN 'CHARGING' ELSE 'NOT_CHARGING' END as value,
|
|
86
|
-
c.ts as ts
|
|
87
|
-
FROM counter c
|
|
88
|
-
JOIN counter_track ct ON c.track_id = ct.id
|
|
89
|
-
WHERE ct.name GLOB '*battery_status*' OR ct.name GLOB '*charging*' OR ct.name GLOB '*BatteryStatus*'
|
|
90
|
-
ORDER BY c.ts DESC
|
|
91
|
-
LIMIT 1
|
|
92
|
-
),
|
|
93
|
-
thermal_info AS (
|
|
94
|
-
SELECT
|
|
95
|
-
'thermal_zone' as metric,
|
|
96
|
-
ct.name || ': ' || CAST(ROUND(MAX(c.value) / 1000.0, 1) AS TEXT) || '°C' as value,
|
|
97
|
-
MAX(c.ts) as ts
|
|
98
|
-
FROM counter c
|
|
99
|
-
JOIN counter_track ct ON c.track_id = ct.id
|
|
100
|
-
CROSS JOIN trace_bounds tb
|
|
101
|
-
WHERE (ct.name GLOB '*thermal_zone*' OR ct.name GLOB '*Temperature*')
|
|
102
|
-
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
103
|
-
GROUP BY ct.name
|
|
104
|
-
ORDER BY MAX(c.value) DESC
|
|
105
|
-
LIMIT 5
|
|
106
|
-
),
|
|
107
|
-
cpu_freq_summary AS (
|
|
108
|
-
SELECT
|
|
109
|
-
'cpu_max_freq' as metric,
|
|
110
|
-
'CPU' || ct.name || ': ' || CAST(ROUND(MAX(c.value) / 1e6, 2) AS TEXT) || 'GHz' as value,
|
|
111
|
-
MAX(c.ts) as ts
|
|
112
|
-
FROM counter c
|
|
113
|
-
JOIN cpu_counter_track ct ON c.track_id = ct.id
|
|
114
|
-
CROSS JOIN trace_bounds tb
|
|
115
|
-
WHERE ct.name = 'cpufreq'
|
|
116
|
-
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
117
|
-
GROUP BY ct.cpu
|
|
118
|
-
ORDER BY ct.cpu
|
|
119
|
-
),
|
|
120
|
-
memory_info AS (
|
|
121
|
-
SELECT
|
|
122
|
-
'memory_pressure' as metric,
|
|
123
|
-
CAST(ROUND(MAX(c.value), 0) AS TEXT) as value,
|
|
124
|
-
MAX(c.ts) as ts
|
|
125
|
-
FROM counter c
|
|
126
|
-
JOIN counter_track ct ON c.track_id = ct.id
|
|
127
|
-
CROSS JOIN trace_bounds tb
|
|
128
|
-
WHERE (ct.name GLOB '*mem.*pressure*' OR ct.name GLOB '*MemFree*' OR ct.name GLOB '*MemAvailable*')
|
|
129
|
-
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
130
|
-
),
|
|
131
|
-
process_count AS (
|
|
132
|
-
SELECT
|
|
133
|
-
'active_processes' as metric,
|
|
134
|
-
CAST(COUNT(DISTINCT p.upid) AS TEXT) as value,
|
|
135
|
-
NULL as ts
|
|
136
|
-
FROM process p
|
|
137
|
-
JOIN thread t ON t.upid = p.upid
|
|
138
|
-
JOIN thread_state ts_tbl ON ts_tbl.utid = t.utid
|
|
139
|
-
CROSS JOIN trace_bounds tb
|
|
140
|
-
WHERE ts_tbl.ts >= tb.t_start AND ts_tbl.ts <= tb.t_end
|
|
141
|
-
AND ts_tbl.state = 'Running'
|
|
142
|
-
),
|
|
143
|
-
oom_adj AS (
|
|
144
|
-
SELECT
|
|
145
|
-
'foreground_apps' as metric,
|
|
146
|
-
GROUP_CONCAT(p.name, ', ') as value,
|
|
147
|
-
NULL as ts
|
|
148
|
-
FROM (
|
|
149
|
-
SELECT DISTINCT p.name, p.upid
|
|
150
|
-
FROM counter c
|
|
151
|
-
JOIN process_counter_track pct ON c.track_id = pct.id
|
|
152
|
-
JOIN process p ON p.upid = pct.upid
|
|
153
|
-
CROSS JOIN trace_bounds tb
|
|
154
|
-
WHERE pct.name = 'oom_score_adj'
|
|
155
|
-
AND c.value <= 0
|
|
156
|
-
AND c.ts >= tb.t_start AND c.ts <= tb.t_end
|
|
157
|
-
AND p.name IS NOT NULL AND p.name != ''
|
|
158
|
-
LIMIT 10
|
|
159
|
-
) p
|
|
160
|
-
)
|
|
161
|
-
SELECT metric, value, printf('%d', ts) as ts FROM screen_state
|
|
162
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM battery_info
|
|
163
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM charging_info
|
|
164
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM thermal_info
|
|
165
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM cpu_freq_summary
|
|
166
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM memory_info
|
|
167
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM process_count
|
|
168
|
-
UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM oom_adj
|
|
169
|
-
|
|
170
|
-
output:
|
|
171
|
-
format: structured
|