> ## Documentation Index
> Fetch the complete documentation index at: https://novita.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Interactieve terminal (PTY)

export const SandboxConfigHint = () => {
  if (typeof document === "undefined") {
    return null;
  } else {
    return <Note>Before running the example code in this document, please ensure you have properly configured environment variables. For details, please refer to <a href="/docs/nl/guides/sandbox-your-first-agent-sandbox#configure-environment-variables">Configure Environment Variables</a>.</Note>;
  }
};

De PTY-, of pseudo-terminal-, module maakt interactieve terminalsessies binnen de sandbox mogelijk met realtime, bidirectionele communicatie.

Een PTY-sessie ondersteunt **realtime streaming**, waarbij terminaluitvoer continu via callbacks wordt geleverd terwijl deze wordt geproduceerd, en biedt **bidirectionele invoer**, waardoor gegevens kunnen worden verzonden terwijl de sessie nog actief is. Het biedt ook een **interactieve shell**-ervaring met volledig terminalgedrag, inclusief ANSI-kleuren en escape-sequenties, en ondersteunt **sessiepersistentie**, zodat een actieve sessie kan worden losgekoppeld en later opnieuw kan worden verbonden.

<SandboxConfigHint />

## Een PTY-sessie maken

Je kunt `sandbox.pty.create()` gebruiken om een interactieve bash-shell te starten.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,              // Terminal width in characters
    rows: 24,              // Terminal height in characters
    onData: (data) => {
      // Called whenever terminal outputs data
      process.stdout.write(data)
    },
    envs: { MY_VAR: 'hello' },  // Optional environment variables
    cwd: '/home/user',          // Optional working directory
    user: 'root',               // Optional user to run as
  })

  // terminal.pid contains the process ID
  console.log('Terminal PID:', terminal.pid)
  ```

  ```python Python icon="python" theme={"system"}
  import threading

  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(
      size=PtySize(rows=24, cols=80),  # PtySize is (rows, cols)
      envs={'MY_VAR': 'hello'},        # Optional environment variables
      cwd='/home/user',                # Optional working directory
      user='root',                     # Optional user to run as
  )

  # terminal.pid contains the process ID
  print('Terminal PID:', terminal.pid)

  # The Python SDK has no on_data param. Output is streamed via wait(on_pty=...),
  # which blocks, so run it in a background thread.
  threading.Thread(
      target=lambda: terminal.wait(on_pty=lambda data: print(data.decode(), end='')),
      daemon=True,
  ).start()
  ```
</CodeGroup>

<Note>
  De PTY start een interactieve bash-shell met `TERM=xterm-256color`, zodat ANSI-kleuren en escape-sequenties werken zoals verwacht.
</Note>

## Timeout

De timeout-instelling is configureerbaar en bepaalt hoelang de PTY-sessie actief blijft. Je kunt een PTY-sessie onbeperkt openhouden door `timeoutMs: 0` in JavaScript of `timeout=0` in Python in te stellen. De sessie gebruikt standaard een timeout van 60 seconden.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => process.stdout.write(data),
    timeoutMs: 0,  // Keep the session open indefinitely
  })
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(
      size=PtySize(rows=24, cols=80),
      timeout=0,  # Keep the session open indefinitely
  )
  ```
</CodeGroup>

## Invoer naar PTY verzenden

Je kunt `sendInput()` in JavaScript of `send_stdin()` in Python gebruiken om gegevens naar de terminal te verzenden.

In JavaScript retourneert `sendInput()` een Promise, en alle terminaluitvoer wordt geleverd via de callback `onData` in plaats van direct te worden geretourneerd.
In Python wordt `send_stdin()` synchroon voltooid, en alle terminaluitvoer wordt geleverd via de callback `on_pty` die aan `wait()` wordt doorgegeven.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => process.stdout.write(data),
  })

  // Send a command (don't forget the newline!)
  await sandbox.pty.sendInput(
    terminal.pid,
    new TextEncoder().encode('echo "Hello from PTY"\n')
  )
  ```

  ```python Python icon="python" theme={"system"}
  import threading

  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(size=PtySize(rows=24, cols=80))

  # Stream output in a background thread (Python uses wait(on_pty=...))
  threading.Thread(
      target=lambda: terminal.wait(on_pty=lambda data: print(data.decode(), end='')),
      daemon=True,
  ).start()

  # Send a command as bytes (b'...' is Python's byte string syntax)
  # Don't forget the newline!
  sandbox.pty.send_stdin(terminal.pid, b'echo "Hello from PTY"\n')
  ```
</CodeGroup>

## De terminalgrootte wijzigen

Je kunt `resize()` gebruiken om de PTY te informeren wanneer de gebruiker de grootte van het terminalvenster wijzigt.
De waarden cols en rows vertegenwoordigen de terminalafmetingen in tekens in plaats van pixels.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => process.stdout.write(data),
  })

  // Resize to new dimensions (in characters)
  await sandbox.pty.resize(terminal.pid, {
    cols: 120,
    rows: 40,
  })
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(size=PtySize(rows=24, cols=80))

  # Resize to new dimensions (in characters)
  sandbox.pty.resize(terminal.pid, PtySize(rows=40, cols=120))
  ```
</CodeGroup>

## Verbinding verbreken en opnieuw verbinden

Een PTY-sessie kan actief blijven, zelfs nadat de client de verbinding heeft verbroken. Je kunt de sessie loskoppelen en er later opnieuw verbinding mee maken met een nieuwe data-handler.

Dit kan worden gebruikt om te herstellen van netwerkonderbrekingen, terminaltoegang vanaf meerdere clients te ondersteunen en sessiestatus te behouden tussen nieuwe verbindingen.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  // Create a PTY session
  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => console.log('Handler 1:', new TextDecoder().decode(data)),
  })

  const pid = terminal.pid

  // Send a command
  await sandbox.pty.sendInput(pid, new TextEncoder().encode('echo hello\n'))

  // Disconnect - PTY keeps running in the background
  await terminal.disconnect()

  // Later: reconnect with a new data handler
  const reconnected = await sandbox.pty.connect(pid, {
    onData: (data) => console.log('Handler 2:', new TextDecoder().decode(data)),
  })

  // Continue using the session
  await sandbox.pty.sendInput(pid, new TextEncoder().encode('echo world\n'))

  // Wait for the terminal to exit
  await reconnected.wait()
  ```

  ```python Python icon="python" theme={"system"}
  import threading
  import time

  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  # Create a PTY session
  terminal = sandbox.pty.create(size=PtySize(rows=24, cols=80))
  pid = terminal.pid

  # Send a command
  sandbox.pty.send_stdin(pid, b'echo hello\n')
  time.sleep(0.5)

  # Disconnect - PTY keeps running in the background.
  # Don't disconnect while a wait() is iterating the same handle.
  terminal.disconnect()

  # Later: reconnect with a new handle and stream its output
  reconnected = sandbox.pty.connect(pid)
  threading.Thread(
      target=lambda: reconnected.wait(on_pty=lambda data: print('Handler 2:', data.decode())),
      daemon=True,
  ).start()

  # Continue using the session
  sandbox.pty.send_stdin(pid, b'echo world\n')
  time.sleep(1.5)
  ```
</CodeGroup>

## De PTY beëindigen

Je kunt `kill()` gebruiken om de PTY-sessie te beëindigen.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => process.stdout.write(data),
  })

  // Kill the PTY
  const killed = await sandbox.pty.kill(terminal.pid)
  console.log('Killed:', killed)  // true if successful

  // Or use the handle method
  // await terminal.kill()
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(size=PtySize(rows=24, cols=80))

  # Kill the PTY
  killed = sandbox.pty.kill(terminal.pid)
  print('Killed:', killed)  # True if successful

  # Or use the handle method
  # terminal.kill()
  ```
</CodeGroup>

## Wachten tot PTY wordt afgesloten

Je kunt `wait()` gebruiken om te blokkeren totdat de terminalsessie eindigt, bijvoorbeeld wanneer de gebruiker `exit` typt.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create()

  const terminal = await sandbox.pty.create({
    cols: 80,
    rows: 24,
    onData: (data) => process.stdout.write(data),
  })

  // Send exit command
  await sandbox.pty.sendInput(terminal.pid, new TextEncoder().encode('exit\n'))

  // Wait for the terminal to exit
  const result = await terminal.wait()
  console.log('Exit code:', result.exitCode)
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.code_interpreter import Sandbox, PtySize

  sandbox = Sandbox.create()

  terminal = sandbox.pty.create(size=PtySize(rows=24, cols=80))

  # Send exit command
  sandbox.pty.send_stdin(terminal.pid, b'exit\n')

  # wait() blocks until the terminal exits; pass on_pty to stream output
  result = terminal.wait(on_pty=lambda data: print(data.decode(), end=''))
  print('Exit code:', result.exit_code)
  ```
</CodeGroup>

## Interactieve terminal (SSH-achtig)

Je kunt dezelfde `sandbox.pty` API gebruiken die hierboven is beschreven om een volledig interactieve terminal zoals SSH te maken door raw mode, stdin-forwarding en terminal resize events af te handelen.
