agnt5 0.2.8a5__cp310-abi3-manylinux_2_34_x86_64.whl → 0.2.8a6__cp310-abi3-manylinux_2_34_x86_64.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.
Potentially problematic release.
This version of agnt5 might be problematic. Click here for more details.
agnt5/_core.abi3.so
CHANGED
|
Binary file
|
agnt5/_telemetry.py
CHANGED
|
@@ -73,10 +73,17 @@ class OpenTelemetryHandler(logging.Handler):
|
|
|
73
73
|
exc_text = self.formatException(record.exc_info)
|
|
74
74
|
message = f"{message}\n{exc_text}"
|
|
75
75
|
|
|
76
|
+
# Extract correlation IDs from LogRecord attributes (added by _CorrelationFilter)
|
|
77
|
+
# These ensure logs can be correlated with distributed traces in observability backends
|
|
78
|
+
trace_id = getattr(record, 'trace_id', None)
|
|
79
|
+
span_id = getattr(record, 'span_id', None)
|
|
80
|
+
run_id = getattr(record, 'run_id', None)
|
|
81
|
+
|
|
76
82
|
# Forward to Rust tracing system
|
|
77
83
|
# Rust side will:
|
|
78
84
|
# - Add to current span context (inherits invocation.id)
|
|
79
|
-
# -
|
|
85
|
+
# - Attach correlation IDs as span attributes for OTLP export
|
|
86
|
+
# - Send to OTLP exporter with trace context
|
|
80
87
|
# - Print to console via fmt layer
|
|
81
88
|
self._log_from_python(
|
|
82
89
|
level=record.levelname,
|
|
@@ -84,7 +91,10 @@ class OpenTelemetryHandler(logging.Handler):
|
|
|
84
91
|
target=record.name,
|
|
85
92
|
module_path=record.module,
|
|
86
93
|
filename=record.pathname,
|
|
87
|
-
line=record.lineno
|
|
94
|
+
line=record.lineno,
|
|
95
|
+
trace_id=trace_id,
|
|
96
|
+
span_id=span_id,
|
|
97
|
+
run_id=run_id,
|
|
88
98
|
)
|
|
89
99
|
except Exception:
|
|
90
100
|
# Don't let logging errors crash the application
|
agnt5/agent.py
CHANGED
|
@@ -10,7 +10,7 @@ import functools
|
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
12
|
import time
|
|
13
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
13
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
14
14
|
|
|
15
15
|
from .context import Context
|
|
16
16
|
from . import lm
|
|
@@ -86,7 +86,6 @@ class AgentContext(Context):
|
|
|
86
86
|
if state_manager:
|
|
87
87
|
# Explicit state adapter provided (parameter name kept for backward compat)
|
|
88
88
|
self._state_adapter = state_manager
|
|
89
|
-
logger.debug(f"AgentContext using provided state adapter")
|
|
90
89
|
elif parent_context:
|
|
91
90
|
# Try to inherit state adapter from parent
|
|
92
91
|
try:
|
|
@@ -94,38 +93,30 @@ class AgentContext(Context):
|
|
|
94
93
|
if hasattr(parent_context, '_workflow_entity'):
|
|
95
94
|
# WorkflowContext - get state adapter from worker context
|
|
96
95
|
self._state_adapter = _get_state_adapter()
|
|
97
|
-
logger.debug(f"AgentContext inheriting state from WorkflowContext")
|
|
98
96
|
elif hasattr(parent_context, '_state_adapter'):
|
|
99
97
|
# Parent AgentContext - share state adapter
|
|
100
98
|
self._state_adapter = parent_context._state_adapter
|
|
101
|
-
logger.debug(f"AgentContext inheriting state from parent AgentContext")
|
|
102
99
|
elif hasattr(parent_context, '_state_manager'):
|
|
103
100
|
# Backward compatibility: parent has old _state_manager
|
|
104
101
|
self._state_adapter = parent_context._state_manager
|
|
105
|
-
logger.debug(f"AgentContext inheriting state from parent (legacy)")
|
|
106
102
|
else:
|
|
107
103
|
# FunctionContext or base Context - create new state adapter
|
|
108
104
|
self._state_adapter = EntityStateAdapter()
|
|
109
|
-
logger.debug(f"AgentContext created new state adapter (parent has no state)")
|
|
110
105
|
except RuntimeError as e:
|
|
111
106
|
# _get_state_adapter() failed (not in worker context) - create standalone
|
|
112
107
|
self._state_adapter = EntityStateAdapter()
|
|
113
|
-
logger.debug(f"AgentContext created standalone state adapter (not in worker context)")
|
|
114
108
|
else:
|
|
115
109
|
# Try to get from worker context first
|
|
116
110
|
try:
|
|
117
111
|
self._state_adapter = _get_state_adapter()
|
|
118
|
-
logger.debug(f"AgentContext got state adapter from worker context")
|
|
119
112
|
except RuntimeError as e:
|
|
120
113
|
# Standalone - create new state adapter
|
|
121
114
|
self._state_adapter = EntityStateAdapter()
|
|
122
|
-
logger.debug(f"AgentContext created standalone state adapter")
|
|
123
115
|
|
|
124
116
|
# Conversation key for state storage (used for in-memory state)
|
|
125
117
|
self._conversation_key = f"agent:{agent_name}:{self._session_id}:messages"
|
|
126
118
|
# Entity key for database persistence (without :messages suffix to match API expectations)
|
|
127
119
|
self._entity_key = f"agent:{agent_name}:{self._session_id}"
|
|
128
|
-
logger.debug(f"AgentContext initialized - session_id={self._session_id}")
|
|
129
120
|
|
|
130
121
|
@property
|
|
131
122
|
def state(self):
|
|
@@ -174,15 +165,12 @@ class AgentContext(Context):
|
|
|
174
165
|
if isinstance(session_data, dict) and "messages" in session_data:
|
|
175
166
|
# New format with session metadata
|
|
176
167
|
messages_data = session_data["messages"]
|
|
177
|
-
logger.debug(f"Loaded {len(messages_data)} messages from session {entity_key}")
|
|
178
168
|
elif isinstance(session_data, list):
|
|
179
169
|
# Old format - just messages array
|
|
180
170
|
messages_data = session_data
|
|
181
|
-
logger.debug(f"Loaded {len(messages_data)} messages (legacy format)")
|
|
182
171
|
else:
|
|
183
172
|
# No messages found
|
|
184
173
|
messages_data = []
|
|
185
|
-
logger.debug(f"No conversation history found for {entity_key}")
|
|
186
174
|
|
|
187
175
|
# Convert dict representations back to Message objects
|
|
188
176
|
messages = []
|
|
@@ -215,8 +203,6 @@ class AgentContext(Context):
|
|
|
215
203
|
Args:
|
|
216
204
|
messages: List of Message objects to persist
|
|
217
205
|
"""
|
|
218
|
-
logger.debug(f"Saving {len(messages)} messages to conversation history")
|
|
219
|
-
|
|
220
206
|
# Convert Message objects to dict for JSON serialization
|
|
221
207
|
messages_data = []
|
|
222
208
|
for msg in messages:
|
|
@@ -360,16 +346,23 @@ class Handoff:
|
|
|
360
346
|
```python
|
|
361
347
|
specialist = Agent(name="specialist", ...)
|
|
362
348
|
|
|
363
|
-
#
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
349
|
+
# Simple: Pass agent directly (auto-wrapped with defaults)
|
|
350
|
+
coordinator = Agent(
|
|
351
|
+
name="coordinator",
|
|
352
|
+
handoffs=[specialist] # Agent auto-converted to Handoff
|
|
367
353
|
)
|
|
368
354
|
|
|
369
|
-
# Use
|
|
355
|
+
# Advanced: Use Handoff for custom configuration
|
|
370
356
|
coordinator = Agent(
|
|
371
357
|
name="coordinator",
|
|
372
|
-
handoffs=[
|
|
358
|
+
handoffs=[
|
|
359
|
+
Handoff(
|
|
360
|
+
agent=specialist,
|
|
361
|
+
description="Custom description for LLM",
|
|
362
|
+
tool_name="custom_transfer_name",
|
|
363
|
+
pass_full_history=False
|
|
364
|
+
)
|
|
365
|
+
]
|
|
373
366
|
)
|
|
374
367
|
```
|
|
375
368
|
"""
|
|
@@ -447,7 +440,6 @@ class AgentRegistry:
|
|
|
447
440
|
if agent.name in _AGENT_REGISTRY:
|
|
448
441
|
logger.warning(f"Overwriting existing agent '{agent.name}'")
|
|
449
442
|
_AGENT_REGISTRY[agent.name] = agent
|
|
450
|
-
logger.debug(f"Registered agent '{agent.name}'")
|
|
451
443
|
|
|
452
444
|
@staticmethod
|
|
453
445
|
def get(name: str) -> Optional["Agent"]:
|
|
@@ -463,7 +455,6 @@ class AgentRegistry:
|
|
|
463
455
|
def clear() -> None:
|
|
464
456
|
"""Clear all registered agents."""
|
|
465
457
|
_AGENT_REGISTRY.clear()
|
|
466
|
-
logger.debug("Cleared agent registry")
|
|
467
458
|
|
|
468
459
|
|
|
469
460
|
class AgentResult:
|
|
@@ -528,7 +519,7 @@ class Agent:
|
|
|
528
519
|
model: Any, # Can be string like "openai/gpt-4o-mini" OR LanguageModel instance
|
|
529
520
|
instructions: str,
|
|
530
521
|
tools: Optional[List[Any]] = None,
|
|
531
|
-
handoffs: Optional[List[Handoff]] = None,
|
|
522
|
+
handoffs: Optional[List[Union["Agent", Handoff]]] = None, # Accept Agent or Handoff instances
|
|
532
523
|
temperature: float = 0.7,
|
|
533
524
|
max_tokens: Optional[int] = None,
|
|
534
525
|
top_p: Optional[float] = None,
|
|
@@ -543,7 +534,7 @@ class Agent:
|
|
|
543
534
|
model: Model string with provider prefix (e.g., "openai/gpt-4o-mini") OR LanguageModel instance
|
|
544
535
|
instructions: System instructions for the agent
|
|
545
536
|
tools: List of tools available to the agent (functions, Tool instances, or Agent instances)
|
|
546
|
-
handoffs: List of
|
|
537
|
+
handoffs: List of handoff configurations - can be Agent instances (auto-wrapped) or Handoff instances for custom config
|
|
547
538
|
temperature: LLM temperature (0.0 to 1.0)
|
|
548
539
|
max_tokens: Maximum tokens to generate
|
|
549
540
|
top_p: Nucleus sampling parameter
|
|
@@ -573,8 +564,18 @@ class Agent:
|
|
|
573
564
|
else:
|
|
574
565
|
raise TypeError(f"model must be a string or LanguageModel instance, got {type(model)}")
|
|
575
566
|
|
|
576
|
-
#
|
|
577
|
-
self.handoffs =
|
|
567
|
+
# Normalize handoffs: convert Agent instances to Handoff instances
|
|
568
|
+
self.handoffs: List[Handoff] = []
|
|
569
|
+
if handoffs:
|
|
570
|
+
for handoff_item in handoffs:
|
|
571
|
+
if isinstance(handoff_item, Agent):
|
|
572
|
+
# Auto-wrap Agent in Handoff with sensible defaults
|
|
573
|
+
self.handoffs.append(Handoff(agent=handoff_item))
|
|
574
|
+
logger.info(f"Auto-wrapped agent '{handoff_item.name}' in Handoff for '{self.name}'")
|
|
575
|
+
elif isinstance(handoff_item, Handoff):
|
|
576
|
+
self.handoffs.append(handoff_item)
|
|
577
|
+
else:
|
|
578
|
+
raise TypeError(f"handoffs must contain Agent or Handoff instances, got {type(handoff_item)}")
|
|
578
579
|
|
|
579
580
|
# Build tool registry (includes regular tools, agent-as-tools, and handoff tools)
|
|
580
581
|
self.tools: Dict[str, Tool] = {}
|
agnt5/worker.py
CHANGED
|
@@ -612,7 +612,6 @@ class Worker:
|
|
|
612
612
|
elif component_type == "function":
|
|
613
613
|
function_config = FunctionRegistry.get(component_name)
|
|
614
614
|
if function_config:
|
|
615
|
-
logger.info(f"🔥 WORKER: Received request for function: {component_name}")
|
|
616
615
|
# Return coroutine, don't await it
|
|
617
616
|
return self._execute_function(function_config, input_data, request)
|
|
618
617
|
|
|
@@ -637,7 +636,6 @@ class Worker:
|
|
|
637
636
|
from ._core import PyExecuteComponentResponse
|
|
638
637
|
|
|
639
638
|
exec_start = time.time()
|
|
640
|
-
logger.info(f"🔥 WORKER: Executing function {config.name}")
|
|
641
639
|
|
|
642
640
|
try:
|
|
643
641
|
# Parse input data
|
|
@@ -655,26 +653,15 @@ class Worker:
|
|
|
655
653
|
runtime_context=request.runtime_context,
|
|
656
654
|
)
|
|
657
655
|
|
|
658
|
-
#
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
with
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
"service.name": self.service_name,
|
|
668
|
-
},
|
|
669
|
-
) as span:
|
|
670
|
-
# Execute function
|
|
671
|
-
if input_dict:
|
|
672
|
-
result = config.handler(ctx, **input_dict)
|
|
673
|
-
else:
|
|
674
|
-
result = config.handler(ctx)
|
|
675
|
-
|
|
676
|
-
# Debug: Log what type result is
|
|
677
|
-
logger.info(f"🔥 WORKER: Function result type: {type(result).__name__}, isasyncgen: {inspect.isasyncgen(result)}, iscoroutine: {inspect.iscoroutine(result)}")
|
|
656
|
+
# Execute function directly - Rust bridge handles tracing
|
|
657
|
+
# Note: Removed Python-level span creation to avoid duplicate spans.
|
|
658
|
+
# The Rust worker bridge (sdk-python/rust-src/worker.rs:413-659) already
|
|
659
|
+
# creates a comprehensive OpenTelemetry span with all necessary attributes.
|
|
660
|
+
# See DUPLICATE_SPANS_FIX.md for details.
|
|
661
|
+
if input_dict:
|
|
662
|
+
result = config.handler(ctx, **input_dict)
|
|
663
|
+
else:
|
|
664
|
+
result = config.handler(ctx)
|
|
678
665
|
|
|
679
666
|
# Note: Removed flush_telemetry_py() call here - it was causing 2-second blocking delay!
|
|
680
667
|
# The batch span processor handles flushing automatically with 5s timeout
|
|
@@ -842,23 +829,14 @@ class Worker:
|
|
|
842
829
|
runtime_context=request.runtime_context,
|
|
843
830
|
)
|
|
844
831
|
|
|
845
|
-
#
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
"workflow.name": config.name,
|
|
854
|
-
"service.name": self.service_name,
|
|
855
|
-
},
|
|
856
|
-
) as span:
|
|
857
|
-
# Execute workflow
|
|
858
|
-
if input_dict:
|
|
859
|
-
result = await config.handler(ctx, **input_dict)
|
|
860
|
-
else:
|
|
861
|
-
result = await config.handler(ctx)
|
|
832
|
+
# Execute workflow directly - Rust bridge handles tracing
|
|
833
|
+
# Note: Removed Python-level span creation to avoid duplicate spans.
|
|
834
|
+
# The Rust worker bridge creates comprehensive OpenTelemetry spans.
|
|
835
|
+
# See DUPLICATE_SPANS_FIX.md for details.
|
|
836
|
+
if input_dict:
|
|
837
|
+
result = await config.handler(ctx, **input_dict)
|
|
838
|
+
else:
|
|
839
|
+
result = await config.handler(ctx)
|
|
862
840
|
|
|
863
841
|
# Note: Removed flush_telemetry_py() call here - it was causing 2-second blocking delay!
|
|
864
842
|
# The batch span processor handles flushing automatically with 5s timeout
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
agnt5-0.2.
|
|
2
|
-
agnt5-0.2.
|
|
1
|
+
agnt5-0.2.8a6.dist-info/METADATA,sha256=st25oz0S3w9locE4xf85jnN25ZtanIvYJJXTnckQ0QM,996
|
|
2
|
+
agnt5-0.2.8a6.dist-info/WHEEL,sha256=AdMozAxftELsa3nYun92mL1tYO-R1ewuDPju53zvoK0,107
|
|
3
3
|
agnt5/__init__.py,sha256=liMb9egh56qvgY4Xvs9s7grOzF3lXSE8-nIksJLNAy4,2195
|
|
4
4
|
agnt5/_compat.py,sha256=BGuy3v5VDOHVa5f3Z-C22iMN19lAt0mPmXwF3qSSWxI,369
|
|
5
|
-
agnt5/_core.abi3.so,sha256=
|
|
5
|
+
agnt5/_core.abi3.so,sha256=6xzh1gJ7PTU3-7Tt1Wnh9S_x-XWNTNj5tERSW58SeFQ,15809776
|
|
6
6
|
agnt5/_retry_utils.py,sha256=loHsWY5BR4wZy57IzcDEjQAy88DHVwVIr25Cn1d9GPA,5801
|
|
7
7
|
agnt5/_schema_utils.py,sha256=MR67RW757T4Oq2Jqf4kB61H_b51zwaf3CLWELnkngRo,9572
|
|
8
|
-
agnt5/_telemetry.py,sha256=
|
|
9
|
-
agnt5/agent.py,sha256=
|
|
8
|
+
agnt5/_telemetry.py,sha256=gx4TQNqxeQwpyPWvgVVknPjx5NbenmR6E-DGCj18Ssw,6510
|
|
9
|
+
agnt5/agent.py,sha256=ccV0rLj_9eF_G2VfrY8GWDBbNBadmDAYPrBJ6hMeuTE,43089
|
|
10
10
|
agnt5/client.py,sha256=kXksazgxdVXWaG9OkjJA4cWruNtcS-ENhtnkrIdw-Nk,23212
|
|
11
11
|
agnt5/context.py,sha256=S2OzPkhn_jnqSWfT21mSYOux8vHaLKQxcAvggZDHQek,2378
|
|
12
12
|
agnt5/entity.py,sha256=AlHmSHVxQD5EYBvkmERKUkwv0ERrKaT8rvRK611hv_I,28941
|
|
@@ -17,6 +17,6 @@ agnt5/tool.py,sha256=dkShd97Y1cwSOUnTwvL2gr0CW-usRlaq4frki9kREXI,18008
|
|
|
17
17
|
agnt5/tracing.py,sha256=Mh2-OfnQM61lM_P8gxJstafdsUA8Gxoo1lP-Joxhub8,5980
|
|
18
18
|
agnt5/types.py,sha256=Zb71ZMwvrt1p4SH18cAKunp2y5tao_W5_jGYaPDejQo,2840
|
|
19
19
|
agnt5/version.py,sha256=rOq1mObLihnnKgKqBrwZA0zwOPudEKVFcW1a48ynkqc,573
|
|
20
|
-
agnt5/worker.py,sha256=
|
|
20
|
+
agnt5/worker.py,sha256=jRguDRF0uTjYAmmAgmn3GtdEvIxgTuUoIOsme3ba6mU,51172
|
|
21
21
|
agnt5/workflow.py,sha256=cDxKK21mLrsgjLGmosinhKnAme30CoQqs_fUFvRsyI0,23456
|
|
22
|
-
agnt5-0.2.
|
|
22
|
+
agnt5-0.2.8a6.dist-info/RECORD,,
|
|
File without changes
|