Skip to main content

Module long_running

Module long_running 

Source
Expand description

Long-running tool handle machinery.

When a caller passes long_running: true to run_command, run_test, or run_build_command, the builtin spawns the child process without waiting, registers it here, and returns a handle dict immediately:

{
  "handle_id": "hto-<pid-hex>-<n>",
  "started_at": "...",
  "command_or_op_descriptor": "..."
}

A background thread waits for the child and, when it exits, pushes a tool_result entry into the active session’s agent_inbox via harn_vm::orchestration::agent_inbox::push(...) so the agent-loop’s next turn-preflight (or post-compaction drain) picks it up.

§Cancellation

cancel_handle(handle_id) kills the spawned process (SIGKILL) within 2 seconds. The session-end hook registered on startup kills every in-flight handle associated with the ending session.

§PID-based signaling

The waiter thread takes ownership of the Child object to drain stdout/stderr and call wait(). To keep cancellation possible even after the waiter has taken the Child, we store the raw OS process ID in the entry and kill by PID when needed. On Unix we call kill(2) directly via an extern "C" declaration (no libc crate required). A shared cancelled flag suppresses the feedback push when the waiter sees an exit caused by cancellation. Callers that need artifact-stable cancellation can opt into waiting for the waiter result through cancel_handle.

Structs§

LongRunningHandleInfo
Metadata returned to the caller immediately when a long-running spawn succeeds. Serialised as a response dict by the calling builtin.

Functions§

cancel_handle
Cancel a specific in-flight long-running handle. Kills the process and lets the waiter drain output/artifacts. Returns true if the handle was found and cancellation was newly requested.
cancel_session_handles
Cancel all in-flight handles for a given session. Called by the session-end hook to avoid orphaned processes.
register_completion_notifier
Register a completion notifier for handle_id. The waiter thread sends () on the returned receiver after it pushes the feedback item to the global queue. Returns None if the handle is no longer in the store (e.g. already cancelled or completed). Used by tests to await waiter completion deterministically — no polling, no thread::sleep.
spawn_long_running
Spawn the argv as a long-running child process and return a handle.