Other Frameworks
SideSeat works with any framework that emits OpenTelemetry traces. This page covers frameworks without dedicated integration pages.
LangChain
Section titled “LangChain”pip install langchain langchain-openai "sideseat[langchain]"uv add langchain langchain-openai "sideseat[langchain]"from sideseat import SideSeat, Frameworksfrom langchain_openai import ChatOpenAI
SideSeat(framework=Frameworks.LangChain)
llm = ChatOpenAI(model="gpt-5-mini")response = llm.invoke("Hello!")print(response.content)PydanticAI
Section titled “PydanticAI”pip install pydantic-ai "sideseat[pydantic-ai]"uv add pydantic-ai "sideseat[pydantic-ai]"from sideseat import SideSeat, Frameworksfrom 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
Section titled “LlamaIndex”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:
pip install llama-index sideseat openinference-instrumentation-llama-indexuv add llama-index sideseat openinference-instrumentation-llama-indexfrom sideseat import SideSeatfrom openinference.instrumentation.llama_index import LlamaIndexInstrumentorfrom 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.
AutoGen
Section titled “AutoGen”pip install autogen-agentchat "autogen-ext[openai]" "sideseat[autogen]"uv add autogen-agentchat "autogen-ext[openai]" "sideseat[autogen]"import asyncio
from sideseat import SideSeat, Frameworksfrom autogen_agentchat.agents import AssistantAgentfrom 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())pip install agno openai "sideseat[agno]"from sideseat import SideSeat, Frameworksfrom agno.agent import Agentfrom 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.
Smolagents
Section titled “Smolagents”pip install smolagents "sideseat[smolagents]"from sideseat import SideSeat, Frameworksfrom 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.
pip install "ag2[openai]<1.0" "sideseat[ag2]"from sideseat import SideSeat, Frameworksfrom 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.
AgentScope
Section titled “AgentScope”pip install agentscope sideseatfrom 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.
Langflow
Section titled “Langflow”pip install langflow sideseatLangflow emits OpenTelemetry itself. Either run it in a process where SideSeat has installed the provider, or point Langflow’s own OTLP exporter at SideSeat:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:5388/otel/defaultFlow spans carry langflow.flow_id, langflow.flow_name and langflow.session_id.
Haystack
Section titled “Haystack”pip install haystack-ai "sideseat[haystack]"from sideseat import SideSeat, Frameworksfrom haystack import Pipelinefrom haystack.components.generators.chat import OpenAIChatGeneratorfrom 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.
browser-use
Section titled “browser-use”pip install browser-use sideseatimport asyncio
from sideseat import SideSeat, Frameworksfrom 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.
Recognised without a setup guide
Section titled “Recognised without a setup guide”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:
| Framework | Recognised by |
|---|---|
| Semantic Kernel | semantic_kernel.* attributes |
| Azure AI Foundry | Azure AI attributes, after the more specific Azure OpenAI rule |
| Logfire | Pydantic Logfire’s own attributes |
| MLflow | MLflow tracing attributes |
| TraceLoop | OpenLLMetry / TraceLoop attributes |
| LiveKit | LiveKit 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.
Generic OpenTelemetry
Section titled “Generic OpenTelemetry”For frameworks not listed above, send traces directly via the OpenTelemetry SDK:
-
Start SideSeat
Terminal window npx sideseat -
Set the endpoint
Terminal window export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:5388/otel/default -
Install and configure
Terminal window pip install opentelemetry-sdk opentelemetry-exporter-otlpTerminal window uv add opentelemetry-sdk opentelemetry-exporter-otlpfrom opentelemetry import tracefrom opentelemetry.sdk.trace import TracerProviderfrom opentelemetry.sdk.trace.export import BatchSpanProcessorfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporterprovider = TracerProvider()provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))trace.set_tracer_provider(provider)
SideSeat auto-detects framework spans and normalizes them into the workbench timeline.
Next Steps
Section titled “Next Steps”- Python SDK — SDK reference
- OpenTelemetry Reference — attribute extraction details