Prompt Detection Strategies

Overview

When executing commands on network devices via terminal (SSH/Telnet), RADKit needs to detect when a command has finished executing and the device is ready for the next input. This is achieved through prompt detection strategies.

A prompt detection strategy is an algorithm that determines when command execution is complete by monitoring the terminal output stream and identifying patterns, timeouts, or other indicators that signal readiness for new input.

RADKit provides five built-in strategies, each optimized for different scenarios and device behaviors:

  1. Test Probe (default) - Active marker injection with backoff algorithms

  2. Auto Prompt - Discovers prompt dynamically, then uses regex matching

  3. Regex - Pattern-based matching for known prompt formats

  4. Timeout - Simple wait-based detection for fixed-duration commands

  5. Idle Detection - Monitors stream inactivity to detect completion

Note

Prompt detection is automatically handled by RADKit during command execution via Device.exec(). Most users will not need to explicitly configure these strategies, as the default Test Probe strategy works reliably across most device types.

Available Strategies

Device-Type Aware Defaults

RADKit automatically selects a prompt detection strategy based on the device type. This infrastructure allows the system to optimize behavior for specific network operating systems and platforms when needed.

Current Defaults:

Most device types (IOS-XR, NX-OS, ASA, Linux, etc.) default to the Test Probe with Exponential Backoff strategy, which has proven reliable across all platforms.

IOS-XE exception: For IOS-XE devices, RADKit automatically switches to the Auto Prompt strategy when the command contains show platform integrity. This is because these commands abort their output if any keystroke (including a test probe) is received during execution.

Overriding Device-Type Defaults:

You can override the automatic default by explicitly specifying a prompt_detection_strategy parameter:

from radkit_client import RegexPromptDetectionStrategy

device = client.get_device("device-id")

# Uses device-type default (test-probe-exponential-backoff)
result = device.exec("show version")

# Explicitly override with regex strategy
result = device.exec(
    "show version",
    prompt_detection_strategy=RegexPromptDetectionStrategy(
        patterns=[r"[\w\-]+#\s*$"],
        max_timeout=15.0,
    ),
)

Test Probe Strategy (Default)

The test probe strategy is the default and most reliable method for prompt detection. It works by actively injecting marker strings into the terminal session and detecting when they appear in the output.

How it works:

  1. Clears the terminal screen (CTRL+L)

  2. Sends the user’s command

  3. Injects a unique marker string (e.g., $prompttest-1$)

  4. Monitors output until the marker appears on the current line

  5. Removes the marker using CTRL+U (line erase)

  6. Returns captured output

Variants:

  • test-probe-exponential-backoff: Increases wait time exponentially between detection attempts (default)

  • test-probe-linear-backoff: Increases wait time linearly

  • test-probe-constant-backoff: Uses fixed wait time between attempts

Configuration example:

from radkit_client import TestProbeExponentialBackoffPromptDetectionStrategy

strategy = TestProbeExponentialBackoffPromptDetectionStrategy(
    max_probes=50,  # Maximum marker injection attempts
    read_chunk_timeout=1.0,  # Timeout for each read attempt (seconds)
)

When to use: Default choice for most devices. Highly reliable but slightly intrusive due to marker injection.

Advantages:

  • Most reliable across different device types

  • Handles devices with unpredictable prompt formats

  • Automatically adapts timing with backoff algorithms

Disadvantages:

  • Injects test markers that briefly appear in terminal

  • Slightly more overhead than passive strategies

Auto Prompt Strategy

The auto prompt strategy first discovers the current prompt by sending an empty \r command using the test probe technique. Once the prompt is known, it switches to regex-based matching for the actual command, avoiding any further keystrokes during output collection.

This makes it the correct choice for commands that abort their output when a keystroke is received mid-stream (e.g., show platform integrity sign on IOS-XE).

How it works:

  1. Sends an empty \r using the test probe strategy to capture the current prompt

  2. Builds a set of regex patterns from the discovered prompt (also replacing the trailing >, $, or # to handle prompt changes)

  3. Sends the actual command

  4. Uses the regex strategy to detect completion by matching the known prompt

Configuration example:

from radkit_client import AutoPromptDetectionStrategy

strategy = AutoPromptDetectionStrategy(
    max_probes=50,         # Probes used for initial prompt discovery
    max_timeout=15.0,      # Max wait for regex match on actual command
    read_chunk_timeout=1.0,
)

When to use: For commands that abort their output when receiving any keystroke during execution, such as show platform integrity sign on IOS-XE. RADKit enables this strategy automatically for those commands.

Advantages:

  • Non-intrusive during actual command output collection

  • No prior knowledge of the prompt format required

  • Handles prompt changes (e.g., > to #) caused by the command

Disadvantages:

  • Slightly slower than pure regex (requires an extra round-trip to discover the prompt)

  • Falls back silently if prompt discovery fails


The regex strategy detects prompts by matching regular expression patterns against the terminal output stream.

How it works:

  1. Sends the user’s command

  2. Continuously reads output chunks

  3. Checks each chunk against configured regex pattern(s)

  4. Returns captured output when a match is found

  5. Falls back to timeout if no match occurs within max_timeout

Configuration example:

from radkit_client import RegexPromptDetectionStrategy

# Single pattern
strategy = RegexPromptDetectionStrategy(
    patterns=r"#\s*$",  # Match '#' followed by optional whitespace at line end
    max_timeout=15.0,
    match_mode="current-line",  # or "full-buffer"
)

# Multiple patterns (alternation)
strategy = RegexPromptDetectionStrategy(
    patterns=[
        r"#\s*$",      # Privileged mode prompt
        r">\s*$",      # User mode prompt
        r"\$\s*$",     # Shell prompt
    ],
    max_timeout=15.0,
    match_mode="current-line",
)

Match modes:

  • current-line: Match pattern only against the last line of output (faster, recommended)

  • full-buffer: Match pattern anywhere in the entire output buffer (slower, use for prompts appearing mid-output)

When to use: When device prompts follow consistent, predictable patterns. Ideal for homogeneous device environments.

Advantages:

  • Non-intrusive (passive detection)

  • Fast when patterns match quickly

  • No terminal manipulation required

Disadvantages:

  • Requires knowing device prompt patterns in advance

  • May fail on devices with dynamic/changing prompts

  • Can produce false positives if pattern matches command output

Timeout Strategy

The timeout strategy simply waits a fixed duration after sending the command, then returns all accumulated output.

How it works:

  1. Sends the user’s command

  2. Waits for wait_time seconds

  3. Optionally exhausts remaining stream data

  4. Returns all captured output

Configuration example:

from radkit_client import TimeoutPromptDetectionStrategy

strategy = TimeoutPromptDetectionStrategy(
    wait_time=5.0,  # Wait 5 seconds after sending command
    exhaust_stream=True,  # Read remaining data after wait_time (default: False)
    stream_exhausting_timeout=0.5,  # Timeout for draining remaining data
)

When to use: For devices without interactive prompts, or commands with known execution duration. Also useful for troubleshooting when other strategies fail.

Advantages:

  • Extremely simple and predictable

  • Works on any device type

  • Useful for commands with fixed execution time

Disadvantages:

  • Inefficient (waits full duration even if command finishes earlier)

  • May truncate slow command output if timeout is too short

  • No confirmation that command actually completed

Idle Detection Strategy

The idle detection strategy monitors the output stream for periods of inactivity, confirming the command is complete when no data arrives for multiple consecutive timeout periods.

How it works:

  1. Sends the user’s command

  2. Monitors stream for data arrival

  3. Counts consecutive idle_timeout periods with no data

  4. Returns captured output when confirmation_reads consecutive idle periods are detected

  5. Enforces max_total_time as an absolute timeout limit

Configuration example:

from radkit_client import IdleDetectionStrategy

strategy = IdleDetectionStrategy(
    idle_timeout=1.0,  # Timeout for each idle check (seconds)
    confirmation_reads=3,  # Number of consecutive idle periods to confirm
    max_total_time=60.0,  # Absolute maximum wait time (seconds)
)

When to use: For commands that produce intermittent output (e.g., ping, traceroute) or devices where prompt detection is unreliable.

Advantages:

  • Handles commands with slow/intermittent output

  • Adapts to actual command execution time

  • More robust than simple timeout

Disadvantages:

  • Slower than active detection strategies

  • May trigger prematurely if command has long pauses

  • Requires tuning parameters for optimal performance

Using Strategies with Device.exec()

Basic Usage

To use a specific strategy, pass it to the prompt_detection_strategy parameter of Device.exec():

>>> from radkit_client import RegexPromptDetectionStrategy

>>> response = device.exec(
...     "show version",
...     prompt_detection_strategy=RegexPromptDetectionStrategy(
...         patterns=r"router1#\s*$",
...         max_timeout=15.0,
...     ),
... )
>>> response.wait()
>>> print(response.data)

It is also possible to specify a strategy per individual command, when multiple commands are passed to Device.exec(), by passing Command objects instead of strings:

>>> from radkit_client import AutoPromptDetectionStrategy, RegexPromptDetectionStrategy
>>> from radkit_client.sync import Command
>>> response = device.exec(
...     [
...         Command(
...             "show version",
...             # Override prompt detection strategy for this command.
...             prompt_detection_strategy=AutoPromptDetectionStrategy(),
...         ),
...         Command(
...             "show clock"
...         ),
...     ],
...     # Default strategy for commands that don't specify a strategy. If
...     # not passed at all, the service will choose the default.
...     prompt_detection_strategy=RegexPromptDetectionStrategy(
...         patterns=r"router1#\s*$",
...     ),
... )

Forward and Backward Compatibility

Warning

The direct-model style shown above is the recommended approach. This class is made for power-users; it is only recommended as a workaround, in conjunction with expert advice from Cisco.

If you have existing code using the GenericPromptDetectionStrategy wrapper, or need to use a strategy name/options not yet modelled by the current client version, the wrapper is still supported.

The name field accepts both PromptDetectionStrategyName enum values and plain strings, and options accepts both Pydantic model instances and plain dictionaries. This means you can use strategies that a newer RADKit Service supports even if your client version doesn’t have the corresponding enum or model yet:

from radkit_client import GenericPromptDetectionStrategy

# Existing code using the wrapper still works unchanged
strategy = GenericPromptDetectionStrategy(
    name="regex-prompt",
    options={
        "patterns": r"#\s*$",
    },
)

# Also useful for strategies added in a newer Service version that the
# current client does not yet model
strategy = GenericPromptDetectionStrategy(
    name="some-future-strategy",
    options={
        "some_param": 42,
    },
)

Note

Strategy resolution happens on the service side. The client serializes the strategy name and options and sends them over the wire, which allows older clients to use new strategies added in newer service versions.

Performance Considerations

Strategy Performance Comparison

Strategy

Speed

Reliability

Device Support

Best Use Case

Test Probe (default)

Medium

Very High

Universal

General purpose, heterogeneous environments

Auto Prompt

Medium

High

Universal

Commands that abort on keystrokes (e.g., show platform integrity on IOS-XE)

Regex

Fast

Medium

Universal

Homogeneous environments with known prompts

Timeout

Slow

Medium

Universal

Fixed-duration commands, troubleshooting

Idle Detection

Medium-Slow

Medium

Universal

Commands with intermittent output

Optimization Tips

  1. Use regex strategy for performance-critical scenarios when prompt patterns are well-known and consistent.

  2. Tune backoff parameters for test probe strategy based on device response times:

    • Fast devices: Use smaller initial/max intervals

    • Slow devices: Increase max_probes and timeouts

  3. Adjust timeout values based on command characteristics:

    • Quick commands (show, status): 5-10 seconds

    • Configuration commands: 15-30 seconds

    • Long-running commands (backup, copy): 60+ seconds

  4. Use idle detection for commands with variable execution time (e.g., pings with dynamic counts).

Best Practices

Strategy Selection Guidelines

  1. Start with the default (test probe with exponential backoff) - it works reliably for most devices.

  2. Switch to auto prompt if:

    • The command aborts its output when any keystroke is received (e.g., show platform integrity sign on IOS-XE)

    • RADKit enables this automatically for known affected commands

  3. Switch to regex if:

    • Performance is critical

    • You manage many devices of the same type with consistent prompts

    • You can invest time in prompt pattern development/testing

  4. Use timeout only when:

    • Other strategies consistently fail

    • Devices lack interactive prompts

    • Commands have known, fixed execution time

  5. Consider idle detection for:

    • Commands with intermittent output patterns

    • Devices where prompt detection is unreliable

    • Network latency introduces variable delays

Troubleshooting

Common Issues

Command output truncated

  • Cause: Timeout too short for command execution

  • Solution: Increase max_timeout or wait_time depending on strategy

Command never completes / hangs

  • Cause: Prompt detection pattern doesn’t match device prompt

  • Solution:

    • Verify actual device prompt format

    • Use more flexible regex patterns (e.g., .*#\s*$ instead of hostname#$)

    • Switch to test probe strategy for reliability

Spurious markers in output (test probe)

  • Cause: Device doesn’t properly handle CTRL+U (line erase)

  • Solution: Switch to regex or idle detection strategy

Regex matches command output instead of prompt

  • Cause: Pattern too broad, matches unintended text

  • Solution:

    • Use more specific patterns (e.g., add $ anchor for end-of-line)

    • Switch match_mode to "current-line"

    • Use test probe strategy instead