MCPcopy Create free account
hub / github.com/MiniMax-AI/Mini-Agent / BackgroundShellManager

Class BackgroundShellManager

mini_agent/tools/bash_tool.py:108–214  ·  view source on GitHub ↗

Manager for all background shell processes.

Source from the content-addressed store, hash-verified

106
107
108class BackgroundShellManager:
109 """Manager for all background shell processes."""
110
111 _shells: dict[str, BackgroundShell] = {}
112 _monitor_tasks: dict[str, asyncio.Task] = {}
113
114 @classmethod
115 def add(cls, shell: BackgroundShell) -> None:
116 """Add a background shell to management."""
117 cls._shells[shell.bash_id] = shell
118
119 @classmethod
120 def get(cls, bash_id: str) -> BackgroundShell | None:
121 """Get a background shell by ID."""
122 return cls._shells.get(bash_id)
123
124 @classmethod
125 def get_available_ids(cls) -> list[str]:
126 """Get all available bash IDs."""
127 return list(cls._shells.keys())
128
129 @classmethod
130 def _remove(cls, bash_id: str) -> None:
131 """Remove a background shell from management (internal use only)."""
132 if bash_id in cls._shells:
133 del cls._shells[bash_id]
134
135 @classmethod
136 async def start_monitor(cls, bash_id: str) -> None:
137 """Start monitoring a background shell's output."""
138 shell = cls.get(bash_id)
139 if not shell:
140 return
141
142 async def monitor():
143 try:
144 process = shell.process
145 # Continuously read output until process ends
146 while process.returncode is None:
147 try:
148 if process.stdout:
149 line = await asyncio.wait_for(process.stdout.readline(), timeout=0.1)
150 if line:
151 decoded_line = line.decode("utf-8", errors="replace").rstrip("\n")
152 shell.add_output(decoded_line)
153 else:
154 break
155 except asyncio.TimeoutError:
156 await asyncio.sleep(0.1)
157 continue
158 except Exception:
159 await asyncio.sleep(0.1)
160 continue
161
162 # Process ended, wait for exit code
163 try:
164 returncode = await process.wait()
165 except Exception:

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected