From ab8d6f6b6fd4e5bcf60405709aad1884a5e27b0a Mon Sep 17 00:00:00 2001 From: Himanshu Dongre Date: Sun, 17 May 2026 23:57:35 +0530 Subject: [PATCH] Clarify claim completion metrics --- backend/app/api/routes/metrics.py | 3 +++ backend/tests/integration/test_metrics.py | 2 ++ cli/smriti_cli/formatters.py | 16 ++++++++++++++-- cli/tests/test_metrics_cli.py | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/backend/app/api/routes/metrics.py b/backend/app/api/routes/metrics.py index b4a6ce0..b5d22d6 100644 --- a/backend/app/api/routes/metrics.py +++ b/backend/app/api/routes/metrics.py @@ -37,6 +37,7 @@ class CoordinationMetrics(BaseModel): total_claims: int = 0 claims_done: int = 0 claims_abandoned: int = 0 + claims_unresolved: int = 0 claims_with_task_id: int = 0 claim_completion_rate: Optional[float] = None @@ -134,6 +135,7 @@ def get_space_metrics(space_id: uuid.UUID, db: Session = Depends(get_db)): ) cl_row = db.execute(claim_stmt).one() total_resolved = cl_row.done + cl_row.abandoned + unresolved = max(cl_row.total - total_resolved, 0) completion_rate = round(cl_row.done / total_resolved, 2) if total_resolved > 0 else None coordination = CoordinationMetrics( @@ -144,6 +146,7 @@ def get_space_metrics(space_id: uuid.UUID, db: Session = Depends(get_db)): total_claims=cl_row.total, claims_done=cl_row.done, claims_abandoned=cl_row.abandoned, + claims_unresolved=unresolved, claims_with_task_id=cl_row.with_task_id, claim_completion_rate=completion_rate, ) diff --git a/backend/tests/integration/test_metrics.py b/backend/tests/integration/test_metrics.py index 86f846f..ec3e1e8 100644 --- a/backend/tests/integration/test_metrics.py +++ b/backend/tests/integration/test_metrics.py @@ -56,6 +56,7 @@ def test_metrics_empty_space(client): assert data["coordination"]["total_checkpoints"] == 0 assert data["coordination"]["unique_agents"] == 0 assert data["coordination"]["total_claims"] == 0 + assert data["coordination"]["claims_unresolved"] == 0 assert data["state_quality"]["avg_decisions_per_checkpoint"] == 0.0 assert data["branches"]["active"] == 0 @@ -127,6 +128,7 @@ def test_metrics_claim_stats(client): assert data["coordination"]["total_claims"] == 3 assert data["coordination"]["claims_done"] == 1 assert data["coordination"]["claims_abandoned"] == 1 + assert data["coordination"]["claims_unresolved"] == 1 assert data["coordination"]["claims_with_task_id"] == 1 # Completion rate: 1 done / (1 done + 1 abandoned) = 0.5 assert data["coordination"]["claim_completion_rate"] == 0.5 diff --git a/cli/smriti_cli/formatters.py b/cli/smriti_cli/formatters.py index 03a89c7..879d61c 100644 --- a/cli/smriti_cli/formatters.py +++ b/cli/smriti_cli/formatters.py @@ -924,10 +924,22 @@ def format_metrics(data: dict) -> str: parts.append(f"{cross} cross-agent continuation{'s' if cross != 1 else ''}") claims_total = coord.get("total_claims", 0) + claims_done = coord.get("claims_done", 0) + claims_abandoned = coord.get("claims_abandoned", 0) + resolved_claims = claims_done + claims_abandoned + unresolved_claims = coord.get("claims_unresolved") + if unresolved_claims is None: + unresolved_claims = max(claims_total - resolved_claims, 0) rate = coord.get("claim_completion_rate") - rate_str = f"{int(rate * 100)}% completion" if rate is not None else "no claims resolved" + if rate is not None: + rate_str = f"{resolved_claims} resolved ({int(rate * 100)}% done)" + else: + rate_str = f"{resolved_claims} resolved" task_id_claims = coord.get("claims_with_task_id", 0) - parts.append(f"{claims_total} claims · {rate_str} · {task_id_claims} with task IDs") + parts.append( + f"{claims_total} claims · {rate_str} · " + f"{unresolved_claims} unresolved · {task_id_claims} with task IDs" + ) parts.append("") # State quality diff --git a/cli/tests/test_metrics_cli.py b/cli/tests/test_metrics_cli.py index 0a1b982..12ca151 100644 --- a/cli/tests/test_metrics_cli.py +++ b/cli/tests/test_metrics_cli.py @@ -17,6 +17,7 @@ def test_format_metrics_omits_empty_agent_distribution(): assert "0 checkpoints · 0 agents\n" in out assert "0 agents ()" not in out + assert "0 claims · 0 resolved · 0 unresolved · 0 with task IDs" in out def test_format_metrics_names_checkpoint_task_counts(): @@ -31,3 +32,22 @@ def test_format_metrics_names_checkpoint_task_counts(): }) assert "5 checkpoints with structured tasks · 5 checkpoints with task IDs" in out + + +def test_format_metrics_claim_completion_names_resolved_denominator(): + out = format_metrics({ + "space_name": "claims", + "coordination": { + "total_claims": 3, + "claims_done": 2, + "claims_abandoned": 0, + "claims_unresolved": 1, + "claim_completion_rate": 1.0, + "claims_with_task_id": 2, + }, + "state_quality": {}, + "branches": {}, + }) + + assert "3 claims · 2 resolved (100% done) · 1 unresolved · 2 with task IDs" in out + assert "100% completion" not in out