Skip to content

Other Frameworks

SideSeat works with any framework that emits OpenTelemetry traces. This page covers frameworks without dedicated integration pages.

Terminal window
pip install langchain langchain-openai "sideseat[langchain]"
from sideseat import SideSeat, Frameworks
from langchain_openai import ChatOpenAI
SideSeat(framework=Frameworks.LangChain)
llm = ChatOpenAI(model="gpt-5-mini")
response = llm.invoke("Hello!")
print(response.content)
Terminal window
pip install pydantic-ai "sideseat[pydantic-ai]"
from sideseat import SideSeat, Frameworks
from pydantic_ai import Agent
SideSeat(framework=Frameworks.PydanticAI)
agent = Agent('openai:gpt-5-mini')
result = agent.run_sync('What is the capital of France?')
print(result.output)

LlamaIndex does not emit OpenTelemetry itself — it has its own instrumentation dispatcher and no opentelemetry dependency. Bridging it needs the OpenInference instrumentor, which SideSeat does not bundle as an extra, so install it alongside:

Terminal window
pip install llama-index sideseat openinference-instrumentation-llama-index
from sideseat import SideSeat
from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
# auto_instrument=False: without a LlamaIndex branch the SDK would otherwise instrument
# whichever framework it happens to auto-detect from your installed packages.
client = SideSeat(auto_instrument=False)
LlamaIndexInstrumentor().instrument(tracer_provider=client.telemetry.tracer_provider)
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("What is this about?")
print(response)

There is no Frameworks.LlamaIndex constant. Passing framework="llama-index" would not do what it looks like: an unrecognised value is recorded as a provider, and framework still falls back to auto-detection. Hence auto_instrument=False above.

The server has a LlamaIndex rule (llama_index.* attributes) checked before the broader OpenInference one, so spans carrying those attributes are classified LlamaIndex and the rest as OpenInference — which of the two you get depends on what the instrumentor version you install emits. There is no captured fixture for LlamaIndex, so this is read from the classifier rather than measured; the support matrix in server/tests/fixtures/messages/README.md is the exact boundary of what the goldens verify.

Terminal window
pip install autogen-agentchat "autogen-ext[openai]" "sideseat[autogen]"
import asyncio
from sideseat import SideSeat, Frameworks
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
SideSeat(framework=Frameworks.AutoGen)
async def main():
model_client = OpenAIChatCompletionClient(model="gpt-5-mini", api_key="sk-xxx")
assistant = AssistantAgent("assistant", model_client=model_client)
result = await assistant.run(task="Hello!")
print(result.messages[-1].content)
asyncio.run(main())
Terminal window
pip install agno openai "sideseat[agno]"
from sideseat import SideSeat, Frameworks
from agno.agent import Agent
from agno.models.openai import OpenAIChat
SideSeat(framework=Frameworks.Agno)
agent = Agent(model=OpenAIChat(id="gpt-5-mini"), tools=[])
agent.print_response("Hello!")

Agno is instrumented through OpenInference. Its spans carry agno.* attributes alongside openinference.*, and SideSeat’s detection prefers the specific agno. prefix so runs are labelled Agno rather than the generic OpenInference.

Terminal window
pip install smolagents "sideseat[smolagents]"
from sideseat import SideSeat, Frameworks
from smolagents import CodeAgent, InferenceClientModel
SideSeat(framework=Frameworks.Smolagents)
agent = CodeAgent(tools=[], model=InferenceClientModel())
agent.run("What is 2+2?")

Only the agent run span carries smolagents.*; step, model and tool spans inside the run are attributed by their own attributes.

Terminal window
pip install "ag2[openai]<1.0" "sideseat[ag2]"
from sideseat import SideSeat, Frameworks
from autogen import ConversableAgent
SideSeat(framework=Frameworks.AG2)
assistant = ConversableAgent(
name="assistant",
llm_config={"model": "gpt-5-mini"},
)
print(assistant.generate_reply(messages=[{"role": "user", "content": "Hello!"}]))

AG2 is the community fork of AutoGen and keeps the autogen import path, so its OpenInference instrumentor is openinference-instrumentation-autogen. Pin below 1.0: ag2 1.0 renamed its top-level module from autogen to ag2 and removed ConversableAgent, and the instrumentor patches autogen. SideSeat distinguishes the two by the ag2.* attribute prefix, so AG2 runs are not mislabelled AutoGen.

Terminal window
pip install agentscope sideseat
from sideseat import SideSeat, Frameworks
SideSeat(framework=Frameworks.AgentScope)
# AgentScope emits OpenTelemetry itself and only needs the provider SideSeat installs.

No extra is needed: AgentScope exports spans through the global tracer provider. Its spans carry agentscope.* attributes and gen_ai.conversation.id, which SideSeat reads as the session id.

Terminal window
pip install langflow sideseat

Langflow emits OpenTelemetry itself. Either run it in a process where SideSeat has installed the provider, or point Langflow’s own OTLP exporter at SideSeat:

Terminal window
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:5388/otel/default

Flow spans carry langflow.flow_id, langflow.flow_name and langflow.session_id.

Terminal window
pip install haystack-ai "sideseat[haystack]"
from sideseat import SideSeat, Frameworks
from haystack import Pipeline
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
SideSeat(framework=Frameworks.Haystack)
pipeline = Pipeline()
pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-5-mini"))
result = pipeline.run({"llm": {"messages": [ChatMessage.from_user("Hello")]}})
print(result["llm"]["replies"][0].text)

Component spans carry haystack.component.name and haystack.component.type, which SideSeat uses to label the run Haystack rather than generic OpenInference.

Terminal window
pip install browser-use sideseat
import asyncio
from sideseat import SideSeat, Frameworks
from browser_use import Agent, ChatOpenAI
SideSeat(framework=Frameworks.BrowserUse)
async def main():
agent = Agent(task="Find the docs", llm=ChatOpenAI(model="gpt-5-mini"))
print(await agent.run())
asyncio.run(main())

No extra is needed: browser-use exports OpenTelemetry through the global provider. Every span it emits sets gen_ai.provider.name = "browser_use", which is how SideSeat detects it.

The server classifies these, but nothing here tells you how to wire them up — each already emits OpenTelemetry on its own, so the generic setup below is the whole instruction and the spans are attributed once they arrive:

FrameworkRecognised by
Semantic Kernelsemantic_kernel.* attributes
Azure AI FoundryAzure AI attributes, after the more specific Azure OpenAI rule
LogfirePydantic Logfire’s own attributes
MLflowMLflow tracing attributes
TraceLoopOpenLLMetry / TraceLoop attributes
LiveKitLiveKit Agents attributes

None of these has a captured fixture, so their message extraction is not covered by the goldens. The support matrix in server/tests/fixtures/messages/README.md is the exact boundary of what is verified.

For frameworks not listed above, send traces directly via the OpenTelemetry SDK:

  1. Start SideSeat

    Terminal window
    npx sideseat
  2. Set the endpoint

    Terminal window
    export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:5388/otel/default
  3. Install and configure

    Terminal window
    pip install opentelemetry-sdk opentelemetry-exporter-otlp
    from opentelemetry import trace
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    provider = TracerProvider()
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)

SideSeat auto-detects framework spans and normalizes them into the workbench timeline.