ioa-observe-sdk 1.0.23__tar.gz → 1.0.25__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/PKG-INFO +32 -1
  2. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/README.md +31 -0
  3. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instrumentations/a2a.py +60 -0
  4. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instrumentations/slim.py +18 -12
  5. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe_sdk.egg-info/PKG-INFO +32 -1
  6. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/pyproject.toml +1 -1
  7. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/LICENSE.md +0 -0
  8. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/__init__.py +0 -0
  9. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/__init__.py +0 -0
  10. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/client/__init__.py +0 -0
  11. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/client/client.py +0 -0
  12. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/client/http.py +0 -0
  13. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/config/__init__.py +0 -0
  14. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/connectors/__init__.py +0 -0
  15. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/connectors/slim.py +0 -0
  16. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/decorators/__init__.py +0 -0
  17. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/decorators/base.py +0 -0
  18. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/decorators/helpers.py +0 -0
  19. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/decorators/util.py +0 -0
  20. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instrumentations/__init__.py +0 -0
  21. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instrumentations/mcp.py +0 -0
  22. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instrumentations/nats.py +0 -0
  23. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/instruments.py +0 -0
  24. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/logging/__init__.py +0 -0
  25. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/logging/logging.py +0 -0
  26. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/__init__.py +0 -0
  27. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agent.py +0 -0
  28. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/__init__.py +0 -0
  29. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/agent_connections.py +0 -0
  30. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/availability.py +0 -0
  31. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/heuristics.py +0 -0
  32. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/recovery_tracker.py +0 -0
  33. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/tool_call_tracker.py +0 -0
  34. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/agents/tracker.py +0 -0
  35. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/metrics/metrics.py +0 -0
  36. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/telemetry.py +0 -0
  37. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/__init__.py +0 -0
  38. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/content_allow_list.py +0 -0
  39. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/context_manager.py +0 -0
  40. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/context_utils.py +0 -0
  41. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/manual.py +0 -0
  42. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/tracing.py +0 -0
  43. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/tracing/transform_span.py +0 -0
  44. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/utils/__init__.py +0 -0
  45. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/utils/const.py +0 -0
  46. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/utils/in_memory_span_exporter.py +0 -0
  47. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/utils/json_encoder.py +0 -0
  48. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/utils/package_check.py +0 -0
  49. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe/sdk/version.py +0 -0
  50. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe_sdk.egg-info/SOURCES.txt +0 -0
  51. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe_sdk.egg-info/dependency_links.txt +0 -0
  52. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe_sdk.egg-info/requires.txt +0 -0
  53. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/ioa_observe_sdk.egg-info/top_level.txt +0 -0
  54. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/setup.cfg +0 -0
  55. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/tests/test_client.py +0 -0
  56. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/tests/test_instrumentor.py +0 -0
  57. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/tests/test_manual_instrumentation.py +0 -0
  58. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/tests/test_transform_span.py +0 -0
  59. {ioa_observe_sdk-1.0.23 → ioa_observe_sdk-1.0.25}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ioa-observe-sdk
3
- Version: 1.0.23
3
+ Version: 1.0.25
4
4
  Summary: IOA Observability SDK
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -76,6 +76,37 @@ Alternatively, to download the SDK from git, you could also use the following co
76
76
  uv add "git+https://github.com/agntcy/observe"
77
77
  ```
78
78
 
79
+ ### Quick Start
80
+
81
+ After installation, import and initialize the SDK:
82
+
83
+ ```python
84
+ import os
85
+ from ioa_observe.sdk import Observe
86
+ from ioa_observe.sdk.decorators import agent
87
+ from ioa_observe.sdk.tracing import session_start
88
+
89
+ # Initialize Observe
90
+ Observe.init(
91
+ app_name="your_app_name",
92
+ api_endpoint=os.getenv("OTLP_HTTP_ENDPOINT", "http://localhost:4318")
93
+ )
94
+
95
+ # Use decorators to instrument your agents
96
+ @agent(name="my_agent", description="Example agent")
97
+ def my_agent_function(state):
98
+ # Your agent logic here
99
+ return {"result": "success"}
100
+
101
+ # Start a session for tracking
102
+ with session_start() as session_id:
103
+ result = my_agent_function({"input": "data"})
104
+ ```
105
+
106
+ **Note:** The package name for installation is `ioa_observe_sdk`, but imports use `ioa_observe` (underscore, not hyphen).
107
+
108
+ For comprehensive integration examples with LangGraph, LlamaIndex, and other frameworks, see the [Getting Started Guide](GETTING-STARTED.md).
109
+
79
110
  ## Schema
80
111
 
81
112
  The AGNTCY observability schema is an extension of the OTel LLM Semantic Conventions for Generative AI systems.
@@ -27,6 +27,37 @@ Alternatively, to download the SDK from git, you could also use the following co
27
27
  uv add "git+https://github.com/agntcy/observe"
28
28
  ```
29
29
 
30
+ ### Quick Start
31
+
32
+ After installation, import and initialize the SDK:
33
+
34
+ ```python
35
+ import os
36
+ from ioa_observe.sdk import Observe
37
+ from ioa_observe.sdk.decorators import agent
38
+ from ioa_observe.sdk.tracing import session_start
39
+
40
+ # Initialize Observe
41
+ Observe.init(
42
+ app_name="your_app_name",
43
+ api_endpoint=os.getenv("OTLP_HTTP_ENDPOINT", "http://localhost:4318")
44
+ )
45
+
46
+ # Use decorators to instrument your agents
47
+ @agent(name="my_agent", description="Example agent")
48
+ def my_agent_function(state):
49
+ # Your agent logic here
50
+ return {"result": "success"}
51
+
52
+ # Start a session for tracking
53
+ with session_start() as session_id:
54
+ result = my_agent_function({"input": "data"})
55
+ ```
56
+
57
+ **Note:** The package name for installation is `ioa_observe_sdk`, but imports use `ioa_observe` (underscore, not hyphen).
58
+
59
+ For comprehensive integration examples with LangGraph, LlamaIndex, and other frameworks, see the [Getting Started Guide](GETTING-STARTED.md).
60
+
30
61
  ## Schema
31
62
 
32
63
  The AGNTCY observability schema is an extension of the OTel LLM Semantic Conventions for Generative AI systems.
@@ -89,6 +89,60 @@ class A2AInstrumentor(BaseInstrumentor):
89
89
 
90
90
  A2AClient.send_message = instrumented_send_message
91
91
 
92
+ # Instrument broadcast_message
93
+ if hasattr(A2AClient, "broadcast_message"):
94
+ original_broadcast_message = A2AClient.broadcast_message
95
+
96
+ @functools.wraps(original_broadcast_message)
97
+ async def instrumented_broadcast_message(self, request, *args, **kwargs):
98
+ # Put context into A2A message metadata instead of HTTP headers
99
+ with _global_tracer.start_as_current_span("a2a.broadcast_message"):
100
+ traceparent = get_current_traceparent()
101
+ session_id = None
102
+ if traceparent:
103
+ session_id = kv_store.get(f"execution.{traceparent}")
104
+ if session_id:
105
+ kv_store.set(f"execution.{traceparent}", session_id)
106
+
107
+ # Ensure metadata dict exists
108
+ try:
109
+ md = getattr(request.params, "metadata", None)
110
+ except AttributeError:
111
+ md = None
112
+ metadata = md if isinstance(md, dict) else {}
113
+
114
+ observe_meta = dict(metadata.get("observe", {}))
115
+
116
+ # Inject W3C trace context + baggage into observe_meta
117
+ TraceContextTextMapPropagator().inject(carrier=observe_meta)
118
+ W3CBaggagePropagator().inject(carrier=observe_meta)
119
+
120
+ if traceparent:
121
+ observe_meta["traceparent"] = traceparent
122
+ if session_id:
123
+ observe_meta["session_id"] = session_id
124
+ baggage.set_baggage(f"execution.{traceparent}", session_id)
125
+
126
+ metadata["observe"] = observe_meta
127
+
128
+ # Write back metadata (pydantic models are mutable by default in v2)
129
+ try:
130
+ request.params.metadata = metadata
131
+ except Exception:
132
+ # Fallback
133
+ request = request.model_copy(
134
+ update={
135
+ "params": request.params.model_copy(
136
+ update={"metadata": metadata}
137
+ )
138
+ }
139
+ )
140
+
141
+ # Call through without transport-specific kwargs
142
+ return await original_broadcast_message(self, request, *args, **kwargs)
143
+
144
+ A2AClient.broadcast_message = instrumented_broadcast_message
145
+
92
146
  # Instrument server handler
93
147
  from a2a.server.request_handlers import DefaultRequestHandler
94
148
 
@@ -156,6 +210,12 @@ class A2AInstrumentor(BaseInstrumentor):
156
210
 
157
211
  A2AClient.send_message = A2AClient.send_message.__wrapped__
158
212
 
213
+ # Uninstrument `broadcast_message`
214
+ if hasattr(A2AClient, "broadcast_message") and hasattr(
215
+ A2AClient.broadcast_message, "__wrapped__"
216
+ ):
217
+ A2AClient.broadcast_message = A2AClient.broadcast_message.__wrapped__
218
+
159
219
  # Uninstrument server handler
160
220
  from a2a.server.request_handlers import DefaultRequestHandler
161
221
 
@@ -478,19 +478,19 @@ class SLIMInstrumentor(BaseInstrumentor):
478
478
  slim_bindings.Slim.listen_for_session = instrumented_listen_for_session
479
479
 
480
480
  def _instrument_session_methods(self, slim_bindings):
481
- # check if slim_bindings >= v0.6.0 is installed by looking for Session class
482
- if not hasattr(slim_bindings, "Session"):
483
- return
484
-
485
- # In v0.6.0+, we need to instrument session classes dynamically
486
481
  # Try to find session-related classes in the slim_bindings module
487
482
  session_classes = []
488
483
 
489
- # Look for common session class names
490
- for attr_name in ["Session", "P2PSession", "GroupSession"]:
491
- if hasattr(slim_bindings, attr_name):
492
- session_class = getattr(slim_bindings, attr_name)
493
- session_classes.append((attr_name, session_class))
484
+ # Check for v0.6.0+ Session classes
485
+ if hasattr(slim_bindings, "Session"):
486
+ for attr_name in ["Session", "P2PSession", "GroupSession"]:
487
+ if hasattr(slim_bindings, attr_name):
488
+ session_class = getattr(slim_bindings, attr_name)
489
+ session_classes.append((attr_name, session_class))
490
+
491
+ # Check for older PySession class (pre-v0.6.0)
492
+ if hasattr(slim_bindings, "PySession"):
493
+ session_classes.append(("PySession", slim_bindings.PySession))
494
494
 
495
495
  # Also look for any class that has session-like methods
496
496
  for attr_name in dir(slim_bindings):
@@ -501,7 +501,7 @@ class SLIMInstrumentor(BaseInstrumentor):
501
501
  session_classes.append((attr_name, attr))
502
502
 
503
503
  # Instrument session methods for found classes
504
- for _, session_class in session_classes:
504
+ for class_name, session_class in session_classes:
505
505
  # Instrument get_message (v0.6.0+ replacement for receive)
506
506
  if hasattr(session_class, "get_message"):
507
507
  self._instrument_session_get_message(session_class)
@@ -686,7 +686,13 @@ class SLIMInstrumentor(BaseInstrumentor):
686
686
  baggage.set_baggage(f"execution.{traceparent}", session_id)
687
687
 
688
688
  # Wrap the message (first argument for publish, second for publish_to)
689
- message_idx = 1 if method_name == "publish_to" else 0
689
+ # If the session_class is SessionContext, the message is always in second position
690
+ message_idx = (
691
+ 1
692
+ if method_name == "publish_to"
693
+ or session_class.__name__ == "SessionContext"
694
+ else 0
695
+ )
690
696
  if len(args) > message_idx:
691
697
  args_list = list(args)
692
698
  message = args_list[message_idx]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ioa-observe-sdk
3
- Version: 1.0.23
3
+ Version: 1.0.25
4
4
  Summary: IOA Observability SDK
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -76,6 +76,37 @@ Alternatively, to download the SDK from git, you could also use the following co
76
76
  uv add "git+https://github.com/agntcy/observe"
77
77
  ```
78
78
 
79
+ ### Quick Start
80
+
81
+ After installation, import and initialize the SDK:
82
+
83
+ ```python
84
+ import os
85
+ from ioa_observe.sdk import Observe
86
+ from ioa_observe.sdk.decorators import agent
87
+ from ioa_observe.sdk.tracing import session_start
88
+
89
+ # Initialize Observe
90
+ Observe.init(
91
+ app_name="your_app_name",
92
+ api_endpoint=os.getenv("OTLP_HTTP_ENDPOINT", "http://localhost:4318")
93
+ )
94
+
95
+ # Use decorators to instrument your agents
96
+ @agent(name="my_agent", description="Example agent")
97
+ def my_agent_function(state):
98
+ # Your agent logic here
99
+ return {"result": "success"}
100
+
101
+ # Start a session for tracking
102
+ with session_start() as session_id:
103
+ result = my_agent_function({"input": "data"})
104
+ ```
105
+
106
+ **Note:** The package name for installation is `ioa_observe_sdk`, but imports use `ioa_observe` (underscore, not hyphen).
107
+
108
+ For comprehensive integration examples with LangGraph, LlamaIndex, and other frameworks, see the [Getting Started Guide](GETTING-STARTED.md).
109
+
79
110
  ## Schema
80
111
 
81
112
  The AGNTCY observability schema is an extension of the OTel LLM Semantic Conventions for Generative AI systems.
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "ioa-observe-sdk"
8
- version = "1.0.23"
8
+ version = "1.0.25"
9
9
  license = "Apache-2.0"
10
10
  description = "IOA Observability SDK"
11
11
  readme = "README.md"