Skip to main content

Interactive terminal

A ready-to-run example is available here.

The BashTool provides agents with the ability to interact with terminal applications that require back-and-forth communication, such as Python's interactive mode, ipython, database CLIs, and other REPL environments. This enables agents to execute commands within these interactive sessions, receive output, and send follow-up commands based on the results.

How it works

cwd = os.getcwd()
register_tool("BashTool", BashTool)
tools = [
Tool(
name="BashTool",
params={"no_change_timeout_seconds": 3},
)
]

The BashTool is configured with a no_change_timeout_seconds parameter that determines how long to wait for terminal updates before sending the output back to the agent.

In the example above, the agent should:

  1. Enters Python's interactive mode by running python3
  2. Executes Python code to get the current time
  3. Exits the Python interpreter

The BashTool maintains the session state throughout these interactions, allowing the agent to send multiple commands within the same terminal session. Review the BashTool and terminal source code to better understand how the interactive session is configured and managed.

Ready-to-run example

import os

from pydantic import SecretStr

from faheemcode.sdk import (
LLM,
Agent,
Conversation,
Event,
LLMConvertibleEvent,
get_logger,
)
from faheemcode.sdk.tool import Tool
from faheemcode.tools.terminal import TerminalTool

logger = get_logger(__name__)

# Configure LLM
api_key = os.getenv("LLM_API_KEY")
assert api_key is not None, "LLM_API_KEY environment variable is not set."
model = os.getenv("LLM_MODEL", "anthropic/claude-sonnet-4-5-20250929")
base_url = os.getenv("LLM_BASE_URL")
llm = LLM(
usage_id="agent",
model=model,
base_url=base_url,
api_key=SecretStr(api_key),
)

# Tools
cwd = os.getcwd()
tools = [
Tool(
name=TerminalTool.name,
params={"no_change_timeout_seconds": 3},
)
]

# Agent
agent = Agent(llm=llm, tools=tools)

llm_messages = [] # collect raw LLM messages

def conversation_callback(event: Event):
if isinstance(event, LLMConvertibleEvent):
llm_messages.append(event.to_llm_message())

conversation = Conversation(
agent=agent, callbacks=[conversation_callback], workspace=cwd
)

conversation.send_message(
"Enter python interactive mode by directly running `python3`, then tell me "
"the current time, and exit python interactive mode."
)
conversation.run()

print("=" * 100)
print("Conversation finished. Got the following LLM messages:")
for i, message in enumerate(llm_messages):
print(f"Message {i}: {str(message)[:200]}")

You can run the example code as-is.

Bring your own provider key
export LLM_API_KEY="your-api-key"
export LLM_MODEL="anthropic/claude-sonnet-4-5-20250929" # or openai/gpt-4o, etc.
cd software-agent-sdk
uv run python examples/01_standalone_sdk/06_interactive_terminal_w_reasoning.py
Faheem Code Cloud key
# https://app.faheemcode.ai/settings/api-keys
export LLM_API_KEY="example-user-api-key"
export LLM_MODEL="faheemcode/claude-sonnet-4-5-20250929"
cd software-agent-sdk
uv run python examples/01_standalone_sdk/06_interactive_terminal_w_reasoning.py

Next steps

  • Custom Tools - Create your own tools for specific use cases