work_graph_run_query.py
2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""c_work_graph_run_list (`GET /api/work-graph-runs`), the one net-new
backend capability from the `v_graph_console` SDD (2026-08-03): a
cross-task "graph run history" list for the FR-5 Planner-output-overview
panel. Every other data need on that page is served by existing
`task_query`/`artifact_query` functions -- this is the only query in this
codebase that lists `work_graph_run` rows across all tasks in a project
rather than for one `task_id` at a time, which is why it lives in its own
module instead of `task_query.py` (that module's own docstring frames it
as "built around a single task_id").
"""
_VALID_ORG_NODES = ("planner", "coder", "validator")
class InvalidParamError(Exception):
"""INVALID_PARAM -- missing project_id, org_node outside the enum, or
limit outside [1, 100]."""
def list_work_graph_runs(conn, project_id, org_node=None, limit=20):
if not project_id:
raise InvalidParamError("project_id is required")
if org_node is not None and org_node not in _VALID_ORG_NODES:
raise InvalidParamError("org_node must be one of {}, got {!r}".format(_VALID_ORG_NODES, org_node))
if limit is None:
limit = 20
try:
limit = int(limit)
except (TypeError, ValueError):
raise InvalidParamError("limit must be an integer, got {!r}".format(limit))
if limit < 1 or limit > 100:
raise InvalidParamError("limit must be in [1, 100], got {!r}".format(limit))
query = (
"SELECT wgr.run_id, wgr.task_id, wgr.org_node, wgr.status, wgr.started_at, wgr.completed_at, "
"(SELECT COUNT(*) FROM work_node_execution wne WHERE wne.run_id = wgr.run_id) AS node_count "
"FROM work_graph_run wgr JOIN task t ON t.task_id = wgr.task_id WHERE t.project_id = ?"
)
params = [project_id]
if org_node:
query += " AND wgr.org_node = ?"
params.append(org_node)
query += " ORDER BY wgr.started_at DESC LIMIT ?"
params.append(limit)
rows = conn.execute(query, params).fetchall()
return [
{
"run_id": r[0], "task_id": r[1], "org_node": r[2], "status": r[3],
"started_at": r[4], "completed_at": r[5], "node_count": r[6],
}
for r in rows
]