Home / Class/ ShellSession Class — langchain Architecture

ShellSession Class — langchain Architecture

Architecture documentation for the ShellSession class in shell_tool.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8["ShellSession"]
  943b36d5_cd9f_c106_7d11_56e39e63078a["shell_tool.py"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|defined in| 943b36d5_cd9f_c106_7d11_56e39e63078a
  322a954d_5e2a_3444_fecf_23cbb2e463c9["__init__()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 322a954d_5e2a_3444_fecf_23cbb2e463c9
  a66768b0_c906_c61b_b24b_37fd445b1af9["start()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| a66768b0_c906_c61b_b24b_37fd445b1af9
  376fc508_1bee_23a7_7de6_267e13821247["restart()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 376fc508_1bee_23a7_7de6_267e13821247
  8e7ca27f_5ba4_f43b_b7dd_ea19f14cf7c4["stop()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 8e7ca27f_5ba4_f43b_b7dd_ea19f14cf7c4
  da18dc22_e4fc_2b4a_2829_9217c9f5d8f5["execute()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| da18dc22_e4fc_2b4a_2829_9217c9f5d8f5
  89d586a2_0b74_ac5c_97da_a6a18a02f59d["_collect_output()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 89d586a2_0b74_ac5c_97da_a6a18a02f59d
  cd8522f1_4b7e_553a_b994_d38d2c6d02fb["_collect_output_after_exit()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| cd8522f1_4b7e_553a_b994_d38d2c6d02fb
  689aee59_b72f_671f_1bc6_26e76e9d6fba["_kill_process()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 689aee59_b72f_671f_1bc6_26e76e9d6fba
  2f7426b9_6136_7c0a_bac5_0f65a2e30ac4["_enqueue_stream()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 2f7426b9_6136_7c0a_bac5_0f65a2e30ac4
  6de1caf7_edd6_8519_6774_9efe986ad3fe["_drain_queue()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 6de1caf7_edd6_8519_6774_9efe986ad3fe
  2c92ef14_d880_f149_5132_20d7d028b5b7["_drain_remaining_stderr()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 2c92ef14_d880_f149_5132_20d7d028b5b7
  6744f48e_023a_08e7_32fe_b5a699793a47["_safe_int()"]
  cf4eeaa4_4bcc_69d9_a0f3_664b1eecb4e8 -->|method| 6744f48e_023a_08e7_32fe_b5a699793a47

Relationship Graph

Source Code

libs/langchain_v1/langchain/agents/middleware/shell_tool.py lines 125–459

class ShellSession:
    """Persistent shell session that supports sequential command execution."""

    def __init__(
        self,
        workspace: Path,
        policy: BaseExecutionPolicy,
        command: tuple[str, ...],
        environment: Mapping[str, str],
    ) -> None:
        self._workspace = workspace
        self._policy = policy
        self._command = command
        self._environment = dict(environment)
        self._process: subprocess.Popen[str] | None = None
        self._stdin: Any = None
        self._queue: queue.Queue[tuple[str, str | None]] = queue.Queue()
        self._lock = threading.Lock()
        self._stdout_thread: threading.Thread | None = None
        self._stderr_thread: threading.Thread | None = None
        self._terminated = False

    def start(self) -> None:
        """Start the shell subprocess and reader threads.

        Raises:
            RuntimeError: If the shell session pipes cannot be initialized.
        """
        if self._process and self._process.poll() is None:
            return

        self._process = self._policy.spawn(
            workspace=self._workspace,
            env=self._environment,
            command=self._command,
        )
        if (
            self._process.stdin is None
            or self._process.stdout is None
            or self._process.stderr is None
        ):
            msg = "Failed to initialize shell session pipes."
            raise RuntimeError(msg)

        self._stdin = self._process.stdin
        self._terminated = False
        self._queue = queue.Queue()

        self._stdout_thread = threading.Thread(
            target=self._enqueue_stream,
            args=(self._process.stdout, "stdout"),
            daemon=True,
        )
        self._stderr_thread = threading.Thread(
            target=self._enqueue_stream,
            args=(self._process.stderr, "stderr"),
            daemon=True,
        )
        self._stdout_thread.start()
        self._stderr_thread.start()

    def restart(self) -> None:
        """Restart the shell process."""
        self.stop(self._policy.termination_timeout)
        self.start()

    def stop(self, timeout: float) -> None:
        """Stop the shell subprocess."""
        if not self._process:
            return

        if self._process.poll() is None and not self._terminated:
            try:
                self._stdin.write("exit\n")
                self._stdin.flush()
            except (BrokenPipeError, OSError):
                LOGGER.debug(
                    "Failed to write exit command; terminating shell session.",
                    exc_info=True,
                )

Frequently Asked Questions

What is the ShellSession class?
ShellSession is a class in the langchain codebase, defined in libs/langchain_v1/langchain/agents/middleware/shell_tool.py.
Where is ShellSession defined?
ShellSession is defined in libs/langchain_v1/langchain/agents/middleware/shell_tool.py at line 125.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free