> ## 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.

# Interaktives 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/de/guides/sandbox-your-first-agent-sandbox#configure-environment-variables">Configure Environment Variables</a>.</Note>;
  }
};

Das PTY- oder Pseudo-Terminal-Modul ermöglicht interaktive Terminalsitzungen innerhalb der Sandbox mit bidirektionaler Kommunikation in Echtzeit.

Eine PTY-Sitzung unterstützt **Echtzeit-Streaming**, wodurch Terminalausgaben kontinuierlich über Callbacks bereitgestellt werden, sobald sie erzeugt werden, und bietet **bidirektionale Eingabe**, sodass Daten gesendet werden können, während die Sitzung noch läuft. Außerdem bietet sie ein **interaktives Shell**-Erlebnis mit vollständigem Terminalverhalten, einschließlich ANSI-Farben und Escape-Sequenzen, und unterstützt **Sitzungspersistenz**, sodass eine laufende Sitzung getrennt und später erneut verbunden werden kann.

<SandboxConfigHint />

## PTY-Sitzung erstellen

Sie können `sandbox.pty.create()` verwenden, um eine interaktive Bash-Shell zu 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>
  Das PTY startet eine interaktive Bash-Shell mit `TERM=xterm-256color`, sodass ANSI-Farben und Escape-Sequenzen wie erwartet funktionieren.
</Note>

## Zeitüberschreitung

Die Timeout-Einstellung ist konfigurierbar und bestimmt, wie lange die PTY-Sitzung aktiv bleibt. Sie können eine PTY-Sitzung unbegrenzt offen halten, indem Sie in JavaScript `timeoutMs: 0` oder in Python `timeout=0` festlegen. Standardmäßig verwendet die Sitzung ein Timeout von 60 Sekunden.

<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>

## Eingabe an PTY senden

Sie können in JavaScript `sendInput()` oder in Python `send_stdin()` verwenden, um Daten an das Terminal zu senden.

In JavaScript gibt `sendInput()` ein Promise zurück, und jede Terminalausgabe wird über den `onData`-Callback bereitgestellt, anstatt direkt zurückgegeben zu werden.
In Python wird `send_stdin()` synchron abgeschlossen, und jede Terminalausgabe wird über den `on_pty`-Callback bereitgestellt, der an `wait()` übergeben wurde.

<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>

## Terminalgröße ändern

Sie können `resize()` verwenden, um das PTY zu benachrichtigen, wenn der Benutzer die Größe des Terminalfensters ändert.
Die cols- und rows-Werte repräsentieren die Terminalabmessungen in Zeichen statt in Pixeln.

<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>

## Trennen und erneut verbinden

Eine PTY-Sitzung kann auch dann aktiv bleiben, wenn der Client die Verbindung trennt. Sie können sich von der Sitzung trennen und später mit einem neuen Datenhandler erneut verbinden.

Dies kann verwendet werden, um sich von Netzwerkunterbrechungen zu erholen, Terminalzugriff von mehreren Clients zu unterstützen und den Sitzungszustand über erneute Verbindungen hinweg zu erhalten.

<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>

## PTY beenden

Sie können `kill()` verwenden, um die PTY-Sitzung zu beenden.

<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>

## Auf das Beenden des PTY warten

Sie können `wait()` verwenden, um zu blockieren, bis die Terminalsitzung endet, zum Beispiel wenn der Benutzer `exit` eingibt.

<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>

## Interaktives Terminal (SSH-ähnlich)

Sie können dieselbe oben beschriebene `sandbox.pty`-API verwenden, um ein vollständig interaktives Terminal wie SSH zu erstellen, indem Sie Raw Mode, stdin-Weiterleitung und Ereignisse zur Änderung der Terminalgröße behandeln.
