Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions loopx/control_plane/quota/execution_preparation.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,34 @@ def apply_selected_todo_execution_preparation(
payload["actionable_by_codex"] = False
if obligation is not None:
obligation["must_attempt_work"] = False


def attach_interaction_execution_preparation(
contract: dict[str, Any], payload: dict[str, Any],
) -> None:
preparation = payload.get("execution_preparation")
if not isinstance(preparation, dict):
return
contract["agent_channel"]["execution_preparation"] = preparation
contract["cli_channel"]["execution_preparation"] = preparation
state = preparation.get("state")
if state == "ready":
return
reason = str(preparation.get("reason") or "Selected Todo execution is not prepared.")
contract["agent_channel"]["delivery_allowed"] = False
contract["agent_channel"]["primary_action"] = reason
if state != "claim_required":
return
claim = preparation.get("claim")
command = claim.get("command_line") if isinstance(claim, dict) else None
if isinstance(command, str) and command:
contract["agent_channel"]["must_attempt"] = True
contract["agent_channel"]["quiet_noop_allowed"] = False
contract["agent_channel"]["primary_action"] = (
f"Run the atomic execution preparation action: {command}"
)
contract["cli_channel"]["next_cli_actions"] = [command]
for key in (
"settlement_plan", "quota_spend_source", "replan_settlement_contract",
):
contract["cli_channel"].pop(key, None)
34 changes: 2 additions & 32 deletions loopx/control_plane/work_items/interaction_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ..goals.acceptance_readback import configured_checks
from ..quota.blocked_transition_notice import blocked_priority_fallback_owner_reason
from ..quota.effective_action import EffectiveAction
from ..quota.execution_preparation import attach_interaction_execution_preparation
from ..effect_runtime import effect_runtime_result
import json
import shlex
Expand Down Expand Up @@ -1578,37 +1579,6 @@ def _attach_interaction_vision_wait_state(
}


def _attach_interaction_execution_preparation(
contract: dict[str, Any], payload: dict[str, Any],
) -> None:
preparation = payload.get("execution_preparation")
if not isinstance(preparation, dict):
return
contract["agent_channel"]["execution_preparation"] = preparation
contract["cli_channel"]["execution_preparation"] = preparation
state = preparation.get("state")
if state == "ready":
return
reason = str(preparation.get("reason") or "Selected Todo execution is not prepared.")
contract["agent_channel"]["delivery_allowed"] = False
contract["agent_channel"]["primary_action"] = reason
if state != "claim_required":
return
claim = preparation.get("claim")
command = claim.get("command_line") if isinstance(claim, dict) else None
if isinstance(command, str) and command:
contract["agent_channel"]["must_attempt"] = True
contract["agent_channel"]["quiet_noop_allowed"] = False
contract["agent_channel"]["primary_action"] = (
f"Run the atomic execution preparation action: {command}"
)
contract["cli_channel"]["next_cli_actions"] = [command]
for key in (
"settlement_plan", "quota_spend_source", "replan_settlement_contract",
):
contract["cli_channel"].pop(key, None)


def _interaction_fallback_policy_required(payload: Mapping[str, object], *, mode: str) -> bool:
return mode in {
"user_gate",
Expand Down Expand Up @@ -1747,7 +1717,7 @@ def _build_interaction_contract_projection(
registry_path=registry_path,
),
}
_attach_interaction_execution_preparation(contract, payload)
attach_interaction_execution_preparation(contract, payload)
response_plan = _build_interaction_response_plan(
user_channel=user_channel,
agent_channel=agent_channel,
Expand Down
Loading