ioa-observe-sdk 1.0.23__py3-none-any.whl → 1.0.25__py3-none-any.whl
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.
- ioa_observe/sdk/instrumentations/a2a.py +60 -0
- ioa_observe/sdk/instrumentations/slim.py +18 -12
- {ioa_observe_sdk-1.0.23.dist-info → ioa_observe_sdk-1.0.25.dist-info}/METADATA +32 -1
- {ioa_observe_sdk-1.0.23.dist-info → ioa_observe_sdk-1.0.25.dist-info}/RECORD +7 -7
- {ioa_observe_sdk-1.0.23.dist-info → ioa_observe_sdk-1.0.25.dist-info}/WHEEL +0 -0
- {ioa_observe_sdk-1.0.23.dist-info → ioa_observe_sdk-1.0.25.dist-info}/licenses/LICENSE.md +0 -0
- {ioa_observe_sdk-1.0.23.dist-info → ioa_observe_sdk-1.0.25.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
#
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
@@ -14,10 +14,10 @@ ioa_observe/sdk/decorators/base.py,sha256=pnoj73UrpvaZmOPbcpGRRYCwg7LBAgO8PiBDh5
|
|
|
14
14
|
ioa_observe/sdk/decorators/helpers.py,sha256=I9HXMBivkZpGDtPe9Ad_UU35p_m_wEPate4r_fU0oOA,2705
|
|
15
15
|
ioa_observe/sdk/decorators/util.py,sha256=IebvH9gwZN1en3LblYJUh4bAV2STl6xmp8WpZzBDH2g,30068
|
|
16
16
|
ioa_observe/sdk/instrumentations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
ioa_observe/sdk/instrumentations/a2a.py,sha256=
|
|
17
|
+
ioa_observe/sdk/instrumentations/a2a.py,sha256=6BOMxrGeMiii-5rptouqkUd2RDpGL01ZyDotgo7pFyM,9088
|
|
18
18
|
ioa_observe/sdk/instrumentations/mcp.py,sha256=vRM3ofnn7AMmry2RrfyZnZVPEutLWiDMghx2TSnm0Wk,18569
|
|
19
19
|
ioa_observe/sdk/instrumentations/nats.py,sha256=UOp2AJlm1JkYkwF3xzU_izzohQVQkByjL-AX4n_JRfo,14476
|
|
20
|
-
ioa_observe/sdk/instrumentations/slim.py,sha256=
|
|
20
|
+
ioa_observe/sdk/instrumentations/slim.py,sha256=HEl4IUKqoGN55FHKiWgP78KZWA1uCcfdDcKgtRhcfU8,44226
|
|
21
21
|
ioa_observe/sdk/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
ioa_observe/sdk/logging/logging.py,sha256=HZxW9s8Due7jgiNkdI38cIjv5rC9D-Flta3RQMOnpow,2891
|
|
23
23
|
ioa_observe/sdk/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -42,8 +42,8 @@ ioa_observe/sdk/utils/const.py,sha256=d67dUTAH9UpWvUV9GLBUqn1Sc2knJ55dy-e6YoLrvS
|
|
|
42
42
|
ioa_observe/sdk/utils/in_memory_span_exporter.py,sha256=H_4TRaThMO1H6vUQ0OpQvzJk_fZH0OOsRAM1iZQXsR8,2112
|
|
43
43
|
ioa_observe/sdk/utils/json_encoder.py,sha256=g4NQ0tTqgWssY6I1D7r4zo0G6PiUo61jhofTAw5-jno,639
|
|
44
44
|
ioa_observe/sdk/utils/package_check.py,sha256=1d1MjxhwoEZIx9dumirT2pRsEWgn-m-SI4npDeEalew,576
|
|
45
|
-
ioa_observe_sdk-1.0.
|
|
46
|
-
ioa_observe_sdk-1.0.
|
|
47
|
-
ioa_observe_sdk-1.0.
|
|
48
|
-
ioa_observe_sdk-1.0.
|
|
49
|
-
ioa_observe_sdk-1.0.
|
|
45
|
+
ioa_observe_sdk-1.0.25.dist-info/licenses/LICENSE.md,sha256=55VjUfgjWOS4vv3Cf55gfq-RxjPgRIO2vlgYPUuC5lA,11362
|
|
46
|
+
ioa_observe_sdk-1.0.25.dist-info/METADATA,sha256=QmZACsAli5POXMbvcTB3xuCdRl28w0FD8d2Nmt_920Y,7997
|
|
47
|
+
ioa_observe_sdk-1.0.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
48
|
+
ioa_observe_sdk-1.0.25.dist-info/top_level.txt,sha256=Yt-6Y1olZEDqCs2REeqI30WjYx0pLGQSVqzYmDd67N8,12
|
|
49
|
+
ioa_observe_sdk-1.0.25.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|