fix(cli): make plan explain accept plan_id for plan-level explanation #1057
@@ -159,6 +159,7 @@ def step_pec_mock_decision_none(context: Context) -> None:
|
||||
context.pec_decision_id = str(ULID())
|
||||
svc = MagicMock()
|
||||
svc.get_decision.return_value = None
|
||||
svc.list_decisions.return_value = []
|
||||
context.pec_container = _mock_container_with_decision_svc(svc)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@tdd_expected_fail @tdd_bug @tdd_bug_968 @mock_only
|
||||
@tdd_bug @tdd_bug_968 @mock_only
|
||||
Feature: TDD Bug #968 — plan explain expects decision_id but test passes plan_id
|
||||
As a developer
|
||||
I want to verify that `plan explain <plan_id>` succeeds when given a plan ID
|
||||
|
||||
@@ -17,7 +17,7 @@ TDD Plan Explain Succeeds With Plan ID
|
||||
[Documentation] Verify that ``plan explain <plan_id>`` exits with rc=0
|
||||
... when given a plan ID that has associated decisions.
|
||||
... Bug #968: the command currently exits with rc=1.
|
||||
[Tags] tdd_expected_fail tdd_bug tdd_bug_968
|
||||
[Tags] tdd_bug tdd_bug_968
|
||||
${result}= Run Process ${PYTHON} ${HELPER} explain-with-plan-id cwd=${WORKSPACE} timeout=60s on_timeout=kill
|
||||
Log ${result.stdout}
|
||||
Log ${result.stderr}
|
||||
@@ -28,7 +28,7 @@ TDD Plan Explain With Plan ID Shows Root Question
|
||||
[Documentation] Verify that ``plan explain <plan_id>`` output contains
|
||||
... the root decision question when given a plan ID.
|
||||
... Bug #968: the command fails before rendering any output.
|
||||
[Tags] tdd_expected_fail tdd_bug tdd_bug_968
|
||||
[Tags] tdd_bug tdd_bug_968
|
||||
${result}= Run Process ${PYTHON} ${HELPER} explain-plan-id-shows-question cwd=${WORKSPACE} timeout=60s on_timeout=kill
|
||||
Log ${result.stdout}
|
||||
Log ${result.stderr}
|
||||
|
||||
@@ -3132,9 +3132,9 @@ def _build_explain_dict(
|
||||
|
||||
@app.command("explain")
|
||||
def explain_decision_cmd(
|
||||
decision_id: Annotated[
|
||||
identifier: Annotated[
|
||||
str,
|
||||
typer.Argument(help="Decision ULID to explain"),
|
||||
typer.Argument(help="Decision or Plan ULID to explain"),
|
||||
],
|
||||
fmt: Annotated[
|
||||
str,
|
||||
@@ -3149,14 +3149,30 @@ def explain_decision_cmd(
|
||||
typer.Option("--show-reasoning", help="Include rationale and actor reasoning"),
|
||||
] = False,
|
||||
) -> None:
|
||||
"""Explain a single decision in the plan decision tree."""
|
||||
"""Explain a single decision or the root decision of a plan."""
|
||||
from cleveragents.application.container import get_container
|
||||
from cleveragents.application.services.decision_service import (
|
||||
DecisionNotFoundError,
|
||||
)
|
||||
|
||||
container = get_container()
|
||||
svc = container.decision_service()
|
||||
decision = svc.get_decision(decision_id)
|
||||
|
||||
# First, try treating the identifier as a decision_id (backward compat).
|
||||
decision = None
|
||||
with suppress(DecisionNotFoundError):
|
||||
decision = svc.get_decision(identifier)
|
||||
|
||||
# If not found as a decision, try as a plan_id.
|
||||
if decision is None:
|
||||
console.print(f"[red]Error:[/red] Decision '{decision_id}' not found.")
|
||||
decisions = svc.list_decisions(identifier)
|
||||
if decisions:
|
||||
decision = decisions[0]
|
||||
|
||||
if decision is None:
|
||||
console.print(
|
||||
f"[red]Error:[/red] '{identifier}' not found as a decision or plan."
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
|
||||
data = _build_explain_dict(
|
||||
|
||||
Reference in New Issue
Block a user