Skip to content

Add generic background service execution for persistent Bash commands#301

Open
mmprotest wants to merge 1 commit into
mainfrom
mmprotest/add-background-service-support-to-runner
Open

Add generic background service execution for persistent Bash commands#301
mmprotest wants to merge 1 commit into
mainfrom
mmprotest/add-background-service-support-to-runner

Conversation

@mmprotest

Copy link
Copy Markdown
Owner

Motivation

  • Prevent long-lived server/process commands from blocking the mission loop by introducing first-class background service support at the runner infrastructure level.
  • Provide a structured lifecycle and readiness checks so persistent processes return control immediately while still exposing PID/URL/logs/readiness to the agent.
  • Keep the change generic and cross-platform and avoid changing short-lived command semantics.

Description

  • New service runtime in villani_code/services.py implementing a ServiceManager and ServiceRecord with lifecycle APIs: start_service, stop_service, get_service_status, and list_services, plus cleanup_services_started_after for mission-time cleanup.
  • Conservative service classification heuristics and endpoint inference are provided (is_likely_service_command, patterns and hint list), and bounded readiness probing is implemented (probe_service_readiness) using TCP connect and optional HTTP GET with per-attempt diagnostics.
  • Routed likely persistent Bash commands through service mode inside villani_code/tools.py so Bash calls that look like servers are launched detached (non-blocking), have stdout/stderr captured to .villani_code/services/*.log, and immediately return a structured service result (mode: "service", service metadata). Short-lived commands continue to use the existing blocking shell path (mode: "command").
  • Integrated the runner with services by creating a ServiceManager on Runner (in villani_code/state.py), passing it into tool execution (state_tooling.execute_tool_with_lifecycle) and performing best-effort cleanup of services started during a mission completion/error paths, and extended Bash result decoding to include mode and service fields.
  • Emits runtime/debug events for important service lifecycle stages (service_launch_requested, service_process_spawned, service_readiness_probe_attempt, service_readiness_succeeded / service_readiness_failed, service_stopped). Platform-specific process-group handling is isolated in the spawn/stop paths (start_new_session + killpg on POSIX, process-group creation/terminate on Windows).

Testing

  • Added tests/test_services.py which includes classification unit tests, readiness probe unit test, an integration test that starts python -m http.server, probes it, and stops it, and regression tests verifying persistent commands return immediately and short-lived commands preserve the original execution path; these tests passed locally under pytest.
  • Ran targeted test suites: pytest -q tests/test_services.py tests/test_tools_patch_debug_events.py tests/test_trace_summary.py::test_bash_tool_finalization_from_tool_result completed successfully (all passed), and pytest -q tests/test_trace_runtime_path.py tests/test_trace_summary.py also completed successfully (all passed).
  • A few attempted test invocations that specified non-matching test node IDs returned no-matching-node errors and did not execute tests, but all newly added and directly related regression tests passed in the automated runs.

Codex Task

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant