Every developer has muscle memory for the terminal, typing, watching logs stream by, resizing panes, killing a runaway process. But for agent workflows, this interaction layer has always been awkward. You could execute commands remotely, sure but you couldn’t feel the session.
That changes today.
Daytona now supports Pseudo Terminal (PTY) sessions inside sandboxes, giving developers and agents a real, interactive terminal environment with full control over input, output, and process lifecycle.
What PTY Really Means
A Pseudo Terminal is a virtual interface that connects a program to a shell as if it were a physical terminal. In plain terms, it’s what lets Daytona stream your command’s output as it happens, not after the process ends, and lets you send input back in real time.
With PTY sessions, you can:
Execute interactive commands that expect input (read, sudo, npm init, etc.)
Resize terminals dynamically to match your UI or CLI tool
Stream logs and output in real time
Manage and kill long-running processes cleanly
Why This Matters
Before PTY, running interactive processes inside remote sandboxes required hacks: piping inputs, redirecting outputs, or wrapping commands in expect scripts. None of that felt natural.
With PTY, the interaction loop is alive again. Whether you’re building a cloud IDE, running an agentic REPL, or debugging build pipelines, Daytona now lets you keep that local terminal feel inside an isolated, managed environment.
Example: Interactive Commands
Here’s a simple Python example that runs an interactive command, resizes the terminal, and handles live output:
1from daytona import Daytona, Sandbox2from daytona.common.pty import PtySize3import time45def handle_pty_data(data: bytes):6 text = data.decode("utf-8", errors="replace")7 print(text, end="")89pty_handle = sandbox.process.create_pty_session(10 id="interactive-session",11 pty_size=PtySize(cols=300, rows=100)12)1314pty_handle.send_input('printf "Accept terms? (y/n): " && read confirm && if [ "$confirm" = "y" ]; then echo "Accepted"; else echo "Declined"; fi\n')15time.sleep(1)16pty_handle.send_input("y\n")1718pty_session_info = pty_handle.resize(PtySize(cols=210, rows=110))19print(f"Resized to {pty_session_info.cols}x{pty_session_info.rows}")2021pty_handle.send_input('exit\n')22for data in pty_handle:23 handle_pty_data(data)
Managing Long-Running Processes
PTY sessions are also ideal for monitoring processes that never end gracefully — think background tasks, build logs, or AI agent executions:
1pty_handle = sandbox.process.create_pty_session(id="long-run", pty_size=PtySize(cols=120, rows=30))2pty_handle.send_input('while true; do echo "Running... $(date)"; sleep 1; done\n')34time.sleep(3)5print("Killing process...")6pty_handle.kill()
Best Practices
Always clean up: Use
try/finally
to kill PTY sessions and prevent leaks.Check exit codes: Capture and handle non-zero results properly.
Handle data efficiently: Stream and process output instead of buffering large chunks.
Where This Unlocks Value
Cloud IDEs & Agents: Real terminal interaction in remote environments.
Automated Debugging: Stream live build logs and run fix commands interactively.
System Operations: Run admin scripts that require manual input or confirmation.
The Bottom Line
PTY transforms Daytona sandboxes from remote shells into true terminals, alive, responsive, and real-time. This allows agents to interact with the environment as if they were human users in a terminal: executing interactive commands, streaming output live, and responding to input dynamically. The end user can transparently observe the agent’s actions in real time and intervene if something looks off. It brings a natural, human-like interaction loop to cloud-based development, while preserving isolation, security, and automation.
Explore the PTY docs at https://www.daytona.io/docs/en/pty/