Skip to main content
Observability Hooks provide a centralized entry and exit point for observability providers (AgentOps, future Langfuse, W&B) in PraisonAI and custom framework adapters. The user starts an orchestrated run; init and finalize hooks emit traces to AgentOps and other providers. praisonai.observability.hooks.init_observability(framework_tag, *, tags=None) and finalize_observability(_framework_tag, *, status=...) are public hooks. The orchestrator calls both automatically; custom framework adapters should use observability_session() as the recommended pattern.

Quick Start

1

Simple Usage

2

With Configuration

3

Pair init with finalize in custom adapters

observability_session calls init_observability on entry and finalize_observability on exit. Status is derived from sys.exc_info() automatically, so success/failure is tagged correctly with no boilerplate.
4

Branch on availability


How It Works

init_observability(framework_tag, *, tags=None) centralizes observability initialization:
  • Auto-call site: orchestrator calls init_observability(adapter.name) immediately after assert_framework_available(...) and before adapter.setup(...)
  • AgentOps init guard: agentops.init(...) only fires if both (a) is_agentops_available() returns true, and (b) AGENTOPS_API_KEY is set in the env. Init is centralised here — agents_generator no longer double-inits AgentOps (PR #2062).
  • Failure mode: ImportError (no agentops) is logged at DEBUG; any other exception is logged at WARNING and never propagated
  • is_agentops_available() lazy function — prefer over the removed eager AGENTOPS_AVAILABLE constant in this module
finalize_observability(_framework_tag, *, status=...) closes observability sessions symmetrically:
  • Auto-call site: built-in adapters (praisonai_adapter, crewai_adapter, AutoGen v0.4, AG2) now wrap run()/arun() in a try: ... finally: block. finalize_observability(self.name, status=status) is called from that finally, with status derived from sys.exc_info(). AgentOps sessions are tagged "Success" on the happy path and "Failure" whenever an exception is propagating (including KeyboardInterrupt, LLM errors, rate limits, cancellation).
  • AgentOps end guard: agentops.end_session(...) only fires if agentops is importable
  • Failure mode: ImportError returns silently; any other exception is logged at WARNING and never propagated
  • Why symmetric calls matter: without finalize_observability, AgentOps dashboard sessions stay stuck “in progress”
The hook also leaves room for future providers (the source already has placeholder comments for _init_langfuse and _init_wandb), so users may want to know the surface area.

Configuration

init_observability

finalize_observability

observability_session

Returns a context manager (ContextManager[None]). Status is auto-derived from sys.exc_info() — no status kwarg needed.

discover_observability_sinks


Third-party sink plugins

Third-party packages can register an observability sink factory under the praisonai.observability_sinks entry-point group. PraisonAI discovers them lazily via discover_observability_sinks() — broken plugins are logged at DEBUG and never break a run.

Register a sink (plugin authors)

Your factory is a zero-arg (or framework-tag-aware) callable that returns a sink implementing the core SDK’s TraceSinkProtocol.

Discover registered sinks


Best Practices

observability_session is the recommended pattern for custom adapters. It guarantees finalize_observability always runs — on success and on any failure — with the correct status derived from sys.exc_info(). This prevents AgentOps/other sessions from being orphaned in an “in progress” state on error, KeyboardInterrupt, or rate-limit paths.
Use status="Success" for the happy path and status="Failure" in exception cases. The string is passed verbatim to agentops.end_session(...); future providers may map other values. When using observability_session, status is derived automatically.
The orchestrator calls init_observability(adapter.name) once per run. If you call it again from setup(), you’ll re-init with your tags (last call wins for AgentOps). Use this for run-scoped tags only:
Don’t import agentops at the top of your adapter — gate it behind is_agentops_available() or rely on the hook to no-op silently:
New providers (Langfuse, W&B, etc.) will be added inside _init_<provider> helpers in praisonai/observability/hooks.py — calling init_observability(...) will automatically pick them up; you don’t need to update adapter code:

AgentOps

AgentOps integration documentation

Framework Adapter Plugins

How to create custom framework adapters

Custom Tracing

ContextTraceSink protocol and third-party sink plugins

Gateway Tracing Hook

Emit OpenTelemetry spans across each gateway pipeline stage