Skip to Content

Streaming vs Single Mode

The isA Agent SDK supports both streaming and single-response modes for different use cases.

Streaming Mode

Streaming mode provides real-time updates as the agent processes your request. Use this for:

  • Interactive UIs with live feedback
  • Long-running tasks with progress updates
  • Tool execution visibility
  • Human-in-the-loop interactions

Basic Streaming

from isa_agent_sdk import query async for msg in query("Analyze this codebase and suggest improvements"): if msg.is_text: # Stream text tokens as they arrive print(msg.content, end="", flush=True) elif msg.is_thinking: # Agent's reasoning process print(f"\n[Thinking: {msg.content}]") elif msg.is_tool_use: # Tool being called print(f"\n[Calling: {msg.tool_name}({msg.tool_args})]") elif msg.is_tool_result: # Tool result received print(f"\n[Result: {msg.tool_result_value}]") elif msg.is_complete: # Final response print(f"\n\n=== Complete ===")

Message Types

TypePropertyDescription
textmsg.is_textStreaming text content
thinkingmsg.is_thinkingAgent reasoning
tool_usemsg.is_tool_useTool invocation
tool_resultmsg.is_tool_resultTool response
resultmsg.is_completeFinal complete response
errormsg.is_errorError occurred
checkpointmsg.is_checkpointHIL checkpoint
progressmsg.type == "progress"Progress update
session_startmsg.type == "session_start"Session began
session_endmsg.type == "session_end"Session ended

Progress Tracking

async for msg in query("Process all files in /src"): if msg.type == "progress": print(f"Progress: {msg.progress_percent:.1f}% - {msg.progress_step}") elif msg.is_text: print(msg.content, end="")

Single Mode (Non-Streaming)

Single mode waits for the complete response. Use this for:

  • Simple Q&A interactions
  • Backend processing
  • When streaming isn’t needed

Using ask()

from isa_agent_sdk import ask # Returns the final text response directly answer = await ask("What is the capital of Japan?") print(answer) # "Tokyo"

Sync Version

from isa_agent_sdk import ask_sync answer = ask_sync("Explain recursion in one sentence") print(answer)

Collecting Full Response from Stream

from isa_agent_sdk import query parts = [] async for msg in query("Write a haiku about coding"): if msg.is_text or msg.is_complete: parts.append(msg.content or "") full_response = "".join(parts) print(full_response)

Handling Different Event Types

Complete Event Handler

from isa_agent_sdk import query, AgentMessage async def handle_message(msg: AgentMessage): match msg.type: case "text": return {"action": "append", "content": msg.content} case "thinking": return {"action": "thinking", "content": msg.content} case "tool_use": return { "action": "tool_start", "tool": msg.tool_name, "args": msg.tool_args } case "tool_result": return { "action": "tool_end", "tool": msg.tool_name, "result": msg.tool_result_value, "error": msg.tool_error } case "checkpoint" | "hil_request": return { "action": "pause", "question": msg.metadata.get("question"), "options": msg.metadata.get("options") } case "error": return {"action": "error", "message": msg.content} case "result": return {"action": "complete", "content": msg.content} case _: return {"action": "ignore"} async for msg in query("Help me refactor this code"): result = await handle_message(msg) print(result)

Tool Execution Visibility

from isa_agent_sdk import query tools_used = [] async for msg in query("Search for Python tutorials and summarize"): if msg.is_tool_use: print(f"Starting: {msg.tool_name}") tools_used.append({ "name": msg.tool_name, "args": msg.tool_args, "id": msg.metadata.get("tool_use_id") }) elif msg.is_tool_result: print(f"Completed: {msg.tool_name}") # Find matching tool and add result for tool in tools_used: if tool["id"] == msg.metadata.get("tool_use_id"): tool["result"] = msg.tool_result_value tool["error"] = msg.tool_error elif msg.is_text: print(msg.content, end="") print(f"\n\nTools used: {len(tools_used)}") for tool in tools_used: print(f" - {tool['name']}: {'success' if not tool.get('error') else 'failed'}")

Server-Sent Events (SSE) for Web

FastAPI SSE Endpoint

from fastapi import FastAPI from fastapi.responses import StreamingResponse from isa_agent_sdk import query import json app = FastAPI() @app.post("/chat/stream") async def stream_chat(prompt: str): async def generate(): async for msg in query(prompt): data = { "type": msg.type, "content": msg.content, "metadata": msg.metadata } yield f"data: {json.dumps(data)}\n\n" return StreamingResponse( generate(), media_type="text/event-stream" )

JavaScript Client

const eventSource = new EventSource('/chat/stream?prompt=Hello'); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'text': appendToChat(data.content); break; case 'tool_use': showToolIndicator(data.metadata.tool_name); break; case 'result': completeMessage(); eventSource.close(); break; case 'error': showError(data.content); eventSource.close(); break; } };

Choosing Between Modes

Use CaseRecommended ModeFunction
Chat UI with live typingStreamingquery()
Simple Q&A botSingleask()
Background processingSingleask_sync()
Progress indicatorsStreamingquery()
Tool execution feedbackStreamingquery()
HIL approval workflowsStreamingquery()
API endpointEitherDepends on client

Next Steps