fix(acms): resolve AmbiguousStep conflicts, format specifier errors, and duplicate step definitions

Convert all Behave {param:d/f/int} cucumber-expression format specifiers
to raw regex patterns (\d+, [\d.]+) compatible with behave 1.3.x parse
library. Remove duplicate @given/@then step definitions across both ACMS
step files that caused AmbiguousStep errors: budget_override and assembled
context budget assertions. Remove overlapping 'I prepare LLM context'
handlers that matched the same plain text feature steps. Restore missing
ContextPolicyConfig/ConfigurationLoader/PolicyScope/ViewPolicyConfiguration
imports in acms/__init__.py.

ISSUES CLOSED: #9584
This commit is contained in:
2026-05-08 22:27:51 +00:00
committed by Forgejo
parent 9a9214dcf1
commit a8cfee5b37
2 changed files with 27 additions and 56 deletions
@@ -87,11 +87,11 @@ def step_check_view_name(context: Any, view_name: str) -> None:
assert context.loaded_config.view_name == view_name
@then("the configuration should have {count:d} policy")
def step_check_policy_count(context: Any, count: int) -> None:
@then(r"the configuration should have (\d+) policy")
def step_check_policy_count(context: Any, count: str) -> None:
"""Check the number of policies in the configuration."""
assert context.loaded_config is not None
assert len(context.loaded_config.policies) == count
assert len(context.loaded_config.policies) == int(count)
@then("the first policy should have name {name}")
@@ -102,20 +102,20 @@ def step_check_first_policy_name(context: Any, name: str) -> None:
assert context.loaded_config.policies[0].name == name
@then("the first policy should have priority_weight {weight:f}")
def step_check_first_policy_priority(context: Any, weight: float) -> None:
@then(r"the first policy should have priority_weight ([\d.]+)")
def step_check_first_policy_priority(context: Any, weight_str: str) -> None:
"""Check the priority weight of the first policy."""
assert context.loaded_config is not None
assert len(context.loaded_config.policies) > 0
assert context.loaded_config.policies[0].priority_weight == weight
assert context.loaded_config.policies[0].priority_weight == float(weight_str)
@then("the first policy should have budget_override {budget:d}")
def step_check_first_policy_budget(context: Any, budget: int) -> None:
@then(r"the first policy should have budget_override (\d+)")
def step_check_first_policy_budget(context: Any, budget: str) -> None:
"""Check the budget override of the first policy."""
assert context.loaded_config is not None
assert len(context.loaded_config.policies) > 0
assert context.loaded_config.policies[0].budget_override == budget
assert context.loaded_config.policies[0].budget_override == int(budget)
@then("I should get a validation error about missing name field")
@@ -276,8 +276,8 @@ def step_have_multiple_policies(context: Any) -> None:
)
@given("policy1 has priority_weight {weight:f}")
def step_policy1_priority(context: Any, weight: float) -> None:
@given(r"policy1 has priority_weight ([\d.]+)")
def step_policy1_priority(context: Any, weight_str: str) -> None:
"""Set priority weight for policy1."""
if context.policy_config.policies:
context.policy_config.policies[0].priority_weight = weight
@@ -288,8 +288,8 @@ def step_policy1_priority(context: Any, weight: float) -> None:
)
@given("policy2 has priority_weight {weight:f}")
def step_policy2_priority(context: Any, weight: float) -> None:
@given(r"policy2 has priority_weight ([\d.]+)")
def step_policy2_priority(context: Any, weight_str: str) -> None:
"""Set priority weight for policy2."""
if len(context.policy_config.policies) > 1:
context.policy_config.policies[1].priority_weight = weight
@@ -315,18 +315,6 @@ def step_policy2_before_policy1(context: Any) -> None:
assert context.applied_policies[0] == "policy2"
@given("the policy has budget_override {budget:d}")
def step_policy_budget_override(context: Any, budget: int) -> None:
"""Set budget override for the policy."""
if context.policy_config.policies:
context.policy_config.policies[0].budget_override = budget
# Reinitialize integration if present (for plan execution integration tests)
if hasattr(context, "integration"):
context.integration = PlanExecutionACMSIntegration(
policy_config=context.policy_config
)
@when("I apply the policy to context")
def step_apply_policy(context: Any) -> None:
"""Apply policy to context."""
@@ -334,15 +322,15 @@ def step_apply_policy(context: Any) -> None:
context.assembled = context.assembler.assemble_context({})
@then("the assembled context should have budget {budget:d}")
def step_check_assembled_budget(context: Any, budget: int) -> None:
@then(r"the assembled context should have budget (\d+)")
def step_check_assembled_budget(context: Any, budget: str) -> None:
"""Check the budget in the assembled context."""
# Support both direct assembler context and integration context
assembled = getattr(context, "assembled", None) or getattr(
context, "llm_context", None
)
assert assembled is not None
assert assembled["assembled_data"].get("budget") == budget
assert assembled["assembled_data"].get("budget") == int(budget)
@when("I assemble context")
@@ -29,10 +29,10 @@ from cleveragents.application.services.plan_executor import (
from cleveragents.tool.runner import ToolRunner
@when("I prepare LLM context$")
@when(r"I prepare LLM context$")
def step_prepare_llm_context_generic(context: Any) -> None:
"""Prepare LLM context. Handles both plain 'prepare LLM context' and qualified versions."""
if context.integration is not None:
"""Prepare LLM context for a plain text step with no qualifiers."""
if hasattr(context, "integration") and context.integration is not None:
raw = getattr(context, "raw_context", {"file_type": "python"})
context.llm_context = context.integration.prepare_llm_context(raw)
@@ -51,10 +51,10 @@ def step_no_policy_config(context: Any) -> None:
context.integration = PlanExecutionACMSIntegration(policy_config=None)
@given("I have a policy configuration with {count:d} policy")
def step_have_policy_config(context: Any, count: int) -> None:
@given(r"I have a policy configuration with (\d+) policy")
def step_have_policy_config(context: Any, count: str) -> None:
"""Create a policy configuration with specified number of policies."""
policies = [ContextPolicyConfig(name=f"policy{i + 1}") for i in range(count)]
policies = [ContextPolicyConfig(name=f"policy{i + 1}") for i in range(int(count))]
context.policy_config = ViewPolicyConfiguration(
view_name="test_view",
policies=policies,
@@ -209,12 +209,6 @@ def step_have_multiple_policies(context: Any) -> None:
)
@when("I prepare LLM context")
def step_prepare_llm_context_simple(context: Any) -> None:
"""Prepare LLM context."""
context.llm_context = context.integration.prepare_llm_context({})
@then("policy2 should be applied before policy1 in the assembled context")
def step_check_policy_order(context: Any) -> None:
"""Check that policy2 is applied before policy1."""
@@ -240,10 +234,10 @@ def step_have_scope_rules(context: Any) -> None:
)
@given("policy{count:d} has priority_weight {weight:f}")
def step_set_policy_priority(context: Any, count: int, weight: float) -> None:
@given(r"policy(\d+) has priority_weight ([\d.]+)")
def step_set_policy_priority(context: Any, count: str, weight: str) -> None:
"""Set the priority weight for a specific policy by index."""
idx = count - 1
idx = int(count) - 1
if (
context.policy_config
and context.policy_config.policies
@@ -256,8 +250,8 @@ def step_set_policy_priority(context: Any, count: int, weight: float) -> None:
)
@given("the policy has budget_override {amount:int}")
def step_set_policy_budget(context: Any, amount: int) -> None:
@given(r"the policy has budget_override (\d+)")
def step_set_policy_budget(context: Any, amount: str) -> None:
"""Set the budget override for the first policy in the configuration."""
if context.policy_config and context.policy_config.policies:
context.policy_config.policies[0].budget_override = int(amount)
@@ -294,17 +288,6 @@ def step_policy_applied(context: Any) -> None:
assert "policy1" in policies_applied
@then("the assembled context should have budget {amount:int}")
def step_check_budget(context: Any, amount: int) -> None:
"""Check that the assembled context includes the expected budget override."""
assert context.llm_context is not None
assembled_data = context.llm_context.get("assembled_data", {})
assert "budget" in assembled_data, (
f"Expected 'budget' key in assembled_data, got keys: {list(assembled_data.keys())}"
)
assert assembled_data["budget"] == int(amount)
@then("the policy should not be applied to the LLM context")
def step_policy_not_applied(context: Any) -> None:
"""Check that the policy was NOT applied."""