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
47 changes: 43 additions & 4 deletions loopx/capabilities/reward_memory/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def reward_memory_goal_configuration_summary(
and receipt.get("exact_readback_verified") is True
)
effective_verified_agents: list[str] = []
configured_automatic_ingest = False
configured_automatic_recall = False
for agent_id in recorded_verified_agents:
try:
status, _ = resolve_goal_reward_memory_experiment(
Expand All @@ -65,6 +67,14 @@ def reward_memory_goal_configuration_summary(
continue
if status.get("available") is True:
effective_verified_agents.append(agent_id)
configured_automatic_ingest = (
configured_automatic_ingest
or status.get("automatic_ingest") is True
)
configured_automatic_recall = (
configured_automatic_recall
or status.get("automatic_recall") is True
)
effective_available = bool(effective_verified_agents)
return {
"enabled": policy["enabled"],
Expand All @@ -75,17 +85,46 @@ def reward_memory_goal_configuration_summary(
"experimental": policy["experimental"],
"config_pointer_registered": bool(policy["config_path"]),
"binding_revision": binding_revision,
"automatic_ingest": effective_available
and policy["automation"].get("automatic_ingest") is True,
"automatic_recall": effective_available
and policy["automation"].get("automatic_recall") is True,
"automatic_ingest": policy["automation"].get("automatic_ingest") is True
and configured_automatic_ingest,
"automatic_recall": policy["automation"].get("automatic_recall") is True
and configured_automatic_recall,
"automation_intent": dict(policy["automation_intent"]),
"host_coverage": reward_memory_host_coverage(),
"enabled_agents": list(policy["enabled_agents"]),
"enablement_verified_agents": effective_verified_agents,
}


def reward_memory_automatic_ingest_for_agent(
goal: Mapping[str, Any], agent_id: str | None
) -> bool:
"""Return whether one Agent may receive automatic-ingest prompt guidance.

Desired policy is a cheap off switch. Active admission reuses the runtime
resolver so the prompt requires this exact Agent's current config binding
and verified enablement receipt. The resolver is read-only and never calls
the configured provider.
"""

policy = reward_memory_goal_policy(goal)
if (
not policy["enabled"]
or policy["automation"].get("automatic_ingest") is not True
or not isinstance(agent_id, str)
or not agent_id.strip()
):
return False
try:
status, _ = resolve_goal_reward_memory_experiment(
goal=goal, agent_id=agent_id
)
except ValueError:
# Legacy alias-only registrations and malformed identities fail closed.
return False
return status.get("available") is True and status.get("automatic_ingest") is True


def plan_reward_memory_goal_configuration(
*,
goal: Mapping[str, Any],
Expand Down
18 changes: 10 additions & 8 deletions loopx/cli_commands/support_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
DEFAULT_CHAT_PORT,
serve_chat,
)
from ..control_plane.reward_memory import reward_memory_goal_policy
from ..control_plane.scheduler.execution_context import SchedulerRuntimeProfile
from ..dashboard_launcher import launch_dashboard, replace_existing_loopx_chat
from ..execution_profile import execution_profile_turn_granularity
Expand Down Expand Up @@ -313,13 +312,6 @@ def handle_support_control_command(
if isinstance(registry_goal, dict)
else None
)
reward_memory_policy = reward_memory_goal_policy(
registry_goal if isinstance(registry_goal, dict) else {}
)
reward_memory_enabled = bool(
reward_memory_policy["enabled"]
and reward_memory_policy["automation"].get("automatic_ingest") is True
)
agent_profile = None
if args.agent_id:
effective_agent_id = require_registered_agent_id(
Expand All @@ -331,6 +323,16 @@ def handle_support_control_command(
agent_profile = agent_profile_from_registry(
agent_registry_path, args.goal_id, effective_agent_id
)
reward_memory_enabled = False
if effective_agent_id is not None:
from ..capabilities.reward_memory.configuration import (
reward_memory_automatic_ingest_for_agent,
)

reward_memory_enabled = reward_memory_automatic_ingest_for_agent(
registry_goal if isinstance(registry_goal, dict) else {},
effective_agent_id,
)
explicit_scheduler_fields = (
args.host_surface,
args.scheduler_owner,
Expand Down
4 changes: 2 additions & 2 deletions loopx/semantics/project_registry_io_manifest_v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2287,15 +2287,15 @@
},
{
"site": "loopx/upgrade.py::<module>.build_upgrade_plan::codec_read:load_registry#1",
"line": 741,
"line": 744,
"column": 16,
"kind": "codec_read",
"api": "load_registry",
"classification": "codec_api"
},
{
"site": "loopx/upgrade.py::<module>.build_upgrade_plan::codec_read:load_registry#2",
"line": 747,
"line": 750,
"column": 24,
"kind": "codec_read",
"api": "load_registry",
Expand Down
15 changes: 9 additions & 6 deletions loopx/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
)
from .execution_profile import execution_profile_turn_granularity
from .heartbeat_prompt import build_heartbeat_prompt
from .control_plane.reward_memory import reward_memory_goal_policy
from .history import load_registry
from .paths import global_registry_path, resolve_runtime_root, select_default_runtime_root
from .registry import registry_goals, resolve_state_file
Expand Down Expand Up @@ -85,11 +84,15 @@ def goal_heartbeat_prompt(
repo = Path(str(goal.get("repo") or ".")).expanduser()
state_file = resolve_state_file(repo, goal.get("state_file"))
registered_agents = registered_agent_ids_for_goal(goal)
reward_memory_policy = reward_memory_goal_policy(goal)
reward_memory_enabled = bool(
reward_memory_policy["enabled"]
and reward_memory_policy["automation"].get("automatic_ingest") is True
)
reward_memory_enabled = False
if agent_id is not None:
from .capabilities.reward_memory.configuration import (
reward_memory_automatic_ingest_for_agent,
)

reward_memory_enabled = reward_memory_automatic_ingest_for_agent(
goal, agent_id
)
return build_heartbeat_prompt(
goal_id=goal_id,
active_state=None,
Expand Down
Loading
Loading