htmlgraph 0.20.1__py3-none-any.whl → 0.27.5__py3-none-any.whl

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.
Files changed (304) hide show
  1. htmlgraph/.htmlgraph/.session-warning-state.json +6 -0
  2. htmlgraph/.htmlgraph/agents.json +72 -0
  3. htmlgraph/.htmlgraph/htmlgraph.db +0 -0
  4. htmlgraph/__init__.py +51 -1
  5. htmlgraph/__init__.pyi +123 -0
  6. htmlgraph/agent_detection.py +26 -10
  7. htmlgraph/agent_registry.py +2 -1
  8. htmlgraph/analytics/__init__.py +8 -1
  9. htmlgraph/analytics/cli.py +86 -20
  10. htmlgraph/analytics/cost_analyzer.py +391 -0
  11. htmlgraph/analytics/cost_monitor.py +664 -0
  12. htmlgraph/analytics/cost_reporter.py +675 -0
  13. htmlgraph/analytics/cross_session.py +617 -0
  14. htmlgraph/analytics/dependency.py +10 -6
  15. htmlgraph/analytics/pattern_learning.py +771 -0
  16. htmlgraph/analytics/session_graph.py +707 -0
  17. htmlgraph/analytics/strategic/__init__.py +80 -0
  18. htmlgraph/analytics/strategic/cost_optimizer.py +611 -0
  19. htmlgraph/analytics/strategic/pattern_detector.py +876 -0
  20. htmlgraph/analytics/strategic/preference_manager.py +709 -0
  21. htmlgraph/analytics/strategic/suggestion_engine.py +747 -0
  22. htmlgraph/analytics/work_type.py +67 -27
  23. htmlgraph/analytics_index.py +53 -20
  24. htmlgraph/api/__init__.py +3 -0
  25. htmlgraph/api/cost_alerts_websocket.py +416 -0
  26. htmlgraph/api/main.py +2498 -0
  27. htmlgraph/api/static/htmx.min.js +1 -0
  28. htmlgraph/api/static/style-redesign.css +1344 -0
  29. htmlgraph/api/static/style.css +1079 -0
  30. htmlgraph/api/templates/dashboard-redesign.html +1366 -0
  31. htmlgraph/api/templates/dashboard.html +794 -0
  32. htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
  33. htmlgraph/api/templates/partials/activity-feed.html +1100 -0
  34. htmlgraph/api/templates/partials/agents-redesign.html +317 -0
  35. htmlgraph/api/templates/partials/agents.html +317 -0
  36. htmlgraph/api/templates/partials/event-traces.html +373 -0
  37. htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
  38. htmlgraph/api/templates/partials/features.html +578 -0
  39. htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
  40. htmlgraph/api/templates/partials/metrics.html +346 -0
  41. htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
  42. htmlgraph/api/templates/partials/orchestration.html +198 -0
  43. htmlgraph/api/templates/partials/spawners.html +375 -0
  44. htmlgraph/api/templates/partials/work-items.html +613 -0
  45. htmlgraph/api/websocket.py +538 -0
  46. htmlgraph/archive/__init__.py +24 -0
  47. htmlgraph/archive/bloom.py +234 -0
  48. htmlgraph/archive/fts.py +297 -0
  49. htmlgraph/archive/manager.py +583 -0
  50. htmlgraph/archive/search.py +244 -0
  51. htmlgraph/atomic_ops.py +560 -0
  52. htmlgraph/attribute_index.py +2 -1
  53. htmlgraph/bounded_paths.py +539 -0
  54. htmlgraph/builders/base.py +57 -2
  55. htmlgraph/builders/bug.py +19 -3
  56. htmlgraph/builders/chore.py +19 -3
  57. htmlgraph/builders/epic.py +19 -3
  58. htmlgraph/builders/feature.py +27 -3
  59. htmlgraph/builders/insight.py +2 -1
  60. htmlgraph/builders/metric.py +2 -1
  61. htmlgraph/builders/pattern.py +2 -1
  62. htmlgraph/builders/phase.py +19 -3
  63. htmlgraph/builders/spike.py +29 -3
  64. htmlgraph/builders/track.py +42 -1
  65. htmlgraph/cigs/__init__.py +81 -0
  66. htmlgraph/cigs/autonomy.py +385 -0
  67. htmlgraph/cigs/cost.py +475 -0
  68. htmlgraph/cigs/messages_basic.py +472 -0
  69. htmlgraph/cigs/messaging.py +365 -0
  70. htmlgraph/cigs/models.py +771 -0
  71. htmlgraph/cigs/pattern_storage.py +427 -0
  72. htmlgraph/cigs/patterns.py +503 -0
  73. htmlgraph/cigs/posttool_analyzer.py +234 -0
  74. htmlgraph/cigs/reporter.py +818 -0
  75. htmlgraph/cigs/tracker.py +317 -0
  76. htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
  77. htmlgraph/cli/.htmlgraph/agents.json +72 -0
  78. htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
  79. htmlgraph/cli/__init__.py +42 -0
  80. htmlgraph/cli/__main__.py +6 -0
  81. htmlgraph/cli/analytics.py +1424 -0
  82. htmlgraph/cli/base.py +685 -0
  83. htmlgraph/cli/constants.py +206 -0
  84. htmlgraph/cli/core.py +954 -0
  85. htmlgraph/cli/main.py +147 -0
  86. htmlgraph/cli/models.py +475 -0
  87. htmlgraph/cli/templates/__init__.py +1 -0
  88. htmlgraph/cli/templates/cost_dashboard.py +399 -0
  89. htmlgraph/cli/work/__init__.py +239 -0
  90. htmlgraph/cli/work/browse.py +115 -0
  91. htmlgraph/cli/work/features.py +568 -0
  92. htmlgraph/cli/work/orchestration.py +676 -0
  93. htmlgraph/cli/work/report.py +728 -0
  94. htmlgraph/cli/work/sessions.py +466 -0
  95. htmlgraph/cli/work/snapshot.py +559 -0
  96. htmlgraph/cli/work/tracks.py +486 -0
  97. htmlgraph/cli_commands/__init__.py +1 -0
  98. htmlgraph/cli_commands/feature.py +195 -0
  99. htmlgraph/cli_framework.py +115 -0
  100. htmlgraph/collections/__init__.py +2 -0
  101. htmlgraph/collections/base.py +197 -14
  102. htmlgraph/collections/bug.py +2 -1
  103. htmlgraph/collections/chore.py +2 -1
  104. htmlgraph/collections/epic.py +2 -1
  105. htmlgraph/collections/feature.py +2 -1
  106. htmlgraph/collections/insight.py +2 -1
  107. htmlgraph/collections/metric.py +2 -1
  108. htmlgraph/collections/pattern.py +2 -1
  109. htmlgraph/collections/phase.py +2 -1
  110. htmlgraph/collections/session.py +194 -0
  111. htmlgraph/collections/spike.py +13 -2
  112. htmlgraph/collections/task_delegation.py +241 -0
  113. htmlgraph/collections/todo.py +14 -1
  114. htmlgraph/collections/traces.py +487 -0
  115. htmlgraph/config/cost_models.json +56 -0
  116. htmlgraph/config.py +190 -0
  117. htmlgraph/context_analytics.py +2 -1
  118. htmlgraph/converter.py +116 -7
  119. htmlgraph/cost_analysis/__init__.py +5 -0
  120. htmlgraph/cost_analysis/analyzer.py +438 -0
  121. htmlgraph/dashboard.html +2246 -248
  122. htmlgraph/dashboard.html.backup +6592 -0
  123. htmlgraph/dashboard.html.bak +7181 -0
  124. htmlgraph/dashboard.html.bak2 +7231 -0
  125. htmlgraph/dashboard.html.bak3 +7232 -0
  126. htmlgraph/db/__init__.py +38 -0
  127. htmlgraph/db/queries.py +790 -0
  128. htmlgraph/db/schema.py +1788 -0
  129. htmlgraph/decorators.py +317 -0
  130. htmlgraph/dependency_models.py +2 -1
  131. htmlgraph/deploy.py +26 -27
  132. htmlgraph/docs/API_REFERENCE.md +841 -0
  133. htmlgraph/docs/HTTP_API.md +750 -0
  134. htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
  135. htmlgraph/docs/ORCHESTRATION_PATTERNS.md +717 -0
  136. htmlgraph/docs/README.md +532 -0
  137. htmlgraph/docs/__init__.py +77 -0
  138. htmlgraph/docs/docs_version.py +55 -0
  139. htmlgraph/docs/metadata.py +93 -0
  140. htmlgraph/docs/migrations.py +232 -0
  141. htmlgraph/docs/template_engine.py +143 -0
  142. htmlgraph/docs/templates/_sections/cli_reference.md.j2 +52 -0
  143. htmlgraph/docs/templates/_sections/core_concepts.md.j2 +29 -0
  144. htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +69 -0
  145. htmlgraph/docs/templates/base_agents.md.j2 +78 -0
  146. htmlgraph/docs/templates/example_user_override.md.j2 +47 -0
  147. htmlgraph/docs/version_check.py +163 -0
  148. htmlgraph/edge_index.py +2 -1
  149. htmlgraph/error_handler.py +544 -0
  150. htmlgraph/event_log.py +86 -37
  151. htmlgraph/event_migration.py +2 -1
  152. htmlgraph/file_watcher.py +12 -8
  153. htmlgraph/find_api.py +2 -1
  154. htmlgraph/git_events.py +67 -9
  155. htmlgraph/hooks/.htmlgraph/.session-warning-state.json +6 -0
  156. htmlgraph/hooks/.htmlgraph/agents.json +72 -0
  157. htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
  158. htmlgraph/hooks/__init__.py +8 -0
  159. htmlgraph/hooks/bootstrap.py +169 -0
  160. htmlgraph/hooks/cigs_pretool_enforcer.py +354 -0
  161. htmlgraph/hooks/concurrent_sessions.py +208 -0
  162. htmlgraph/hooks/context.py +350 -0
  163. htmlgraph/hooks/drift_handler.py +525 -0
  164. htmlgraph/hooks/event_tracker.py +790 -99
  165. htmlgraph/hooks/git_commands.py +175 -0
  166. htmlgraph/hooks/installer.py +5 -1
  167. htmlgraph/hooks/orchestrator.py +327 -76
  168. htmlgraph/hooks/orchestrator_reflector.py +31 -4
  169. htmlgraph/hooks/post_tool_use_failure.py +32 -7
  170. htmlgraph/hooks/post_tool_use_handler.py +257 -0
  171. htmlgraph/hooks/posttooluse.py +92 -19
  172. htmlgraph/hooks/pretooluse.py +527 -7
  173. htmlgraph/hooks/prompt_analyzer.py +637 -0
  174. htmlgraph/hooks/session_handler.py +668 -0
  175. htmlgraph/hooks/session_summary.py +395 -0
  176. htmlgraph/hooks/state_manager.py +504 -0
  177. htmlgraph/hooks/subagent_detection.py +202 -0
  178. htmlgraph/hooks/subagent_stop.py +369 -0
  179. htmlgraph/hooks/task_enforcer.py +99 -4
  180. htmlgraph/hooks/validator.py +212 -91
  181. htmlgraph/ids.py +2 -1
  182. htmlgraph/learning.py +125 -100
  183. htmlgraph/mcp_server.py +2 -1
  184. htmlgraph/models.py +217 -18
  185. htmlgraph/operations/README.md +62 -0
  186. htmlgraph/operations/__init__.py +79 -0
  187. htmlgraph/operations/analytics.py +339 -0
  188. htmlgraph/operations/bootstrap.py +289 -0
  189. htmlgraph/operations/events.py +244 -0
  190. htmlgraph/operations/fastapi_server.py +231 -0
  191. htmlgraph/operations/hooks.py +350 -0
  192. htmlgraph/operations/initialization.py +597 -0
  193. htmlgraph/operations/initialization.py.backup +228 -0
  194. htmlgraph/operations/server.py +303 -0
  195. htmlgraph/orchestration/__init__.py +58 -0
  196. htmlgraph/orchestration/claude_launcher.py +179 -0
  197. htmlgraph/orchestration/command_builder.py +72 -0
  198. htmlgraph/orchestration/headless_spawner.py +281 -0
  199. htmlgraph/orchestration/live_events.py +377 -0
  200. htmlgraph/orchestration/model_selection.py +327 -0
  201. htmlgraph/orchestration/plugin_manager.py +140 -0
  202. htmlgraph/orchestration/prompts.py +137 -0
  203. htmlgraph/orchestration/spawner_event_tracker.py +383 -0
  204. htmlgraph/orchestration/spawners/__init__.py +16 -0
  205. htmlgraph/orchestration/spawners/base.py +194 -0
  206. htmlgraph/orchestration/spawners/claude.py +173 -0
  207. htmlgraph/orchestration/spawners/codex.py +435 -0
  208. htmlgraph/orchestration/spawners/copilot.py +294 -0
  209. htmlgraph/orchestration/spawners/gemini.py +471 -0
  210. htmlgraph/orchestration/subprocess_runner.py +36 -0
  211. htmlgraph/{orchestration.py → orchestration/task_coordination.py} +16 -8
  212. htmlgraph/orchestration.md +563 -0
  213. htmlgraph/orchestrator-system-prompt-optimized.txt +863 -0
  214. htmlgraph/orchestrator.py +2 -1
  215. htmlgraph/orchestrator_config.py +357 -0
  216. htmlgraph/orchestrator_mode.py +115 -4
  217. htmlgraph/parallel.py +2 -1
  218. htmlgraph/parser.py +86 -6
  219. htmlgraph/path_query.py +608 -0
  220. htmlgraph/pattern_matcher.py +636 -0
  221. htmlgraph/pydantic_models.py +476 -0
  222. htmlgraph/quality_gates.py +350 -0
  223. htmlgraph/query_builder.py +2 -1
  224. htmlgraph/query_composer.py +509 -0
  225. htmlgraph/reflection.py +443 -0
  226. htmlgraph/refs.py +344 -0
  227. htmlgraph/repo_hash.py +512 -0
  228. htmlgraph/repositories/__init__.py +292 -0
  229. htmlgraph/repositories/analytics_repository.py +455 -0
  230. htmlgraph/repositories/analytics_repository_standard.py +628 -0
  231. htmlgraph/repositories/feature_repository.py +581 -0
  232. htmlgraph/repositories/feature_repository_htmlfile.py +668 -0
  233. htmlgraph/repositories/feature_repository_memory.py +607 -0
  234. htmlgraph/repositories/feature_repository_sqlite.py +858 -0
  235. htmlgraph/repositories/filter_service.py +620 -0
  236. htmlgraph/repositories/filter_service_standard.py +445 -0
  237. htmlgraph/repositories/shared_cache.py +621 -0
  238. htmlgraph/repositories/shared_cache_memory.py +395 -0
  239. htmlgraph/repositories/track_repository.py +552 -0
  240. htmlgraph/repositories/track_repository_htmlfile.py +619 -0
  241. htmlgraph/repositories/track_repository_memory.py +508 -0
  242. htmlgraph/repositories/track_repository_sqlite.py +711 -0
  243. htmlgraph/sdk/__init__.py +398 -0
  244. htmlgraph/sdk/__init__.pyi +14 -0
  245. htmlgraph/sdk/analytics/__init__.py +19 -0
  246. htmlgraph/sdk/analytics/engine.py +155 -0
  247. htmlgraph/sdk/analytics/helpers.py +178 -0
  248. htmlgraph/sdk/analytics/registry.py +109 -0
  249. htmlgraph/sdk/base.py +484 -0
  250. htmlgraph/sdk/constants.py +216 -0
  251. htmlgraph/sdk/core.pyi +308 -0
  252. htmlgraph/sdk/discovery.py +120 -0
  253. htmlgraph/sdk/help/__init__.py +12 -0
  254. htmlgraph/sdk/help/mixin.py +699 -0
  255. htmlgraph/sdk/mixins/__init__.py +15 -0
  256. htmlgraph/sdk/mixins/attribution.py +113 -0
  257. htmlgraph/sdk/mixins/mixin.py +410 -0
  258. htmlgraph/sdk/operations/__init__.py +12 -0
  259. htmlgraph/sdk/operations/mixin.py +427 -0
  260. htmlgraph/sdk/orchestration/__init__.py +17 -0
  261. htmlgraph/sdk/orchestration/coordinator.py +203 -0
  262. htmlgraph/sdk/orchestration/spawner.py +204 -0
  263. htmlgraph/sdk/planning/__init__.py +19 -0
  264. htmlgraph/sdk/planning/bottlenecks.py +93 -0
  265. htmlgraph/sdk/planning/mixin.py +211 -0
  266. htmlgraph/sdk/planning/parallel.py +186 -0
  267. htmlgraph/sdk/planning/queue.py +210 -0
  268. htmlgraph/sdk/planning/recommendations.py +87 -0
  269. htmlgraph/sdk/planning/smart_planning.py +319 -0
  270. htmlgraph/sdk/session/__init__.py +19 -0
  271. htmlgraph/sdk/session/continuity.py +57 -0
  272. htmlgraph/sdk/session/handoff.py +110 -0
  273. htmlgraph/sdk/session/info.py +309 -0
  274. htmlgraph/sdk/session/manager.py +103 -0
  275. htmlgraph/sdk/strategic/__init__.py +26 -0
  276. htmlgraph/sdk/strategic/mixin.py +563 -0
  277. htmlgraph/server.py +295 -107
  278. htmlgraph/session_hooks.py +300 -0
  279. htmlgraph/session_manager.py +285 -3
  280. htmlgraph/session_registry.py +587 -0
  281. htmlgraph/session_state.py +436 -0
  282. htmlgraph/session_warning.py +2 -1
  283. htmlgraph/sessions/__init__.py +23 -0
  284. htmlgraph/sessions/handoff.py +756 -0
  285. htmlgraph/system_prompts.py +450 -0
  286. htmlgraph/templates/orchestration-view.html +350 -0
  287. htmlgraph/track_builder.py +33 -1
  288. htmlgraph/track_manager.py +38 -0
  289. htmlgraph/transcript.py +18 -5
  290. htmlgraph/validation.py +115 -0
  291. htmlgraph/watch.py +2 -1
  292. htmlgraph/work_type_utils.py +2 -1
  293. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/dashboard.html +2246 -248
  294. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/METADATA +95 -64
  295. htmlgraph-0.27.5.dist-info/RECORD +337 -0
  296. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/entry_points.txt +1 -1
  297. htmlgraph/cli.py +0 -4839
  298. htmlgraph/sdk.py +0 -2359
  299. htmlgraph-0.20.1.dist-info/RECORD +0 -118
  300. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/styles.css +0 -0
  301. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
  302. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
  303. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
  304. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/WHEEL +0 -0
@@ -0,0 +1,790 @@
1
+ """
2
+ HtmlGraph Query Builders - SQLite Query Construction
3
+
4
+ Provides high-level query builders for common operations on HtmlGraph data:
5
+ - Event queries (agent activity, tool usage, error tracking)
6
+ - Feature queries (work item status, priority filtering)
7
+ - Session queries (agent metrics, collaboration tracking)
8
+ - Track queries (initiative progress, feature dependencies)
9
+ - Collaboration queries (handoffs, parallel work)
10
+
11
+ All builders return SQL and parameters for safe parameterized queries.
12
+ """
13
+
14
+ from datetime import datetime
15
+ from enum import Enum
16
+
17
+
18
+ class EventType(Enum):
19
+ """Types of events that can be recorded."""
20
+
21
+ TOOL_CALL = "tool_call"
22
+ TOOL_RESULT = "tool_result"
23
+ ERROR = "error"
24
+ DELEGATION = "delegation"
25
+ COMPLETION = "completion"
26
+ START = "start"
27
+ END = "end"
28
+ CHECK_POINT = "check_point"
29
+
30
+
31
+ class FeatureType(Enum):
32
+ """Types of work items."""
33
+
34
+ FEATURE = "feature"
35
+ BUG = "bug"
36
+ SPIKE = "spike"
37
+ CHORE = "chore"
38
+ EPIC = "epic"
39
+ TASK = "task"
40
+
41
+
42
+ class FeatureStatus(Enum):
43
+ """Possible feature statuses."""
44
+
45
+ TODO = "todo"
46
+ IN_PROGRESS = "in_progress"
47
+ BLOCKED = "blocked"
48
+ DONE = "done"
49
+ CANCELLED = "cancelled"
50
+
51
+
52
+ class Priority(Enum):
53
+ """Priority levels."""
54
+
55
+ LOW = "low"
56
+ MEDIUM = "medium"
57
+ HIGH = "high"
58
+ CRITICAL = "critical"
59
+
60
+
61
+ class Queries:
62
+ """Query builders for HtmlGraph SQLite backend."""
63
+
64
+ # ========== AGENT EVENTS QUERIES ==========
65
+
66
+ @staticmethod
67
+ def get_events_by_session(session_id: str) -> tuple[str, tuple]:
68
+ """
69
+ Get all events for a session ordered by timestamp.
70
+
71
+ Args:
72
+ session_id: Session ID to query
73
+
74
+ Returns:
75
+ Tuple of (SQL query, parameters)
76
+ """
77
+ sql = """
78
+ SELECT * FROM agent_events
79
+ WHERE session_id = ?
80
+ ORDER BY timestamp ASC
81
+ """
82
+ return sql, (session_id,)
83
+
84
+ @staticmethod
85
+ def get_events_by_agent(
86
+ agent_id: str,
87
+ start_time: datetime | None = None,
88
+ end_time: datetime | None = None,
89
+ ) -> tuple[str, tuple]:
90
+ """
91
+ Get all events generated by a specific agent.
92
+
93
+ Args:
94
+ agent_id: Agent identifier
95
+ start_time: Optional start time filter
96
+ end_time: Optional end time filter
97
+
98
+ Returns:
99
+ Tuple of (SQL query, parameters)
100
+ """
101
+ sql = """
102
+ SELECT * FROM agent_events
103
+ WHERE agent_id = ?
104
+ """
105
+ params = [agent_id]
106
+
107
+ if start_time:
108
+ sql += " AND timestamp >= ?"
109
+ params.append(start_time.isoformat())
110
+
111
+ if end_time:
112
+ sql += " AND timestamp <= ?"
113
+ params.append(end_time.isoformat())
114
+
115
+ sql += " ORDER BY timestamp DESC"
116
+ return sql, tuple(params)
117
+
118
+ @staticmethod
119
+ def get_events_by_type(
120
+ event_type: str,
121
+ session_id: str | None = None,
122
+ ) -> tuple[str, tuple]:
123
+ """
124
+ Get events filtered by type (tool_call, error, delegation, etc.).
125
+
126
+ Args:
127
+ event_type: Type of event to filter
128
+ session_id: Optional session filter
129
+
130
+ Returns:
131
+ Tuple of (SQL query, parameters)
132
+ """
133
+ sql = "SELECT * FROM agent_events WHERE event_type = ?"
134
+ params = [event_type]
135
+
136
+ if session_id:
137
+ sql += " AND session_id = ?"
138
+ params.append(session_id)
139
+
140
+ sql += " ORDER BY timestamp DESC"
141
+ return sql, tuple(params)
142
+
143
+ @staticmethod
144
+ def get_tool_usage_summary(
145
+ session_id: str,
146
+ ) -> tuple[str, tuple]:
147
+ """
148
+ Get summary of tool usage in a session.
149
+
150
+ Returns tool calls grouped by tool name with counts.
151
+
152
+ Args:
153
+ session_id: Session to analyze
154
+
155
+ Returns:
156
+ Tuple of (SQL query, parameters)
157
+ """
158
+ sql = """
159
+ SELECT
160
+ tool_name,
161
+ COUNT(*) as call_count,
162
+ SUM(cost_tokens) as total_tokens,
163
+ COUNT(CASE WHEN event_type = 'error' THEN 1 END) as error_count,
164
+ MIN(timestamp) as first_call,
165
+ MAX(timestamp) as last_call
166
+ FROM agent_events
167
+ WHERE session_id = ? AND tool_name IS NOT NULL
168
+ GROUP BY tool_name
169
+ ORDER BY call_count DESC
170
+ """
171
+ return sql, (session_id,)
172
+
173
+ @staticmethod
174
+ def get_events_with_errors(
175
+ session_id: str,
176
+ ) -> tuple[str, tuple]:
177
+ """
178
+ Get all error events in a session with context.
179
+
180
+ Args:
181
+ session_id: Session to analyze
182
+
183
+ Returns:
184
+ Tuple of (SQL query, parameters)
185
+ """
186
+ sql = """
187
+ SELECT
188
+ event_id,
189
+ agent_id,
190
+ timestamp,
191
+ tool_name,
192
+ output_summary as error_message,
193
+ context
194
+ FROM agent_events
195
+ WHERE session_id = ? AND event_type = 'error'
196
+ ORDER BY timestamp ASC
197
+ """
198
+ return sql, (session_id,)
199
+
200
+ @staticmethod
201
+ def get_delegation_chain(
202
+ session_id: str,
203
+ ) -> tuple[str, tuple]:
204
+ """
205
+ Get the chain of delegations in a session.
206
+
207
+ Shows parent-child relationships between delegated events.
208
+
209
+ Args:
210
+ session_id: Session to analyze
211
+
212
+ Returns:
213
+ Tuple of (SQL query, parameters)
214
+ """
215
+ sql = """
216
+ SELECT
217
+ event_id,
218
+ parent_event_id,
219
+ agent_id,
220
+ parent_agent_id,
221
+ event_type,
222
+ timestamp,
223
+ tool_name
224
+ FROM agent_events
225
+ WHERE session_id = ? AND (parent_agent_id IS NOT NULL OR event_type = 'delegation')
226
+ ORDER BY timestamp ASC
227
+ """
228
+ return sql, (session_id,)
229
+
230
+ # ========== FEATURES QUERIES ==========
231
+
232
+ @staticmethod
233
+ def get_features_by_status(
234
+ status: str,
235
+ limit: int | None = None,
236
+ ) -> tuple[str, tuple]:
237
+ """
238
+ Get features filtered by status.
239
+
240
+ Args:
241
+ status: Status to filter by (todo, in_progress, done, etc.)
242
+ limit: Optional limit on results
243
+
244
+ Returns:
245
+ Tuple of (SQL query, parameters)
246
+ """
247
+ sql = """
248
+ SELECT * FROM features
249
+ WHERE status = ?
250
+ ORDER BY priority DESC, created_at DESC
251
+ """
252
+ params: list[str | int] = [status]
253
+
254
+ if limit:
255
+ sql += " LIMIT ?"
256
+ params.append(limit)
257
+
258
+ return sql, tuple(params)
259
+
260
+ @staticmethod
261
+ def get_features_by_track(
262
+ track_id: str,
263
+ ) -> tuple[str, tuple]:
264
+ """
265
+ Get all features linked to a track.
266
+
267
+ Args:
268
+ track_id: Track ID
269
+
270
+ Returns:
271
+ Tuple of (SQL query, parameters)
272
+ """
273
+ sql = """
274
+ SELECT * FROM features
275
+ WHERE track_id = ?
276
+ ORDER BY priority DESC, created_at ASC
277
+ """
278
+ return sql, (track_id,)
279
+
280
+ @staticmethod
281
+ def get_features_assigned_to(
282
+ agent_id: str,
283
+ ) -> tuple[str, tuple]:
284
+ """
285
+ Get all features assigned to an agent.
286
+
287
+ Args:
288
+ agent_id: Agent identifier
289
+
290
+ Returns:
291
+ Tuple of (SQL query, parameters)
292
+ """
293
+ sql = """
294
+ SELECT * FROM features
295
+ WHERE assigned_to = ?
296
+ ORDER BY priority DESC, created_at DESC
297
+ """
298
+ return sql, (agent_id,)
299
+
300
+ @staticmethod
301
+ def get_feature_progress(
302
+ feature_id: str,
303
+ ) -> tuple[str, tuple]:
304
+ """
305
+ Get progress info for a feature (steps completed, estimated vs actual time).
306
+
307
+ Args:
308
+ feature_id: Feature ID
309
+
310
+ Returns:
311
+ Tuple of (SQL query, parameters)
312
+ """
313
+ sql = """
314
+ SELECT
315
+ id,
316
+ title,
317
+ type,
318
+ status,
319
+ steps_total,
320
+ steps_completed,
321
+ CASE WHEN steps_total > 0 THEN (steps_completed * 100.0 / steps_total) ELSE 0 END as progress_percent,
322
+ created_at,
323
+ completed_at,
324
+ CASE WHEN completed_at IS NOT NULL
325
+ THEN CAST((julianday(completed_at) - julianday(created_at)) * 24 AS INT)
326
+ ELSE NULL
327
+ END as hours_elapsed
328
+ FROM features
329
+ WHERE id = ?
330
+ """
331
+ return sql, (feature_id,)
332
+
333
+ @staticmethod
334
+ def get_high_priority_features(
335
+ limit: int = 10,
336
+ ) -> tuple[str, tuple]:
337
+ """
338
+ Get all high/critical priority features not yet done.
339
+
340
+ Args:
341
+ limit: Maximum results to return
342
+
343
+ Returns:
344
+ Tuple of (SQL query, parameters)
345
+ """
346
+ sql = """
347
+ SELECT * FROM features
348
+ WHERE priority IN ('high', 'critical')
349
+ AND status != 'done'
350
+ ORDER BY priority DESC, created_at ASC
351
+ LIMIT ?
352
+ """
353
+ return sql, (limit,)
354
+
355
+ @staticmethod
356
+ def get_blocked_features() -> tuple[str, tuple]:
357
+ """
358
+ Get all currently blocked features.
359
+
360
+ Returns:
361
+ Tuple of (SQL query, parameters)
362
+ """
363
+ sql = """
364
+ SELECT id, title, type, assigned_to, created_at
365
+ FROM features
366
+ WHERE status = 'blocked'
367
+ ORDER BY created_at ASC
368
+ """
369
+ return sql, ()
370
+
371
+ @staticmethod
372
+ def get_feature_dependency_tree(
373
+ feature_id: str,
374
+ ) -> tuple[str, tuple]:
375
+ """
376
+ Get feature dependency tree (parent-child relationships).
377
+
378
+ Args:
379
+ feature_id: Root feature ID
380
+
381
+ Returns:
382
+ Tuple of (SQL query, parameters)
383
+ """
384
+ sql = """
385
+ WITH RECURSIVE feature_tree AS (
386
+ -- Base case: start with the requested feature
387
+ SELECT id, title, parent_feature_id, type, status, 0 as depth
388
+ FROM features
389
+ WHERE id = ?
390
+
391
+ UNION ALL
392
+
393
+ -- Recursive case: get all child features
394
+ SELECT f.id, f.title, f.parent_feature_id, f.type, f.status, ft.depth + 1
395
+ FROM features f
396
+ INNER JOIN feature_tree ft ON f.parent_feature_id = ft.id
397
+ WHERE ft.depth < 10 -- Prevent infinite loops
398
+ )
399
+ SELECT * FROM feature_tree
400
+ ORDER BY depth ASC, id
401
+ """
402
+ return sql, (feature_id,)
403
+
404
+ # ========== SESSIONS QUERIES ==========
405
+
406
+ @staticmethod
407
+ def get_session_metrics(
408
+ session_id: str,
409
+ ) -> tuple[str, tuple]:
410
+ """
411
+ Get comprehensive metrics for a session.
412
+
413
+ Includes event count, token usage, features worked on, etc.
414
+
415
+ Args:
416
+ session_id: Session ID
417
+
418
+ Returns:
419
+ Tuple of (SQL query, parameters)
420
+ """
421
+ sql = """
422
+ SELECT
423
+ s.session_id,
424
+ s.agent_assigned,
425
+ s.created_at,
426
+ s.completed_at,
427
+ CASE WHEN s.completed_at IS NOT NULL
428
+ THEN CAST((julianday(s.completed_at) - julianday(s.created_at)) * 24 * 60 AS INT)
429
+ ELSE CAST((julianday(CURRENT_TIMESTAMP) - julianday(s.created_at)) * 24 * 60 AS INT)
430
+ END as duration_minutes,
431
+ COUNT(DISTINCT e.event_id) as total_events,
432
+ COUNT(DISTINCT CASE WHEN e.event_type = 'error' THEN e.event_id END) as error_count,
433
+ COUNT(DISTINCT CASE WHEN e.event_type = 'delegation' THEN e.event_id END) as delegation_count,
434
+ SUM(e.cost_tokens) as total_tokens,
435
+ s.status,
436
+ s.is_subagent
437
+ FROM sessions s
438
+ LEFT JOIN agent_events e ON s.session_id = e.session_id
439
+ WHERE s.session_id = ?
440
+ GROUP BY s.session_id
441
+ """
442
+ return sql, (session_id,)
443
+
444
+ @staticmethod
445
+ def get_agent_sessions(
446
+ agent_id: str,
447
+ limit: int = 10,
448
+ ) -> tuple[str, tuple]:
449
+ """
450
+ Get all sessions for an agent (most recent first).
451
+
452
+ Args:
453
+ agent_id: Agent identifier
454
+ limit: Maximum sessions to return
455
+
456
+ Returns:
457
+ Tuple of (SQL query, parameters)
458
+ """
459
+ sql = """
460
+ SELECT
461
+ session_id,
462
+ agent_assigned,
463
+ created_at,
464
+ completed_at,
465
+ total_events,
466
+ total_tokens_used,
467
+ status,
468
+ is_subagent
469
+ FROM sessions
470
+ WHERE agent_assigned = ?
471
+ ORDER BY created_at DESC
472
+ LIMIT ?
473
+ """
474
+ return sql, (agent_id, limit)
475
+
476
+ @staticmethod
477
+ def get_active_sessions() -> tuple[str, tuple]:
478
+ """
479
+ Get all currently active sessions.
480
+
481
+ Returns:
482
+ Tuple of (SQL query, parameters)
483
+ """
484
+ sql = """
485
+ SELECT
486
+ session_id,
487
+ agent_assigned,
488
+ created_at,
489
+ total_events,
490
+ total_tokens_used,
491
+ status
492
+ FROM sessions
493
+ WHERE status = 'active'
494
+ ORDER BY created_at DESC
495
+ """
496
+ return sql, ()
497
+
498
+ @staticmethod
499
+ def get_subagent_sessions(
500
+ parent_session_id: str,
501
+ ) -> tuple[str, tuple]:
502
+ """
503
+ Get all subagent sessions spawned from a parent session.
504
+
505
+ Args:
506
+ parent_session_id: Parent session ID
507
+
508
+ Returns:
509
+ Tuple of (SQL query, parameters)
510
+ """
511
+ sql = """
512
+ SELECT
513
+ session_id,
514
+ agent_assigned,
515
+ created_at,
516
+ completed_at,
517
+ total_events,
518
+ total_tokens_used,
519
+ status
520
+ FROM sessions
521
+ WHERE parent_session_id = ?
522
+ ORDER BY created_at ASC
523
+ """
524
+ return sql, (parent_session_id,)
525
+
526
+ @staticmethod
527
+ def get_context_drift(
528
+ session_id: str,
529
+ ) -> tuple[str, tuple]:
530
+ """
531
+ Get context drift metric for a session.
532
+
533
+ Higher drift indicates context loss across session.
534
+
535
+ Args:
536
+ session_id: Session ID
537
+
538
+ Returns:
539
+ Tuple of (SQL query, parameters)
540
+ """
541
+ sql = """
542
+ SELECT
543
+ session_id,
544
+ context_drift,
545
+ total_events,
546
+ CASE WHEN total_events > 0 THEN (context_drift / total_events) ELSE 0 END as drift_per_event
547
+ FROM sessions
548
+ WHERE session_id = ?
549
+ """
550
+ return sql, (session_id,)
551
+
552
+ # ========== TRACKS QUERIES ==========
553
+
554
+ @staticmethod
555
+ def get_track_status(
556
+ track_id: str,
557
+ ) -> tuple[str, tuple]:
558
+ """
559
+ Get comprehensive status of a track and its features.
560
+
561
+ Args:
562
+ track_id: Track ID
563
+
564
+ Returns:
565
+ Tuple of (SQL query, parameters)
566
+ """
567
+ sql = """
568
+ SELECT
569
+ t.track_id,
570
+ t.title,
571
+ t.status,
572
+ t.priority,
573
+ t.created_at,
574
+ t.completed_at,
575
+ COUNT(DISTINCT f.id) as total_features,
576
+ COUNT(DISTINCT CASE WHEN f.status = 'done' THEN f.id END) as completed_features,
577
+ COUNT(DISTINCT CASE WHEN f.status = 'in_progress' THEN f.id END) as in_progress_features,
578
+ COUNT(DISTINCT CASE WHEN f.status = 'blocked' THEN f.id END) as blocked_features,
579
+ CASE WHEN COUNT(f.id) > 0
580
+ THEN CAST(COUNT(CASE WHEN f.status = 'done' THEN f.id END) * 100.0 / COUNT(f.id) AS INT)
581
+ ELSE 0
582
+ END as completion_percent
583
+ FROM tracks t
584
+ LEFT JOIN features f ON t.track_id = f.track_id
585
+ WHERE t.track_id = ?
586
+ GROUP BY t.track_id
587
+ """
588
+ return sql, (track_id,)
589
+
590
+ @staticmethod
591
+ def get_active_tracks(
592
+ limit: int = 10,
593
+ ) -> tuple[str, tuple]:
594
+ """
595
+ Get all active (in-progress) tracks.
596
+
597
+ Args:
598
+ limit: Maximum tracks to return
599
+
600
+ Returns:
601
+ Tuple of (SQL query, parameters)
602
+ """
603
+ sql = """
604
+ SELECT
605
+ t.track_id,
606
+ t.title,
607
+ t.priority,
608
+ COUNT(f.id) as feature_count,
609
+ COUNT(CASE WHEN f.status = 'done' THEN f.id END) as completed_count
610
+ FROM tracks t
611
+ LEFT JOIN features f ON t.track_id = f.track_id
612
+ WHERE t.status = 'in_progress'
613
+ GROUP BY t.track_id
614
+ ORDER BY t.priority DESC, t.created_at DESC
615
+ LIMIT ?
616
+ """
617
+ return sql, (limit,)
618
+
619
+ # ========== COLLABORATION QUERIES ==========
620
+
621
+ @staticmethod
622
+ def get_handoffs(
623
+ session_id: str,
624
+ ) -> tuple[str, tuple]:
625
+ """
626
+ Get all handoffs (delegations) in a session.
627
+
628
+ Args:
629
+ session_id: Session ID
630
+
631
+ Returns:
632
+ Tuple of (SQL query, parameters)
633
+ """
634
+ sql = """
635
+ SELECT
636
+ handoff_id,
637
+ from_agent,
638
+ to_agent,
639
+ timestamp,
640
+ feature_id,
641
+ handoff_type,
642
+ status,
643
+ reason
644
+ FROM agent_collaboration
645
+ WHERE session_id = ?
646
+ ORDER BY timestamp ASC
647
+ """
648
+ return sql, (session_id,)
649
+
650
+ @staticmethod
651
+ def get_agent_collaboration_summary() -> tuple[str, tuple]:
652
+ """
653
+ Get summary of agent collaboration patterns.
654
+
655
+ Shows which agents delegate to whom most frequently.
656
+
657
+ Returns:
658
+ Tuple of (SQL query, parameters)
659
+ """
660
+ sql = """
661
+ SELECT
662
+ from_agent,
663
+ to_agent,
664
+ COUNT(*) as handoff_count,
665
+ COUNT(CASE WHEN status = 'completed' THEN 1 END) as successful_handoffs,
666
+ COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_handoffs,
667
+ COUNT(DISTINCT feature_id) as unique_features
668
+ FROM agent_collaboration
669
+ GROUP BY from_agent, to_agent
670
+ ORDER BY handoff_count DESC
671
+ """
672
+ return sql, ()
673
+
674
+ @staticmethod
675
+ def get_parallel_work(
676
+ session_id: str,
677
+ ) -> tuple[str, tuple]:
678
+ """
679
+ Get instances of parallel work in a session.
680
+
681
+ Returns:
682
+ Tuple of (SQL query, parameters)
683
+ """
684
+ sql = """
685
+ SELECT
686
+ handoff_id,
687
+ from_agent,
688
+ to_agent,
689
+ feature_id,
690
+ timestamp,
691
+ status
692
+ FROM agent_collaboration
693
+ WHERE session_id = ? AND handoff_type = 'parallel'
694
+ ORDER BY timestamp ASC
695
+ """
696
+ return sql, (session_id,)
697
+
698
+ # ========== ANALYTICAL QUERIES ==========
699
+
700
+ @staticmethod
701
+ def get_system_statistics() -> tuple[str, tuple]:
702
+ """
703
+ Get system-wide statistics across all data.
704
+
705
+ Returns:
706
+ Tuple of (SQL query, parameters)
707
+ """
708
+ sql = """
709
+ SELECT
710
+ (SELECT COUNT(*) FROM agent_events) as total_events,
711
+ (SELECT COUNT(*) FROM features) as total_features,
712
+ (SELECT COUNT(*) FROM sessions) as total_sessions,
713
+ (SELECT COUNT(*) FROM tracks) as total_tracks,
714
+ (SELECT COUNT(DISTINCT agent_id) FROM agent_events) as unique_agents,
715
+ (SELECT SUM(cost_tokens) FROM agent_events) as total_tokens,
716
+ (SELECT COUNT(*) FROM features WHERE status = 'done') as completed_features,
717
+ (SELECT COUNT(*) FROM features WHERE status = 'blocked') as blocked_features,
718
+ (SELECT COUNT(*) FROM agent_collaboration) as total_handoffs
719
+ """
720
+ return sql, ()
721
+
722
+ @staticmethod
723
+ def get_agent_performance_metrics() -> tuple[str, tuple]:
724
+ """
725
+ Get performance metrics per agent.
726
+
727
+ Includes event counts, token usage, error rates, etc.
728
+
729
+ Returns:
730
+ Tuple of (SQL query, parameters)
731
+ """
732
+ sql = """
733
+ SELECT
734
+ e.agent_id,
735
+ COUNT(*) as total_events,
736
+ COUNT(DISTINCT e.session_id) as total_sessions,
737
+ COUNT(DISTINCT CASE WHEN e.event_type = 'error' THEN e.event_id END) as error_count,
738
+ CAST(
739
+ COUNT(DISTINCT CASE WHEN e.event_type = 'error' THEN e.event_id END) * 100.0
740
+ / COUNT(*) AS DECIMAL(5, 2)
741
+ ) as error_rate,
742
+ SUM(e.cost_tokens) as total_tokens,
743
+ ROUND(AVG(e.cost_tokens), 2) as avg_tokens_per_event,
744
+ COUNT(DISTINCT CASE WHEN e.tool_name IS NOT NULL THEN e.tool_name END) as unique_tools_used
745
+ FROM agent_events e
746
+ GROUP BY e.agent_id
747
+ ORDER BY total_events DESC
748
+ """
749
+ return sql, ()
750
+
751
+ @staticmethod
752
+ def get_events_timeline(
753
+ start_date: datetime,
754
+ end_date: datetime,
755
+ bucket_minutes: int = 60,
756
+ ) -> tuple[str, tuple]:
757
+ """
758
+ Get timeline of events grouped by time bucket.
759
+
760
+ Useful for visualizing activity over time.
761
+
762
+ Args:
763
+ start_date: Start of time range
764
+ end_date: End of time range
765
+ bucket_minutes: Group events into buckets of this size
766
+
767
+ Returns:
768
+ Tuple of (SQL query, parameters)
769
+ """
770
+ sql = f"""
771
+ SELECT
772
+ strftime('%Y-%m-%d %H:%M', datetime(
773
+ (julianday(timestamp) - julianday(?)) * 24 * 60 / {bucket_minutes}
774
+ * {bucket_minutes} / 24 / 60 + julianday(?)
775
+ )) as time_bucket,
776
+ COUNT(*) as event_count,
777
+ COUNT(DISTINCT agent_id) as unique_agents,
778
+ COUNT(DISTINCT session_id) as unique_sessions,
779
+ SUM(cost_tokens) as total_tokens
780
+ FROM agent_events
781
+ WHERE timestamp BETWEEN ? AND ?
782
+ GROUP BY time_bucket
783
+ ORDER BY time_bucket ASC
784
+ """
785
+ return sql, (
786
+ start_date.isoformat(),
787
+ start_date.isoformat(),
788
+ start_date.isoformat(),
789
+ end_date.isoformat(),
790
+ )