refactor(focus-area): output all clusters as context; remove scoring and preferred_areas
The agent no longer picks a winner — it summarises every cluster so the
orchestrator can decide what's relevant. Scoring by overdue count overlapped
with the overdue-task agent. preferred_areas (project-ID based, broken label
matching) removed entirely.
Output format: numbered list of areas with task titles included.
Snapshot: {cluster_count, clusters: [{label, task_count, tasks}]}.
Version bumped to 3.0.0; inferred_params cleared.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -213,41 +213,41 @@ class TestFocusAreaAgent:
|
||||
out = self.agent.compute(_inp())
|
||||
assert "no tasks" in out.prompt_text.lower()
|
||||
|
||||
def test_single_project(self):
|
||||
tasks = [_task(f"T{i}", project_id="Work") for i in range(3)]
|
||||
out = self.agent.compute(_inp(tasks=tasks))
|
||||
assert '"Work"' in out.prompt_text
|
||||
assert "3 tasks" in out.prompt_text
|
||||
|
||||
def test_most_congested_wins(self):
|
||||
def test_lists_all_clusters(self):
|
||||
tasks = (
|
||||
[_task(f"W{i}", project_id="Work") for i in range(5)]
|
||||
[_task(f"W{i}", project_id="Work") for i in range(3)]
|
||||
+ [_task(f"H{i}", project_id="Home") for i in range(2)]
|
||||
)
|
||||
out = self.agent.compute(_inp(tasks=tasks))
|
||||
assert '"Work"' in out.prompt_text
|
||||
assert "Work" in out.prompt_text
|
||||
assert "Home" in out.prompt_text
|
||||
|
||||
def test_overdue_weighting(self):
|
||||
# Home has 2 tasks (1 overdue), Work has 3 non-overdue tasks
|
||||
# Home score = 2+1 = 3; Work score = 3 — Home should win due to overdue weight
|
||||
tasks = (
|
||||
[_task("Home1", project_id="Home", is_overdue=True),
|
||||
_task("Home2", project_id="Home")]
|
||||
+ [_task(f"W{i}", project_id="Work") for i in range(3)]
|
||||
)
|
||||
def test_includes_task_titles(self):
|
||||
tasks = [_task("Buy milk", project_id="Personal"), _task("Write report", project_id="Personal")]
|
||||
out = self.agent.compute(_inp(tasks=tasks))
|
||||
assert '"Work"' not in out.prompt_text or '"Home"' in out.prompt_text
|
||||
assert '"Buy milk"' in out.prompt_text
|
||||
assert '"Write report"' in out.prompt_text
|
||||
|
||||
def test_task_count_in_output(self):
|
||||
tasks = [_task(f"T{i}", project_id="Work") for i in range(3)]
|
||||
out = self.agent.compute(_inp(tasks=tasks))
|
||||
assert "3 task" in out.prompt_text
|
||||
|
||||
def test_default_project_fallback(self):
|
||||
out = self.agent.compute(_inp(tasks=[_task("No project task")]))
|
||||
# Tasks without project_id fall back to a "Tasks" bucket
|
||||
assert "Tasks" in out.prompt_text
|
||||
|
||||
def test_snapshot_keys(self):
|
||||
out = self.agent.compute(_inp(tasks=[_task("T1", project_id="A")]))
|
||||
public_keys = {k for k in out.signals_snapshot if not k.startswith("_")}
|
||||
assert {"top_cluster_label", "top_task_count", "top_overdue_count", "cluster_count",
|
||||
"strategy", "preferred_areas"} == public_keys
|
||||
assert {"cluster_count", "clusters"} == public_keys
|
||||
|
||||
def test_snapshot_clusters_shape(self):
|
||||
tasks = [_task("Buy milk", project_id="P1"), _task("Fix bug", project_id="P2")]
|
||||
out = self.agent.compute(_inp(tasks=tasks))
|
||||
clusters = out.signals_snapshot["clusters"]
|
||||
assert isinstance(clusters, list)
|
||||
assert all("label" in c and "task_count" in c and "tasks" in c for c in clusters)
|
||||
|
||||
|
||||
# ── Registry ─────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user