SDK Parity
Feature comparison between the Python and JavaScript SDKs.
Feature comparison between the Python (v0.1.10) and JavaScript/TypeScript (v0.3.0) SDKs. Both SDKs share the same wire format and connect to the same gateway — differences are in API surface and integration breadth.
Core API
| Feature | Python | JavaScript | Notes |
|---|---|---|---|
init() | risicare.init() | init() | Same config options |
shutdown() | risicare.shutdown(timeout_ms=5000) | await shutdown() | JS is async |
flush() | client.flush() | await flush() | JS is async |
enable() / disable() | risicare.enable() | enable() | |
is_enabled() | risicare.is_enabled() | isEnabled() | |
get_client() | risicare.get_client() | — | JS uses getTracer() instead |
get_tracer() | risicare.get_tracer() | getTracer() | |
reset_for_testing() | risicare.reset_for_testing() | — | Python only |
Progressive Integration Tiers
| Tier | Feature | Python | JavaScript |
|---|---|---|---|
| 0 | Env var auto-instrumentation | RISICARE_TRACING=true | RISICARE_TRACING=true |
| 1 | Explicit init | risicare.init() | init() |
| 1 | @trace / trace() | Decorator + context manager | trace('name', fn) wrapper |
| 2 | @agent | Decorator | agent(opts, fn) wrapper |
| 3 | @session / session_context() | Decorator + context manager | session(opts, fn) / withSession() |
| 4 | Phase decorators | @trace_think, @trace_decide, @trace_act, @trace_observe | traceThink(fn), traceDecide(fn), traceAct(fn), traceObserve(fn) |
| 5 | Multi-agent | @trace_message, @trace_delegate, @trace_coordinate | traceMessage(opts, fn), traceDelegate(opts, fn), traceCoordinate(opts, fn) |
Critical API behavior difference
Phase decorators behave differently between Python and JavaScript.
Python executes the function immediately and returns its result:
result = trace_think("analyze", lambda: "the answer") # result = "the answer"JavaScript returns a new function (decorator pattern) that you must call:
const fn = traceThink("analyze", () => "the answer"); // fn = [Function]
const result = fn(); // result = "the answer"
// Or call immediately:
const result = traceThink("analyze", () => "the answer")();This applies to traceThink, traceDecide, traceAct, traceObserve, traceMessage, traceDelegate, and traceCoordinate. The agent() and session() wrappers follow the same pattern in both SDKs — they always return a callable.
Context Propagation
| Feature | Python | JavaScript |
|---|---|---|
| Mechanism | contextvars | AsyncLocalStorage |
| Thread propagation | auto_patch=True patches ThreadPoolExecutor | Automatic via Node.js |
| Async propagation | auto_patch=True patches asyncio.create_task | Automatic via AsyncLocalStorage |
session_context() | Sync + async variants | withSession() (single API) |
agent_context() | Sync + async variants | withAgent() (single API) |
phase_context() | phase_context(SemanticPhase.THINK) | withPhase(SemanticPhase.THINK, fn) |
W3C inject_trace_context() | inject_trace_context(headers) | injectTraceContext(headers) |
W3C extract_trace_context() | extract_trace_context(headers) | extractTraceContext(headers) |
get_current_session() | Returns SessionContext | None | Returns SessionContext | undefined |
get_current_agent() | Returns AgentContext | None | Returns AgentContext | undefined |
get_current_span() | Returns Span | None | Returns Span | undefined |
| Span registry | register_span(), get_span_by_id(), unregister_span() | registerSpan(), getSpanById(), unregisterSpan() |
LLM Provider Support
| Provider | Python | JavaScript |
|---|---|---|
| OpenAI | Auto-instrumented | patchOpenAI() |
| Anthropic | Auto-instrumented | patchAnthropic() |
| Vercel AI SDK | — | patchVercelAI() |
| Google Gemini | Auto-instrumented | patchGoogleAI() |
| Cohere | Auto-instrumented | patchCohere() |
| Mistral | Auto-instrumented | patchMistral() |
| Groq | Auto-instrumented | patchGroq() |
| Together AI | Auto-instrumented | patchTogether() |
| Ollama | Auto-instrumented | patchOllama() |
| Amazon Bedrock | Auto-instrumented | patchBedrock() |
| Google Vertex AI | Auto-instrumented | Via patchGoogleAI() |
| Cerebras | Auto-instrumented | patchCerebras() |
| HuggingFace | Auto-instrumented | patchHuggingFace() |
| OpenAI-compatible (base_url) | Host detection (8 providers) | Host detection via patchOpenAI() |
Both SDKs support 12 native providers plus 8 host-detected providers (DeepSeek, xAI, Fireworks, Baseten, Novita, BytePlus, vLLM, and any OpenAI-compatible API). Python auto-patches on import; JavaScript requires an explicit patchX() call.
Instrumentation Style
| Python | JavaScript | |
|---|---|---|
| Method | Import hooks (sys.meta_path) — automatic | ES Proxy wrapping — manual patchX() call |
| When | On first import openai after init() | After calling patchOpenAI(new OpenAI()) |
| Control | install_import_hooks() / remove_import_hooks() | Call or skip patchX() |
| Check | is_instrumented("openai") | — |
| List | get_supported_modules() | — |
Framework Support
| Framework | Python | JavaScript |
|---|---|---|
| LangChain | Callback + patches | RisicareCallbackHandler |
| LangGraph | Patches | instrumentLangGraph() |
| Instructor | Patches | patchInstructor() |
| LlamaIndex | Span handler | RisicareLlamaIndexHandler |
| CrewAI | Patches | — (Python only) |
| AutoGen | Patches (v0.2 + v0.4) | — (Python only) |
| OpenAI Agents SDK | Patches | — (Python only) |
| LiteLLM | Callback | — (Python only) |
| DSPy | Callback | — (Python only) |
| Pydantic AI | Patches | — (Python only) |
Python supports 10 framework integrations. JavaScript supports 4 (LangChain.js, LangGraph.js, Instructor, LlamaIndex.TS). The remaining 6 frameworks are Python-only — no JavaScript npm packages exist for CrewAI, AutoGen, LiteLLM, DSPy, or Pydantic AI.
Exporters
| Exporter | Python | JavaScript |
|---|---|---|
HttpExporter | HTTP/2 via httpx | Native fetch |
ConsoleExporter | To stderr | To stdout |
BatchSpanProcessor | Timer + count threshold | setInterval + count threshold |
OTLPExporter | OTLP/HTTP JSON + circuit breaker | — |
SpanExporter base | Abstract class | Interface |
Fix Runtime
| Feature | Python | JavaScript |
|---|---|---|
FixRuntime | Full implementation | Full implementation |
init_runtime() | init_runtime(config) | initFixRuntime() (called by init()) |
get_runtime() | get_runtime() | getFixRuntime() |
shutdown_runtime() | shutdown_runtime() | shutdownFixRuntime() |
FixLoader | Loads fixes from API | Loads fixes from API |
FixApplier | Applies fixes to functions | Applies fixes to functions |
FixCache | Local fix caching | Local fix caching |
FixInterceptor | Routes calls via A/B test | interceptCall() in OpenAI patch |
Both SDKs wire the Fix Runtime into init() automatically. The OpenAI provider patch in JS calls getFixRuntime().interceptCall() before every LLM call to check for active fixes.
OpenTelemetry
| Feature | Python | JavaScript |
|---|---|---|
| OTel bridge | otel_bridge=True in init() | — |
RisicareSpanExporter | Plugs into OTel SDK | — |
RisicareSpanProcessor | Plugs into OTel SDK | — |
| OTLP export | OTLPExporter class | — |
| OTLP ingestion | Gateway accepts OTLP/HTTP | Gateway accepts OTLP/HTTP |
Configuration
| Option | Python | JavaScript |
|---|---|---|
api_key | api_key | apiKey |
endpoint | endpoint | endpoint |
environment | environment | environment |
service_name | service_name | serviceName |
service_version | service_version | serviceVersion |
enabled | enabled | enabled |
trace_content | trace_content | traceContent |
sample_rate | sample_rate | sampleRate |
batch_size | batch_size | batchSize |
batch_timeout_ms | batch_timeout_ms | batchTimeoutMs |
max_queue_size | — | maxQueueSize |
auto_patch | auto_patch (default True) | — |
debug | debug | debug |
compress | — | compress |
metadata | metadata | metadata |
exporters | exporters | — |
otlp_endpoint | otlp_endpoint | — |
otlp_headers | otlp_headers | — |
otel_bridge | otel_bridge | — |
project_id (deprecated) | Emits DeprecationWarning | Emits console.warn |
Enums
SpanKind, SpanStatus, and SemanticPhase have identical values in both SDKs. AgentRole and MessageType differ:
| Enum | Python | JavaScript |
|---|---|---|
SpanKind | 17 values (identical) | 17 values (identical) |
SpanStatus | UNSET, OK, ERROR | UNSET, OK, ERROR |
SemanticPhase | THINK, DECIDE, ACT, OBSERVE, REFLECT, COMMUNICATE, COORDINATE | Same 7 values |
AgentRole | 12 values | 14 values (superset — adds REVIEWER, CUSTOM) |
MessageType | 15 values | 18 values (superset — adds REQUEST, DELEGATE, COORDINATE) |
Wire Format
Both SDKs produce identical JSON payloads sent to POST /v1/spans. The gateway does not distinguish between Python and JavaScript origins. All 37 SpanData fields are supported by both SDKs.