Use this file to discover all available pages before exploring further.
What this builds. A session that receives three messages in quick succession, then iterates events for all resulting turns.
You’ll end up with. Interleaved TOOL_CALL / TOOL_RESULT lines and streamed text covering every turn — the listener stays open instead of breaking on the first is_complete.Demonstrates creating a conversational session, sending multiple messages
back-to-back, and streaming the response token by token using listen() with
event filtering.
import asynciofrom vectorshift.agent import Agent, AgentType, LlmInfo, MemoryConfigfrom vectorshift.agent.tools import ExaAiTool, GoogleSearchToolfrom vectorshift.events import SessionEventTypefrom vectorshift import ToolInput, ToolInputTypeasync def main() -> None: search = ExaAiTool( tool_name="exa_ai_search", query=ToolInput(type=ToolInputType.DYNAMIC, description="Search query"), ) # Create (or fetch) a conversational agent agent = Agent.new( name="Quantum tutor", type=AgentType.CONVERSATIONAL, llm_info=LlmInfo(provider="openai", model_id="gpt-5.1"), tools=[search], instructions="You answer clearly for beginners.", memory_config=MemoryConfig(enable_session_memory=True), ) # agent.save() print(f"Created agent: {agent.name} with tools: {agent.id}") # Open a session, send one message, stream the response async with await agent.create_session() as session: print(f"Session connected: {session.session_id}") await session.send( "What is quantum computing? Explain for a beginner. search for the latest news on quantum computing and give me that too using google search." ) await session.send("Tell me a joke about it?") await session.send("actially dont tell me a joke about it just make a haiku?") async for event in session.listen( event_types=[ SessionEventType.MESSAGE_DELTA, SessionEventType.MESSAGE_COMPLETE, SessionEventType.TOOL_CALL, SessionEventType.TOOL_RESULT, ] ): match event.type: case SessionEventType.TOOL_CALL: print( f"[Tool Call] {event.tool_name} - {event.data.get('status', '')}" ) print(f"[Tool Call Data] {event.data}") case SessionEventType.TOOL_RESULT: print(f"[Tool Result] {event.data.get('result', '')}") case _: pass if event.delta: print(event.delta, end="", flush=True) # if event.is_complete: # break # Clean up agent.delete() print("\nDone.")if __name__ == "__main__": asyncio.run(main())
Created agent: Quantum tutor with tools: ...Session connected: ...[Tool Call] exa_ai_search - in_progress[Tool Result] ...Quantum computing is...Here's a joke...Qubits dance unseen / ...Done.
The if event.is_complete: break line is commented out on purpose — that’s what lets the listener keep flowing through all three turns instead of stopping after the first.
See Session overview for the full event taxonomy and streaming semantics.