import byzerllm


@byzerllm.prompt()
def _interactive_session() -> str:
    """
    # Interactive Session Guide: Managing Interactive Command-Line Tools

    ## What are Interactive Sessions?

    Interactive sessions allow you to work with command-line tools that maintain state and require real-time input/output, such as:
    - Python REPL (`python -i`)
    - Database CLIs (`mysql`, `psql`, `sqlite3`, `redis-cli`)
    - Node.js REPL (`node`)
    - Interactive shells and debugging tools (`gdb`, `pdb`)
    - Package managers with interactive prompts
    - Any command that expects ongoing user interaction

    Unlike `execute_command` which runs a single command and returns the output, interactive sessions persist across multiple interactions, maintaining state (variables, connections, imports, etc.) between commands.

    ## Three-Tool Workflow

    Interactive sessions use three tools that work together:

    | Tool | Purpose | When to Use |
    |------|---------|-------------|
    | `session_start` | Create a new interactive session | When you need to launch an interactive CLI tool |
    | `session_interactive` | Send input and read output | Each time you need to run a command in the session |
    | `session_stop` | Terminate the session | When you're done with the interactive tool |

    ### Step 1: Start a Session (`session_start`)

    ```xml
    <session_start>
    <command>python -i</command>
    <timeout>300</timeout>
    <cwd>./my_project</cwd>
    </session_start>
    ```

    **Parameters:**

    | Parameter | Required | Default | Description |
    |-----------|----------|---------|-------------|
    | `command` | Yes | - | The interactive command to launch |
    | `timeout` | No | 300 | Session timeout in seconds |
    | `cwd` | No | project root | Working directory for the session |
    | `env` | No | - | Environment variables as JSON object |

    **What happens:**
    - The tool starts the interactive process
    - Waits ~10 seconds for initial output (startup banners, prompts, etc.)
    - Returns a `session_id` you'll use for subsequent interactions
    - The initial output often contains a prompt hint (e.g., `>>>` for Python)

    **Key tip:** Pay attention to the prompt hint in the response! It tells you what `prompt_regex` to use in `session_interactive`.

    ### Step 2: Interact with the Session (`session_interactive`)

    ```xml
    <session_interactive>
    <session_id>abc123</session_id>
    <input>print("Hello World")\n</input>
    <read_timeout>5</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>>>> ?$</prompt_regex>
    </session_interactive>
    ```

    **Parameters:**

    | Parameter | Required | Default | Description |
    |-----------|----------|---------|-------------|
    | `session_id` | Yes | - | Session ID from `session_start` |
    | `input` | Yes | - | Input to send (usually ending with `\\n`) |
    | `read_timeout` | No | 2 | Seconds to wait for output |
    | `max_bytes` | No | 4096 | Maximum bytes to read |
    | `expect_prompt` | No | false | Whether to wait for a prompt pattern |
    | `prompt_regex` | No | - | Regex to match the prompt |

    **Critical rules for `input`:**
    - Always end input with `\\n` (newline) to simulate pressing Enter
    - For multi-line input, use `\\n` between lines: `line1\\nline2\\n`
    - For special keys, consult the specific tool's documentation

    **Understanding `expect_prompt` and `prompt_regex`:**

    When `expect_prompt` is `true`, the tool waits until it sees the prompt pattern (matched by `prompt_regex`) in the output before returning. This is the most reliable way to ensure you get complete output.

    Common prompt patterns:

    | Tool | prompt_regex | Example Prompt |
    |------|-------------|----------------|
    | Python | `>>> ?$` | `>>> ` |
    | Node.js | `> ?$` | `> ` |
    | MySQL | `mysql> ?$` | `mysql> ` |
    | PostgreSQL | `\\w+[=#]> ?$` | `mydb=> ` |
    | SQLite | `sqlite> ?$` | `sqlite> ` |
    | Redis | `127\\.0\\.0\\.1:\\d+> ?$` | `127.0.0.1:6379> ` |
    | Bash/Shell | `\\$ ?$` | `$ ` |
    | GDB | `\\(gdb\\) ?$` | `(gdb) ` |

    ### Step 3: Stop the Session (`session_stop`)

    ```xml
    <session_stop>
    <session_id>abc123</session_id>
    <force>false</force>
    </session_stop>
    ```

    **Parameters:**

    | Parameter | Required | Default | Description |
    |-----------|----------|---------|-------------|
    | `session_id` | Yes | - | Session ID to terminate |
    | `force` | No | false | `true` for force kill, `false` for graceful termination |

    **When to use `force`:**
    - When the session is not responding to graceful termination
    - When the process is stuck or hung
    - Normally, `false` is sufficient

    ## When to Use Interactive Sessions vs execute_command

    | Scenario | Use `execute_command` | Use Interactive Session |
    |----------|----------------------|------------------------|
    | Run a script: `python script.py` | ✅ | ❌ |
    | Python REPL: `python -i` | ❌ | ✅ |
    | Install packages: `pip install X` | ✅ | ❌ |
    | Database queries via CLI | ❌ | ✅ |
    | `git` commands | ✅ | ❌ |
    | Debug with `pdb`/`gdb` | ❌ | ✅ |
    | Interactive setup wizards | ❌ | ✅ |
    | Commands with `input()` calls | ❌ | ✅ |

    **Rule of thumb:** If the command exits after completion, use `execute_command`. If it stays open waiting for more input, use interactive sessions.

    ## Complete Examples

    ### Example 1: Python REPL for Testing

    ```
    # Step 1: Start Python interactive session
    <session_start>
    <command>python -i</command>
    <timeout>300</timeout>
    </session_start>

    # Step 2: Import and test
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>from mymodule import MyClass\n</input>
    <read_timeout>5</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>>>> ?$</prompt_regex>
    </session_interactive>

    # Step 3: Create instance and test
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>obj = MyClass()\nprint(obj.method())\n</input>
    <read_timeout>5</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>>>> ?$</prompt_regex>
    </session_interactive>

    # Step 4: Clean up
    <session_stop>
    <session_id>SESSION_ID</session_id>
    <force>false</force>
    </session_stop>
    ```

    ### Example 2: Database CLI

    ```
    # Step 1: Connect to database
    <session_start>
    <command>mysql -u root -p mydb</command>
    <timeout>600</timeout>
    </session_start>

    # Step 2: Run a query
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>SELECT * FROM users LIMIT 5;\n</input>
    <read_timeout>10</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>mysql> ?$</prompt_regex>
    </session_interactive>

    # Step 3: Run another query
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>DESCRIBE users;\n</input>
    <read_timeout>5</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>mysql> ?$</prompt_regex>
    </session_interactive>

    # Step 4: Disconnect
    <session_stop>
    <session_id>SESSION_ID</session_id>
    <force>false</force>
    </session_stop>
    ```

    ### Example 3: Interactive Debugging with pdb

    ```
    # Step 1: Start debugging
    <session_start>
    <command>python -m pdb script.py</command>
    <timeout>600</timeout>
    </session_start>

    # Step 2: Set a breakpoint
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>b 42\n</input>
    <read_timeout>3</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>\\(Pdb\\) ?$</prompt_regex>
    </session_interactive>

    # Step 3: Continue execution
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>c\n</input>
    <read_timeout>10</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>\\(Pdb\\) ?$</prompt_regex>
    </session_interactive>

    # Step 4: Inspect variables
    <session_interactive>
    <session_id>SESSION_ID</session_id>
    <input>p local_var\n</input>
    <read_timeout>3</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>\\(Pdb\\) ?$</prompt_regex>
    </session_interactive>

    # Step 5: Stop debugging
    <session_stop>
    <session_id>SESSION_ID</session_id>
    <force>false</force>
    </session_stop>
    ```

    ## Best Practices

    ### 1. Always Use expect_prompt When Possible

    ❌ Bad approach (unreliable timing):
    ```xml
    <session_interactive>
    <session_id>abc123</session_id>
    <input>SELECT * FROM large_table;\n</input>
    <read_timeout>2</read_timeout>
    </session_interactive>
    ```

    ✅ Good approach (waits for prompt):
    ```xml
    <session_interactive>
    <session_id>abc123</session_id>
    <input>SELECT * FROM large_table;\n</input>
    <read_timeout>30</read_timeout>
    <expect_prompt>true</expect_prompt>
    <prompt_regex>mysql> ?$</prompt_regex>
    </session_interactive>
    ```

    ### 2. Set Appropriate Timeouts

    | Command Type | Recommended read_timeout |
    |-------------|-------------------------|
    | Simple REPL commands | 2-5 seconds |
    | Database queries | 10-30 seconds |
    | Long-running computations | 30-120 seconds |
    | File I/O operations | 5-15 seconds |

    ### 3. Handle Errors Gracefully

    If a session becomes unresponsive:
    1. Try sending a simple command (e.g., `\\n`) with a short timeout
    2. If no response, use `session_stop` with `force=true`
    3. Start a new session if needed

    ### 4. Clean Up Sessions

    Always stop sessions when done to free resources. Don't leave sessions running indefinitely.

    ### 5. One Command at a Time

    Send one logical command per `session_interactive` call and wait for the response before sending the next. This ensures you can handle errors and unexpected output properly.

    ## Troubleshooting

    | Problem | Solution |
    |---------|----------|
    | No initial output after session_start | Try sending `\\n` via session_interactive to trigger the prompt |
    | Output is truncated | Increase `read_timeout` or `max_bytes` |
    | Session hangs | Use `session_stop` with `force=true`, then restart |
    | Wrong prompt_regex | Check the actual prompt from session_start output and adjust |
    | Command not executed | Ensure input ends with `\\n` |

    ## Guidelines

    1. **Use interactive sessions only for truly interactive tools** - Don't use them for one-shot commands
    2. **Always capture the session_id** - You need it for every subsequent interaction
    3. **Set prompt_regex from initial output** - The session_start response hints at the prompt pattern
    4. **End input with \\n** - This simulates pressing Enter
    5. **Clean up with session_stop** - Always terminate sessions when done
    6. **Use appropriate timeouts** - Too short may miss output; too long wastes time
    """
