OpenInference-compatible observability for AG-Kit
OpenTelemetry-based observability for the TypeScript SDK with OpenInference semantic conventions.
``bashCore package
npm install @cloudbase/agent-observability
$3
When using
@cloudbase/agent-server or @cloudbase/agent-adapter-langgraph, observability is an optional peer dependency. You need to explicitly install it if you want tracing capabilities:`bash
Using with @cloudbase/agent-server
npm install @cloudbase/agent-server @cloudbase/agent-observabilityUsing with @cloudbase/agent-adapter-langgraph
npm install @cloudbase/agent-adapter-langgraph @cloudbase/agent-observability
`Without installing
@cloudbase/agent-observability, the packages will work normally but no traces will be generated.Architecture Overview
This package provides a callback-based observability system that integrates with LangChain/LangGraph through the standard
BaseCallbackHandler mechanism.$3
`
┌─────────────────────────────────────────────────────────────────┐
│ Application │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Server Layer │ │
│ │ Creates AG-UI.Server span, extracts SpanContext, │ │
│ │ propagates via forwardedProps │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Adapter Layer (LangGraph) │ │
│ │ Restores SpanContext, sets external parent context │ │
│ │ in CallbackHandler │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ LangGraph Workflow (streamEvents) │ │
│ │ Events flow through patched astream_events │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ CallbackHandler (BaseCallbackHandler) │ │
│ │ on_chain_start, on_llm_start, on_tool_start, etc. │ │
│ │ Creates spans with correct parent-child relationships │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ OpenTelemetry │ │
│ │ SpanContext propagation, OTLP exporters │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
`$3
The observability system uses LangChain's standard
BaseCallbackHandler to automatically capture tracing events:1. Callback Registration
`typescript
import { CallbackHandler } from '@cloudbase/agent-observability/langchain'; const handler = new CallbackHandler({
adapterName: 'LangGraph'
});
`2. Span Hierarchy Construction
- Server span created at request entry
- SpanContext serialized and passed through
forwardedProps
- Adapter layer restores context and sets external parent
- CallbackHandler creates child spans with correct parent relationships3. Event Handling
-
on_chain_start: Creates CHAIN spans (Adapter.LangGraph, nodes)
- on_llm_start: Creates LLM spans (ChatOpenAI, etc.)
- on_tool_start: Creates TOOL spans (calculator, etc.)
- on_chain_end / on_llm_end / on_tool_end: End spans with durationQuick Start
$3
`typescript
import { startObservation } from '@cloudbase/agent-observability';// Create a span
const span = startObservation(
'my-operation',
{ 'http.method': 'GET' },
{ asType: 'span' }
);
// Update and end
span.update({ 'http.status_code': 200 });
span.end();
`$3
`typescript
import { CallbackHandler } from '@cloudbase/agent-observability/langchain';
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';const handler = CallbackHandler.create({
adapterName: 'LangGraph'
});
// Use with LangChain
const chain = new LLMChain({ llm, prompt, callbacks: [handler] });
await chain.invoke({ input: 'Hello' });
`$3
`typescript
import { CallbackHandler } from '@cloudbase/agent-observability/langchain';
import { StateGraph } from '@langgraph/langgraph';const workflow = new StateGraph(StateSchema)
.addNode('node_a', nodeA)
.addNode('node_b', nodeB)
.compile();
// The callback is automatically injected through the agent wrapper
const agent = new LangGraphAgent({ graph: workflow });
`Span Hierarchy Example
When using LangGraph with the server:
`
AG-UI.Server (Request entry point)
└─ Adapter.LangGraph (Agent adapter layer)
├─ node_a (LangGraph node)
│ └─ ChatOpenAI (LLM call)
├─ node_b (LangGraph node)
│ ├─ ChatOpenAI (LLM call)
│ └─ calculator (Tool call)
└─ synthesizer (LangGraph node)
└─ ChatOpenAI (LLM call)
`Internal spans: LangGraph also emits internal spans like
__start__ and ChannelWrite<...> which are tagged with metadata.tags: ["langsmith:hidden"]. These can be filtered in visualization tools if desired.OpenInference Semantic Conventions
This package follows OpenInference standards:
| Span Kind | Attribute | Description |
|-----------|-----------|-------------|
|
SPAN | openinference.span.kind: SPAN | General operations |
| CHAIN | openinference.span.kind: CHAIN | Chain/workflow spans |
| LLM | openinference.span.kind: LLM | LLM calls |
| TOOL | openinference.span.kind: TOOL | Tool/function calls |
| AGENT | openinference.span.kind: AGENT | Agent workflows |$3
-
input.value / output.value: Message content
- llm.model_name: Model identifier
- llm.token_count.prompt / llm.token_count.completion: Token usage
- tool.name: Tool function nameExporters
$3
`typescript
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
`$3
`typescript
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';const exporter = new OTLPTraceExporter({
url: 'http://localhost:3000/api/public/otel/v1/traces',
headers: {
'Authorization':
Basic ${credentials}
}
});
`API Reference
$3
-
startObservation(name, attributes, options): Create a new span
- getActiveTraceId(): Get current trace ID
- getActiveSpanId(): Get current span ID$3
`typescript
interface CallbackHandlerOptions {
adapterName: string; // e.g., 'LangGraph', 'LangChain'
traceMetadata?: Record;
observationCallbacks?: (obs: any) => void;
}
`$3
-
ObservationLLM: LLM generation spans
- ObservationTool: Tool invocation spans
- ObservationChain: Chain/workflow spans
- ObservationAgent: Agent spansDependencies
$3
-
@langchain/core: For LangChain callback integration$3
-
@opentelemetry/sdk-trace-base: For testing exporters
- @opentelemetry/exporter-trace-otlp-http`: For OTLP export