The agent has access to the full conversation history when answering questions:
# Agent can reference what it has done so farresponse = conversation.ask_agent( "Summarize the activity so far in 1 sentence.")print(f"Response: {response}")
Questions don’t interrupt the main conversation flow - they’re processed separately:
# Start main conversationthread = threading.Thread(target=conversation.run)thread.start()# Ask questions without affecting main executionresponse = conversation.ask_agent("How's the progress?")
You can ask questions while the agent is running or after it has completed:
# During executiontime.sleep(2) # Let agent start workingresponse1 = conversation.ask_agent("Have you finished running?")# After completionthread.join()response2 = conversation.ask_agent("What did you accomplish?")
Example demonstrating the ask_agent functionality for getting sidebar replies
from the agent for a running conversation.This example shows how to use ask_agent() to get quick responses from the agent
about the current conversation state without interrupting the main execution flow.
"""Example demonstrating the ask_agent functionality for getting sidebar repliesfrom the agent for a running conversation.This example shows how to use ask_agent() to get quick responses from the agentabout the current conversation state without interrupting the main execution flow."""import osimport threadingimport timefrom datetime import datetimefrom pydantic import SecretStrfrom openhands.sdk import ( LLM, Agent, Conversation,)from openhands.sdk.conversation import ConversationVisualizerBasefrom openhands.sdk.event import Eventfrom openhands.sdk.tool import Toolfrom openhands.tools.file_editor import FileEditorToolfrom openhands.tools.task_tracker import TaskTrackerToolfrom openhands.tools.terminal import TerminalTool# Configure LLMapi_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),)# Toolscwd = os.getcwd()tools = [ Tool(name=TerminalTool.name), Tool(name=FileEditorTool.name), Tool(name=TaskTrackerTool.name),]class MinimalVisualizer(ConversationVisualizerBase): """A minimal visualizer that print the raw events as they occur.""" count = 0 def on_event(self, event: Event) -> None: """Handle events for minimal progress visualization.""" print(f"\n\n[EVENT {self.count}] {type(event).__name__}") self.count += 1# Agentagent = Agent(llm=llm, tools=tools)conversation = Conversation( agent=agent, workspace=cwd, visualizer=MinimalVisualizer, max_iteration_per_run=5)def timestamp() -> str: return datetime.now().strftime("%H:%M:%S")print("=== Ask Agent Example ===")print("This example demonstrates asking questions during conversation execution")# Step 1: Build conversation contextprint(f"\n[{timestamp()}] Building conversation context...")conversation.send_message("Explore the current directory and describe the architecture")# Step 2: Start conversation in background threadprint(f"[{timestamp()}] Starting conversation in background thread...")thread = threading.Thread(target=conversation.run)thread.start()# Give the agent time to start processingtime.sleep(2)# Step 3: Use ask_agent while conversation is runningprint(f"\n[{timestamp()}] Using ask_agent while conversation is processing...")# Ask context-aware questionsquestions_and_responses = []question_1 = "Summarize the activity so far in 1 sentence."print(f"\n[{timestamp()}] Asking: {question_1}")response1 = conversation.ask_agent(question_1)questions_and_responses.append((question_1, response1))print(f"Response: {response1}")time.sleep(1)question_2 = "How's the progress?"print(f"\n[{timestamp()}] Asking: {question_2}")response2 = conversation.ask_agent(question_2)questions_and_responses.append((question_2, response2))print(f"Response: {response2}")time.sleep(1)question_3 = "Have you finished running?"print(f"\n[{timestamp()}] {question_3}")response3 = conversation.ask_agent(question_3)questions_and_responses.append((question_3, response3))print(f"Response: {response3}")# Step 4: Wait for conversation to completeprint(f"\n[{timestamp()}] Waiting for conversation to complete...")thread.join()# Step 5: Verify conversation state wasn't affectedfinal_event_count = len(conversation.state.events)# Step 6: Ask a final question after conversation completionprint(f"\n[{timestamp()}] Asking final question after completion...")final_response = conversation.ask_agent( "Can you summarize what you accomplished in this conversation?")print(f"Final response: {final_response}")# Step 7: Summaryprint("\n" + "=" * 60)print("SUMMARY OF ASK_AGENT DEMONSTRATION")print("=" * 60)print("\nQuestions and Responses:")for i, (question, response) in enumerate(questions_and_responses, 1): print(f"\n{i}. Q: {question}") print(f" A: {response[:100]}{'...' if len(response) > 100 else ''}")final_truncated = final_response[:100] + ("..." if len(final_response) > 100 else "")print(f"\nFinal Question Response: {final_truncated}")# Report costcost = llm.metrics.accumulated_costprint(f"EXAMPLE_COST: {cost:.4f}")
You can run the example code as-is.
The model name should follow the LiteLLM convention: provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.
ChatGPT Plus/Pro subscribers: You can use LLM.subscription_login() to authenticate with your ChatGPT account and access Codex models without consuming API credits. See the LLM Subscriptions guide for details.