Skip to content

datarobot_genai.drtools.core.sandbox.protocol

protocol

Wire contract between the caller and the container runner.

The runner that executes user code inside the sandbox image is owned by datarobot/datarobot-user-models (public_dropin_environments/ dr_mcp_execute_sandbox_minimal/runner.py, PR datarobot/datarobot-user-models#2137). That runner and this module are the two ends of a small protocol used by the container-backed sandbox (:class:DataRobotWorkloadSandbox):

  • The runner emits its return value as a final stdout line prefixed with :data:RESULT_MARKER; :func:parse_result_marker strips and decodes it.
  • The runner exits :data:SANDBOX_TIMEOUT_EXIT_CODE when its in-process wall-clock cap fires; the caller maps that to SandboxTimeout.

Only these constants + the parser are shared, so we keep them here rather than carrying a hand-synced duplicate of the whole runner in this repo (the runner body would inevitably drift from the image copy).

has_result_marker

has_result_marker(stdout: str) -> bool

Whether stdout contains a result-marker line (see :func:parse_result_marker).

Source code in datarobot_genai/drtools/core/sandbox/protocol.py
def has_result_marker(stdout: str) -> bool:
    """Whether ``stdout`` contains a result-marker line (see :func:`parse_result_marker`)."""
    return _marker_line_index(stdout.splitlines()) != -1

parse_result_marker

parse_result_marker(stdout: str) -> tuple[str, Any]

Split the result marker off stdout.

Returns (clean_stdout, return_value): the last line that starts with :data:RESULT_MARKER is removed from the returned stdout and its JSON payload is decoded as the return value (None on decode failure). When no marker line is present, stdout is returned unchanged with a None value.

Source code in datarobot_genai/drtools/core/sandbox/protocol.py
def parse_result_marker(stdout: str) -> tuple[str, Any]:
    """Split the result marker off ``stdout``.

    Returns ``(clean_stdout, return_value)``: the last line that starts with
    :data:`RESULT_MARKER` is removed from the returned stdout and its JSON
    payload is decoded as the return value (``None`` on decode failure). When no
    marker line is present, stdout is returned unchanged with a ``None`` value.
    """
    lines = stdout.splitlines()
    idx = _marker_line_index(lines)
    if idx == -1:
        return stdout, None
    encoded = lines[idx][len(RESULT_MARKER) :]
    try:
        value = json.loads(encoded)
    except json.JSONDecodeError:
        value = None
    return "\n".join(lines[:idx] + lines[idx + 1 :]), value