mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-07 08:02:23 +00:00
fix: assign single-task kanban decompositions
This commit is contained in:
parent
6c4f11c64a
commit
4da4133d34
3 changed files with 165 additions and 18 deletions
|
|
@ -114,7 +114,7 @@ def test_decompose_with_fanout_creates_children(kanban_home):
|
|||
assert c1.assignee == "engineer"
|
||||
|
||||
|
||||
def test_decompose_fanout_false_falls_back_to_specify(kanban_home):
|
||||
def test_decompose_fanout_false_assigns_default_when_unassigned(kanban_home):
|
||||
with kb.connect() as conn:
|
||||
tid = kb.create_task(conn, title="just one thing", triage=True)
|
||||
|
||||
|
|
@ -125,11 +125,14 @@ def test_decompose_fanout_false_falls_back_to_specify(kanban_home):
|
|||
"body": "**Goal**\nDo the thing.",
|
||||
})
|
||||
|
||||
patches = _patch_list_profiles(["orchestrator"])
|
||||
patches = _patch_list_profiles(["orchestrator", "fallback"])
|
||||
for p in patches:
|
||||
p.start()
|
||||
try:
|
||||
with _patch_aux_client(llm_payload), _patch_extra_body():
|
||||
with _patch_aux_client(llm_payload), _patch_extra_body(), patch(
|
||||
"hermes_cli.kanban_decompose._load_config",
|
||||
return_value={"kanban": {"default_assignee": "fallback"}},
|
||||
):
|
||||
outcome = decomp.decompose_task(tid, author="me")
|
||||
finally:
|
||||
for p in patches:
|
||||
|
|
@ -140,9 +143,113 @@ def test_decompose_fanout_false_falls_back_to_specify(kanban_home):
|
|||
assert outcome.new_title == "Tightened title"
|
||||
with kb.connect() as conn:
|
||||
task = kb.get_task(conn, tid)
|
||||
assert task is not None
|
||||
# specify path with no parents -> recompute_ready flips to 'ready'
|
||||
assert task.status == "ready"
|
||||
assert task.title == "Tightened title"
|
||||
assert task.assignee == "fallback"
|
||||
|
||||
|
||||
def test_decompose_fanout_false_preserves_existing_assignee(kanban_home):
|
||||
with kb.connect() as conn:
|
||||
tid = kb.create_task(
|
||||
conn,
|
||||
title="already routed",
|
||||
assignee="engineer",
|
||||
triage=True,
|
||||
)
|
||||
|
||||
llm_payload = jsonlib.dumps({
|
||||
"fanout": False,
|
||||
"rationale": "single unit",
|
||||
"title": "Tightened title",
|
||||
"body": "Keep existing lane.",
|
||||
"assignee": "fallback",
|
||||
})
|
||||
|
||||
patches = _patch_list_profiles(["orchestrator", "engineer", "fallback"])
|
||||
for p in patches:
|
||||
p.start()
|
||||
try:
|
||||
with _patch_aux_client(llm_payload), _patch_extra_body(), patch(
|
||||
"hermes_cli.kanban_decompose._load_config",
|
||||
return_value={"kanban": {"default_assignee": "fallback"}},
|
||||
):
|
||||
outcome = decomp.decompose_task(tid, author="me")
|
||||
finally:
|
||||
for p in patches:
|
||||
p.stop()
|
||||
|
||||
assert outcome.ok, outcome.reason
|
||||
with kb.connect() as conn:
|
||||
task = kb.get_task(conn, tid)
|
||||
assert task is not None
|
||||
assert task.assignee == "engineer"
|
||||
assert task.title == "Tightened title"
|
||||
|
||||
|
||||
def test_decompose_fanout_false_uses_valid_llm_assignee(kanban_home):
|
||||
with kb.connect() as conn:
|
||||
tid = kb.create_task(conn, title="route me", triage=True)
|
||||
|
||||
llm_payload = jsonlib.dumps({
|
||||
"fanout": False,
|
||||
"rationale": "single unit",
|
||||
"title": "Tightened title",
|
||||
"body": "Route to specialist.",
|
||||
"assignee": "engineer",
|
||||
})
|
||||
|
||||
patches = _patch_list_profiles(["orchestrator", "engineer", "fallback"])
|
||||
for p in patches:
|
||||
p.start()
|
||||
try:
|
||||
with _patch_aux_client(llm_payload), _patch_extra_body(), patch(
|
||||
"hermes_cli.kanban_decompose._load_config",
|
||||
return_value={"kanban": {"default_assignee": "fallback"}},
|
||||
):
|
||||
outcome = decomp.decompose_task(tid, author="me")
|
||||
finally:
|
||||
for p in patches:
|
||||
p.stop()
|
||||
|
||||
assert outcome.ok, outcome.reason
|
||||
with kb.connect() as conn:
|
||||
task = kb.get_task(conn, tid)
|
||||
assert task is not None
|
||||
assert task.assignee == "engineer"
|
||||
|
||||
|
||||
def test_decompose_fanout_false_invalid_llm_assignee_uses_default(kanban_home):
|
||||
with kb.connect() as conn:
|
||||
tid = kb.create_task(conn, title="route me safely", triage=True)
|
||||
|
||||
llm_payload = jsonlib.dumps({
|
||||
"fanout": False,
|
||||
"rationale": "single unit",
|
||||
"title": "Tightened title",
|
||||
"body": "Route to fallback.",
|
||||
"assignee": "made_up",
|
||||
})
|
||||
|
||||
patches = _patch_list_profiles(["orchestrator", "fallback"])
|
||||
for p in patches:
|
||||
p.start()
|
||||
try:
|
||||
with _patch_aux_client(llm_payload), _patch_extra_body(), patch(
|
||||
"hermes_cli.kanban_decompose._load_config",
|
||||
return_value={"kanban": {"default_assignee": "fallback"}},
|
||||
):
|
||||
outcome = decomp.decompose_task(tid, author="me")
|
||||
finally:
|
||||
for p in patches:
|
||||
p.stop()
|
||||
|
||||
assert outcome.ok, outcome.reason
|
||||
with kb.connect() as conn:
|
||||
task = kb.get_task(conn, tid)
|
||||
assert task is not None
|
||||
assert task.assignee == "fallback"
|
||||
|
||||
|
||||
def test_decompose_unknown_assignee_falls_back_to_default(kanban_home):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue