How to Integrate LoopX with Codex App for Heartbeat Automation
To integrate LoopX with a Codex App for heartbeat automation, enable the codex_app_heartbeat runtime profile, generate a specialized prompt using build_heartbeat_prompt, and schedule the resulting CLI command to run at regular intervals on the Codex App host.
The huangruiteng/loopx repository provides native infrastructure for autonomous "heartbeat" runs that allow a Codex App to execute automation tasks on a schedule without consuming quota. This integration relies on three core concepts—a Runtime Profile, a Host Surface, and a Heartbeat Prompt Builder—that work together to construct executable CLI payloads. When properly configured, LoopX emits a JSON response containing the exact command and task body your Codex App needs to maintain continuous operation.
Core Concepts for Codex App Integration
Understanding how LoopX identifies and communicates with a Codex App requires familiarity with three specific abstractions defined in the source code.
Runtime Profile (codex_app_heartbeat)
The Runtime Profile tells the LoopX scheduler that a turn should be treated as a heartbeat-only automation. Defined in loopx/control_plane/scheduler/execution_context.py as part of the SchedulerRuntimeProfile enum, the codex_app_heartbeat profile signals that no quota should be spent and no agent work should be performed unless explicitly required.
Host Surface (codex_app_heartbeat_automation)
The Host Surface marks the Codex App as the execution host for the heartbeat prompt. Located in loopx/host_loop_activation.py, the constant codex_app_heartbeat_automation identifies where the heartbeat automation runs. LoopX detects the appropriate host through the logic in uses_native_goal_host_loop or uses_ark_managed_agent_goal_host; when the profile is set to codex_app_heartbeat, native_goal_host becomes True.
Heartbeat Prompt Builder (build_heartbeat_prompt)
The Heartbeat Prompt Builder constructs the full payload that the Codex App consumes. Implemented in loopx/heartbeat_prompt.py, the build_heartbeat_prompt function generates CLI commands, task bodies, budget constraints, and host contracts. It supports multiple output modes—thin (default), full, compact, and brief—allowing you to control the verbosity of the generated automation instructions.
Step-by-Step Integration Guide
Follow these steps to connect LoopX with your Codex App for automated heartbeat execution.
1. Enable the Heartbeat Profile
Onboard your Codex App by enabling the heartbeat profile using the helper function in loopx/bootstrap.py.
from loopx.bootstrap import normalize_codex_app_heartbeat
# Accepts "ask", "yes", or "no"
codex_app_heartbeat = normalize_codex_app_heartbeat("yes")
This configuration tells LoopX to treat subsequent runs as native heartbeat automations.
2. Generate the Heartbeat Prompt
Call build_heartbeat_prompt from loopx/heartbeat_prompt.py to create the executable payload. Specify the goal_id, set runtime_profile to "codex_app_heartbeat", and optionally provide a custom cli_bin if your LoopX binary is renamed.
from loopx.heartbeat_prompt import build_heartbeat_prompt
payload = build_heartbeat_prompt(
goal_id="my-codex-app-goal",
runtime_profile="codex_app_heartbeat",
thin=True, # Default mode; use False for full output
cli_bin="loopx"
)
print(payload["thin_prompt_command"])
# Output: loopx heartbeat-prompt --thin --goal-id my-codex-app-goal
The function automatically generates a task body explaining the automation steps, includes a quota-guard command, and adds a host_contract for Ark-managed-agent goals.
3. Schedule the Command on the Codex App
Use a scheduler like cron to execute the generated command at regular intervals. Because the payload flags heartbeat_turn_receipt as True for native hosts, the scheduler will not count these turns against your quota.
# Run every 5 minutes
*/5 * * * * /usr/local/bin/loopx heartbeat-prompt --thin --goal-id my-codex-app-goal \
>> /var/log/loopx/heartbeat.log 2>&1
4. Handle the JSON Response
The heartbeat command prints a JSON payload. Parse the response to check execution status and act on any recommendations.
import json
import subprocess
result = subprocess.run(
["loopx", "heartbeat-prompt", "--thin", "--goal-id", "my-codex-app-goal"],
capture_output=True,
text=True
)
payload = json.loads(result.stdout)
if payload["ok"]:
print("Task body:", payload["task_body"])
# Inspect payload["heartbeat_recommendation"] if present
else:
print("Heartbeat failed:", payload["error"])
5. Configure Peer-Agent Identity (Optional)
If multiple agents cooperate on the same goal, provide registered_agents and agent_id to build_heartbeat_prompt. LoopX embeds a peer-agent instruction block that the Codex App uses for coordinated work.
heartbeat = build_heartbeat_prompt(
goal_id="multi-agent-goal",
runtime_profile="codex_app_heartbeat",
agent_id="agent-001",
registered_agents=["agent-001", "agent-002"]
)
Complete Implementation Examples
Python: Generating and Inspecting the Prompt
from loopx.heartbeat_prompt import build_heartbeat_prompt
# Generate a thin heartbeat prompt for a Codex App
heartbeat = build_heartbeat_prompt(
goal_id="codex-automation-goal",
runtime_profile="codex_app_heartbeat",
cli_bin="loopx"
)
print("Command to schedule:")
print(heartbeat["thin_prompt_command"])
print("\nTask body preview:")
print(heartbeat["task_body"][:500])
Bash: Cron Entry with JSON Parsing
# Runs every 3 minutes, extracts task body using jq
*/3 * * * * /usr/local/bin/loopx heartbeat-prompt --thin --goal-id codex-automation-goal \
| jq -r '.task_body' > /tmp/codex_heartbeat.txt 2>> /var/log/loopx/errors.log
Python: Full Response Handler with Error Checking
import json
import subprocess
import pathlib
def run_heartbeat(goal_id: str) -> dict:
cmd = ["loopx", "heartbeat-prompt", "--thin", "--goal-id", goal_id]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
return {"ok": False, "error": result.stderr}
return json.loads(result.stdout)
payload = run_heartbeat("codex-automation-goal")
if payload.get("ok"):
pathlib.Path("/tmp/last_heartbeat.txt").write_text(payload["task_body"])
print("Budget allocated:", payload["interface_budget"])
else:
print("Failed:", payload.get("error", "Unknown error"))
Summary
- Enable the profile: Use
normalize_codex_app_heartbeatinloopx/bootstrap.pyto activate heartbeat automation for your Codex App. - Generate the payload: Call
build_heartbeat_promptfromloopx/heartbeat_prompt.pywithruntime_profile="codex_app_heartbeat"to create CLI commands and task bodies. - Schedule execution: Run the generated
loopx heartbeat-promptcommand viacronor a daemon on the Codex App host; thecodex_app_heartbeatprofile ensures these runs bypass quota limits. - Parse responses: Handle the JSON output containing
task_body,interface_budget, and optionalheartbeat_recommendationfields to drive downstream logic. - Coordinate agents: Pass
agent_idandregistered_agentsto support multi-agent workflows managed through the Codex App host surface.
Frequently Asked Questions
What is the difference between thin, full, compact, and brief heartbeat modes?
The thin mode (default) generates a minimal prompt containing only essential CLI commands and task instructions. Full mode includes complete context and history, compact provides a summarized version, and brief offers a truncated output suitable for high-frequency polling. Specify the mode in build_heartbeat_prompt using thin=True, full=True, compact=True, or brief=True.
How does the codex_app_heartbeat runtime profile prevent quota consumption?
When runtime_profile is set to codex_app_heartbeat, LoopX sets heartbeat_turn_receipt to True in the execution context defined in loopx/control_plane/scheduler/execution_context.py. The scheduler recognizes this flag and excludes the turn from quota calculations unless a downstream operation explicitly requests agent work.
Can I customize the CLI binary name in the generated prompt?
Yes. Pass the cli_bin parameter to build_heartbeat_prompt. For example, setting cli_bin="loopx-custom" results in commands like loopx-custom heartbeat-prompt --thin --goal-id <goal> instead of the default loopx binary name.
What fields are included in the JSON payload returned by the heartbeat command?
The payload includes expanded_prompt_command (the full CLI string), task_body (automation instructions), interface_budget (resource constraints), ok (boolean success status), and optionally error (failure message) or heartbeat_recommendation (actionable advice such as pause_or_delete_current_heartbeat).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →