agnt5 0.2.6__cp39-abi3-macosx_11_0_arm64.whl → 0.2.8a1__cp39-abi3-macosx_11_0_arm64.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/__init__.py CHANGED
@@ -6,7 +6,7 @@ with built-in durability guarantees and state management.
6
6
  """
7
7
 
8
8
  from ._compat import _import_error, _rust_available
9
- from .agent import Agent, AgentRegistry, AgentResult, Handoff, agent, handoff
9
+ from .agent import Agent, AgentContext, AgentRegistry, AgentResult, Handoff, agent, handoff
10
10
  from .client import Client, RunError
11
11
  from .context import Context
12
12
  from .function import FunctionContext
@@ -46,6 +46,7 @@ __all__ = [
46
46
  "Context",
47
47
  "FunctionContext",
48
48
  "WorkflowContext",
49
+ "AgentContext",
49
50
  "Client",
50
51
  "Worker",
51
52
  "function",
agnt5/_core.abi3.so CHANGED
Binary file
agnt5/agent.py CHANGED
@@ -23,6 +23,175 @@ logger = setup_module_logger(__name__)
23
23
  _AGENT_REGISTRY: Dict[str, "Agent"] = {}
24
24
 
25
25
 
26
+ class AgentContext(Context):
27
+ """
28
+ Context for agent execution with conversation state management.
29
+
30
+ Extends base Context with:
31
+ - State management via EntityStateManager
32
+ - Conversation history persistence
33
+ - Context inheritance (child agents share parent's state)
34
+
35
+ Three initialization modes:
36
+ 1. Standalone: Creates own state manager (playground testing)
37
+ 2. Inherit WorkflowContext: Shares parent's state manager
38
+ 3. Inherit parent AgentContext: Shares parent's state manager
39
+
40
+ Example:
41
+ ```python
42
+ # Standalone agent with conversation history
43
+ ctx = AgentContext(run_id="session-1", agent_name="tutor")
44
+ result = await agent.run("Hello", context=ctx)
45
+ result = await agent.run("Continue", context=ctx) # Remembers previous message
46
+
47
+ # Agent in workflow - shares workflow state
48
+ @workflow
49
+ async def research_workflow(ctx: WorkflowContext):
50
+ agent_result = await research_agent.run("Find AI trends", context=ctx)
51
+ # Agent has access to workflow state via inherited context
52
+ ```
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ run_id: str,
58
+ agent_name: str,
59
+ session_id: Optional[str] = None,
60
+ state_manager: Optional[Any] = None,
61
+ parent_context: Optional[Context] = None,
62
+ attempt: int = 0,
63
+ runtime_context: Optional[Any] = None,
64
+ ):
65
+ """
66
+ Initialize agent context.
67
+
68
+ Args:
69
+ run_id: Unique execution identifier
70
+ agent_name: Name of the agent
71
+ session_id: Session identifier for conversation history (default: run_id)
72
+ state_manager: Optional state manager (for context inheritance)
73
+ parent_context: Parent context to inherit state from
74
+ attempt: Retry attempt number
75
+ runtime_context: RuntimeContext for trace correlation
76
+ """
77
+ super().__init__(run_id, attempt, runtime_context)
78
+
79
+ self._agent_name = agent_name
80
+ self._session_id = session_id or run_id
81
+
82
+ # Determine state manager based on parent context
83
+ from .entity import EntityStateManager, _get_state_manager
84
+
85
+ if state_manager:
86
+ # Explicit state manager provided
87
+ self._state_manager = state_manager
88
+ logger.debug(f"AgentContext using provided state manager")
89
+ elif parent_context:
90
+ # Try to inherit state manager from parent
91
+ try:
92
+ # Check if parent is WorkflowContext or AgentContext
93
+ if hasattr(parent_context, '_workflow_entity'):
94
+ # WorkflowContext - get state manager from worker context
95
+ self._state_manager = _get_state_manager()
96
+ logger.debug(f"AgentContext inheriting state from WorkflowContext")
97
+ elif hasattr(parent_context, '_state_manager'):
98
+ # Parent AgentContext - share state manager
99
+ self._state_manager = parent_context._state_manager
100
+ logger.debug(f"AgentContext inheriting state from parent AgentContext")
101
+ else:
102
+ # FunctionContext or base Context - create new state manager
103
+ self._state_manager = EntityStateManager()
104
+ logger.debug(f"AgentContext created new state manager (parent has no state)")
105
+ except RuntimeError:
106
+ # _get_state_manager() failed (not in worker context) - create standalone
107
+ self._state_manager = EntityStateManager()
108
+ logger.debug(f"AgentContext created standalone state manager")
109
+ else:
110
+ # Standalone - create new state manager
111
+ self._state_manager = EntityStateManager()
112
+ logger.debug(f"AgentContext created standalone state manager")
113
+
114
+ # Conversation key for state storage
115
+ self._conversation_key = f"agent:{agent_name}:{self._session_id}:messages"
116
+
117
+ @property
118
+ def state(self):
119
+ """
120
+ Get state interface for agent state management.
121
+
122
+ Returns:
123
+ EntityState instance for state operations
124
+
125
+ Example:
126
+ # Store conversation history
127
+ messages = ctx.state.get(f"agent:{agent_name}:{session_id}:messages", [])
128
+ messages.append({"role": "user", "content": "Hello"})
129
+ ctx.state.set(f"agent:{agent_name}:{session_id}:messages", messages)
130
+
131
+ # Store agent-specific data
132
+ ctx.state.set("research_results", data)
133
+ """
134
+ from .entity import EntityState
135
+
136
+ # Use agent's conversation key as the state key
137
+ state_key = ("agent", self._conversation_key)
138
+ state_dict = self._state_manager.get_or_create_state(state_key)
139
+ return EntityState(state_dict)
140
+
141
+ @property
142
+ def session_id(self) -> str:
143
+ """Get session identifier for this agent context."""
144
+ return self._session_id
145
+
146
+ def get_conversation_history(self) -> List[Message]:
147
+ """
148
+ Retrieve conversation history from state.
149
+
150
+ Returns:
151
+ List of Message objects from conversation history
152
+ """
153
+ messages_data = self.state.get(self._conversation_key, [])
154
+
155
+ # Convert dict representations back to Message objects
156
+ messages = []
157
+ for msg_dict in messages_data:
158
+ if isinstance(msg_dict, dict):
159
+ role = msg_dict.get("role", "user")
160
+ content = msg_dict.get("content", "")
161
+ if role == "user":
162
+ messages.append(Message.user(content))
163
+ elif role == "assistant":
164
+ messages.append(Message.assistant(content))
165
+ else:
166
+ # Generic message - create with MessageRole enum
167
+ from .lm import MessageRole
168
+ msg_role = MessageRole(role) if role in ("user", "assistant", "system") else MessageRole.USER
169
+ msg = Message(role=msg_role, content=content)
170
+ messages.append(msg)
171
+ else:
172
+ # Already a Message object
173
+ messages.append(msg_dict)
174
+
175
+ return messages
176
+
177
+ def save_conversation_history(self, messages: List[Message]) -> None:
178
+ """
179
+ Save conversation history to state.
180
+
181
+ Args:
182
+ messages: List of Message objects to persist
183
+ """
184
+ # Convert Message objects to dict for JSON serialization
185
+ messages_data = []
186
+ for msg in messages:
187
+ messages_data.append({
188
+ "role": msg.role.value if hasattr(msg.role, 'value') else str(msg.role),
189
+ "content": msg.content
190
+ })
191
+
192
+ self.state.set(self._conversation_key, messages_data)
193
+
194
+
26
195
  class Handoff:
27
196
  """Configuration for agent-to-agent handoff.
28
197
 
@@ -463,13 +632,47 @@ class Agent:
463
632
  print(result.output)
464
633
  ```
465
634
  """
466
- # Create context if not provided
635
+ # Create or adapt context
467
636
  if context is None:
637
+ # Standalone execution - create AgentContext
468
638
  import uuid
469
-
470
- context = Context(
471
- run_id=f"agent-{self.name}-{uuid.uuid4().hex[:8]}",
639
+ run_id = f"agent-{self.name}-{uuid.uuid4().hex[:8]}"
640
+ context = AgentContext(
641
+ run_id=run_id,
642
+ agent_name=self.name,
643
+ )
644
+ elif isinstance(context, AgentContext):
645
+ # Already AgentContext - use as-is
646
+ pass
647
+ elif hasattr(context, '_workflow_entity'):
648
+ # WorkflowContext - create AgentContext that inherits state
649
+ import uuid
650
+ run_id = f"{context.run_id}:agent:{self.name}"
651
+ context = AgentContext(
652
+ run_id=run_id,
653
+ agent_name=self.name,
654
+ session_id=context.run_id, # Share workflow's session
655
+ parent_context=context,
472
656
  )
657
+ else:
658
+ # FunctionContext or other - create new AgentContext
659
+ import uuid
660
+ run_id = f"{context.run_id}:agent:{self.name}"
661
+ context = AgentContext(
662
+ run_id=run_id,
663
+ agent_name=self.name,
664
+ )
665
+
666
+ # Load conversation history from state (if AgentContext)
667
+ if isinstance(context, AgentContext):
668
+ messages: List[Message] = context.get_conversation_history()
669
+ # Add new user message
670
+ messages.append(Message.user(user_message))
671
+ # Save updated conversation
672
+ context.save_conversation_history(messages)
673
+ else:
674
+ # Fallback for non-AgentContext (shouldn't happen with code above)
675
+ messages = [Message.user(user_message)]
473
676
 
474
677
  # Create span for agent execution with trace linking
475
678
  from ._core import create_span
@@ -480,12 +683,10 @@ class Agent:
480
683
  context._runtime_context if hasattr(context, "_runtime_context") else None,
481
684
  {
482
685
  "agent.name": self.name,
483
- "agent.model": self.model,
686
+ "agent.model": self.model_name, # Use model_name (always a string)
484
687
  "agent.max_iterations": str(self.max_iterations),
485
688
  },
486
689
  ) as span:
487
- # Initialize conversation
488
- messages: List[Message] = [Message.user(user_message)]
489
690
  all_tool_calls: List[Dict[str, Any]] = []
490
691
 
491
692
  # Reasoning loop
@@ -508,26 +709,42 @@ class Agent:
508
709
  "content": msg.content
509
710
  })
510
711
 
511
- # Call LLM using simplified API
512
- # TODO: Support tools in lm.generate() - for now using GenerateRequest internally
513
- request = GenerateRequest(
514
- model=self.model,
515
- system_prompt=self.instructions,
516
- messages=messages,
517
- tools=tool_defs if tool_defs else [],
518
- )
519
- request.config.temperature = self.temperature
520
- if self.max_tokens:
521
- request.config.max_tokens = self.max_tokens
522
- if self.top_p:
523
- request.config.top_p = self.top_p
524
-
525
- # Create internal LM instance for generation
526
- # TODO: Use model_config when provided
527
- from .lm import _LanguageModel
528
- provider, model_name = self.model.split('/', 1)
529
- internal_lm = _LanguageModel(provider=provider.lower(), default_model=None)
530
- response = await internal_lm.generate(request)
712
+ # Call LLM
713
+ # Check if we have a legacy LanguageModel instance or need to create one
714
+ if self._language_model is not None:
715
+ # Legacy API: use provided LanguageModel instance
716
+ request = GenerateRequest(
717
+ model="mock-model", # Not used by MockLanguageModel
718
+ system_prompt=self.instructions,
719
+ messages=messages,
720
+ tools=tool_defs if tool_defs else [],
721
+ )
722
+ request.config.temperature = self.temperature
723
+ if self.max_tokens:
724
+ request.config.max_tokens = self.max_tokens
725
+ if self.top_p:
726
+ request.config.top_p = self.top_p
727
+ response = await self._language_model.generate(request)
728
+ else:
729
+ # New API: model is a string, create internal LM instance
730
+ request = GenerateRequest(
731
+ model=self.model,
732
+ system_prompt=self.instructions,
733
+ messages=messages,
734
+ tools=tool_defs if tool_defs else [],
735
+ )
736
+ request.config.temperature = self.temperature
737
+ if self.max_tokens:
738
+ request.config.max_tokens = self.max_tokens
739
+ if self.top_p:
740
+ request.config.top_p = self.top_p
741
+
742
+ # Create internal LM instance for generation
743
+ # TODO: Use model_config when provided
744
+ from .lm import _LanguageModel
745
+ provider, model_name = self.model.split('/', 1)
746
+ internal_lm = _LanguageModel(provider=provider.lower(), default_model=None)
747
+ response = await internal_lm.generate(request)
531
748
 
532
749
  # Add assistant response to messages
533
750
  messages.append(Message.assistant(response.text))
@@ -576,6 +793,9 @@ class Agent:
576
793
  f"Handoff detected to '{result['to_agent']}', "
577
794
  f"terminating current agent"
578
795
  )
796
+ # Save conversation before returning
797
+ if isinstance(context, AgentContext):
798
+ context.save_conversation_history(messages)
579
799
  # Return immediately with handoff result
580
800
  return AgentResult(
581
801
  output=result["output"],
@@ -613,6 +833,9 @@ class Agent:
613
833
  else:
614
834
  # No tool calls - agent is done
615
835
  self.logger.debug(f"Agent completed after {iteration + 1} iterations")
836
+ # Save conversation before returning
837
+ if isinstance(context, AgentContext):
838
+ context.save_conversation_history(messages)
616
839
  return AgentResult(
617
840
  output=response.text,
618
841
  tool_calls=all_tool_calls,
@@ -622,68 +845,15 @@ class Agent:
622
845
  # Max iterations reached
623
846
  self.logger.warning(f"Agent reached max iterations ({self.max_iterations})")
624
847
  final_output = messages[-1].content if messages else "No output generated"
848
+ # Save conversation before returning
849
+ if isinstance(context, AgentContext):
850
+ context.save_conversation_history(messages)
625
851
  return AgentResult(
626
852
  output=final_output,
627
853
  tool_calls=all_tool_calls,
628
854
  context=context,
629
855
  )
630
856
 
631
- async def chat(
632
- self,
633
- user_message: str,
634
- messages: List[Message],
635
- context: Optional[Context] = None,
636
- ) -> tuple[str, List[Message]]:
637
- """Continue multi-turn conversation.
638
-
639
- Args:
640
- user_message: New user message
641
- messages: Previous conversation messages
642
- context: Optional context
643
-
644
- Returns:
645
- Tuple of (assistant_response, updated_messages)
646
-
647
- Example:
648
- ```python
649
- messages = []
650
- response, messages = await agent.chat("Hello", messages)
651
- response, messages = await agent.chat("Tell me more", messages)
652
- ```
653
- """
654
- if context is None:
655
- import uuid
656
-
657
- context = Context(
658
- run_id=f"agent-chat-{self.name}-{uuid.uuid4().hex[:8]}",
659
- )
660
-
661
- # Add user message
662
- conversation = messages + [Message.user(user_message)]
663
-
664
- # Build request (no tools for simple chat)
665
- request = GenerateRequest(
666
- model=self.model,
667
- system_prompt=self.instructions,
668
- messages=conversation,
669
- )
670
- request.config.temperature = self.temperature
671
- if self.max_tokens:
672
- request.config.max_tokens = self.max_tokens
673
- if self.top_p:
674
- request.config.top_p = self.top_p
675
-
676
- # Create internal LM instance for generation
677
- from .lm import _LanguageModel
678
- provider, model_name = self.model.split('/', 1)
679
- internal_lm = _LanguageModel(provider=provider.lower(), default_model=None)
680
- response = await internal_lm.generate(request)
681
-
682
- # Add assistant response
683
- conversation.append(Message.assistant(response.text))
684
-
685
- return response.text, conversation
686
-
687
857
 
688
858
  def agent(
689
859
  _func: Optional[Callable] = None,
agnt5/entity.py CHANGED
@@ -6,7 +6,8 @@ import asyncio
6
6
  import contextvars
7
7
  import functools
8
8
  import inspect
9
- from typing import Any, Dict, Optional, Tuple
9
+ import json
10
+ from typing import Any, Dict, Optional, Tuple, get_type_hints
10
11
 
11
12
  from ._schema_utils import extract_function_metadata, extract_function_schemas
12
13
  from .exceptions import ExecutionError
@@ -230,6 +231,108 @@ def create_entity_context():
230
231
  return manager, token
231
232
 
232
233
 
234
+ def extract_state_schema(entity_class: type) -> Optional[Dict[str, Any]]:
235
+ """
236
+ Extract JSON schema from entity class for state structure documentation.
237
+
238
+ The schema can be provided in multiple ways (in order of preference):
239
+ 1. Explicit _state_schema class attribute (most explicit)
240
+ 2. Docstring with state description
241
+ 3. Type annotations on __init__ method (least explicit, basic types only)
242
+
243
+ Args:
244
+ entity_class: The Entity subclass to extract schema from
245
+
246
+ Returns:
247
+ JSON schema dict or None if no schema could be extracted
248
+
249
+ Examples:
250
+ # Option 1: Explicit schema (recommended)
251
+ class ShoppingCart(Entity):
252
+ _state_schema = {
253
+ "type": "object",
254
+ "properties": {
255
+ "items": {"type": "array", "description": "Cart items"},
256
+ "total": {"type": "number", "description": "Cart total"}
257
+ },
258
+ "description": "Shopping cart state"
259
+ }
260
+
261
+ # Option 2: Docstring
262
+ class ShoppingCart(Entity):
263
+ '''
264
+ Shopping cart entity.
265
+
266
+ State:
267
+ items (list): List of cart items
268
+ total (float): Total cart value
269
+ '''
270
+
271
+ # Option 3: Type hints (basic extraction)
272
+ class ShoppingCart(Entity):
273
+ def __init__(self, key: str):
274
+ super().__init__(key)
275
+ self.items: list = []
276
+ self.total: float = 0.0
277
+ """
278
+ # Option 1: Check for explicit _state_schema attribute
279
+ if hasattr(entity_class, '_state_schema'):
280
+ schema = entity_class._state_schema
281
+ logger.debug(f"Found explicit _state_schema for {entity_class.__name__}")
282
+ return schema
283
+
284
+ # Option 2: Extract from docstring (basic parsing)
285
+ if entity_class.__doc__:
286
+ doc = entity_class.__doc__.strip()
287
+ if "State:" in doc or "state:" in doc.lower():
288
+ # Found state documentation - create basic schema
289
+ logger.debug(f"Found state documentation in docstring for {entity_class.__name__}")
290
+ return {
291
+ "type": "object",
292
+ "description": f"State structure for {entity_class.__name__} (see docstring for details)"
293
+ }
294
+
295
+ # Option 3: Try to extract from __init__ type hints (very basic)
296
+ try:
297
+ init_method = entity_class.__init__
298
+ type_hints = get_type_hints(init_method)
299
+ # Remove 'key' and 'return' from hints
300
+ state_hints = {k: v for k, v in type_hints.items() if k not in ('key', 'return')}
301
+
302
+ if state_hints:
303
+ logger.debug(f"Extracted type hints from __init__ for {entity_class.__name__}")
304
+ properties = {}
305
+ for name, type_hint in state_hints.items():
306
+ # Basic type mapping
307
+ if type_hint == str:
308
+ properties[name] = {"type": "string"}
309
+ elif type_hint == int:
310
+ properties[name] = {"type": "integer"}
311
+ elif type_hint == float:
312
+ properties[name] = {"type": "number"}
313
+ elif type_hint == bool:
314
+ properties[name] = {"type": "boolean"}
315
+ elif type_hint == list or str(type_hint).startswith('list'):
316
+ properties[name] = {"type": "array"}
317
+ elif type_hint == dict or str(type_hint).startswith('dict'):
318
+ properties[name] = {"type": "object"}
319
+ else:
320
+ properties[name] = {"type": "object", "description": str(type_hint)}
321
+
322
+ if properties:
323
+ return {
324
+ "type": "object",
325
+ "properties": properties,
326
+ "description": f"State structure inferred from type hints for {entity_class.__name__}"
327
+ }
328
+ except Exception as e:
329
+ logger.debug(f"Could not extract type hints from {entity_class.__name__}: {e}")
330
+
331
+ # No schema could be extracted
332
+ logger.debug(f"No state schema found for {entity_class.__name__}")
333
+ return None
334
+
335
+
233
336
  class EntityRegistry:
234
337
  """Registry for entity types."""
235
338
 
@@ -262,7 +365,7 @@ class EntityType:
262
365
  """
263
366
  Metadata about an Entity class.
264
367
 
265
- Stores entity name, method schemas, and metadata for Worker auto-discovery
368
+ Stores entity name, method schemas, state schema, and metadata for Worker auto-discovery
266
369
  and platform integration. Created automatically when Entity subclasses are defined.
267
370
  """
268
371
 
@@ -278,8 +381,50 @@ class EntityType:
278
381
  self.entity_class = entity_class
279
382
  self._method_schemas: Dict[str, Tuple[Optional[Dict[str, Any]], Optional[Dict[str, Any]]]] = {}
280
383
  self._method_metadata: Dict[str, Dict[str, str]] = {}
384
+ self._state_schema: Optional[Dict[str, Any]] = None
281
385
  logger.debug("Created entity type: %s", name)
282
386
 
387
+ def set_state_schema(self, schema: Optional[Dict[str, Any]]) -> None:
388
+ """
389
+ Set the state schema for this entity type.
390
+
391
+ Args:
392
+ schema: JSON schema describing the entity's state structure
393
+ """
394
+ self._state_schema = schema
395
+ if schema:
396
+ logger.debug(f"Set state schema for {self.name}")
397
+
398
+ def build_entity_definition(self) -> Dict[str, Any]:
399
+ """
400
+ Build complete entity definition for platform registration.
401
+
402
+ Returns:
403
+ Dictionary with entity name, state schema, and method schemas
404
+ """
405
+ # Build method schemas dict
406
+ method_schemas = {}
407
+ for method_name, (input_schema, output_schema) in self._method_schemas.items():
408
+ method_metadata = self._method_metadata.get(method_name, {})
409
+ method_schemas[method_name] = {
410
+ "input_schema": input_schema,
411
+ "output_schema": output_schema,
412
+ "description": method_metadata.get("description", ""),
413
+ "metadata": method_metadata
414
+ }
415
+
416
+ # Build complete definition
417
+ definition = {
418
+ "entity_name": self.name,
419
+ "methods": method_schemas
420
+ }
421
+
422
+ # Add state schema if available
423
+ if self._state_schema:
424
+ definition["state_schema"] = self._state_schema
425
+
426
+ return definition
427
+
283
428
 
284
429
  # ============================================================================
285
430
  # Class-Based Entity API (Cloudflare Durable Objects style)
@@ -507,9 +652,10 @@ class Entity:
507
652
  Auto-register Entity subclasses and wrap methods.
508
653
 
509
654
  This is called automatically when a class inherits from Entity.
510
- It performs two tasks:
511
- 1. Wraps all public async methods with single-writer consistency
512
- 2. Registers the entity type with metadata for platform discovery
655
+ It performs three tasks:
656
+ 1. Extracts state schema from the class
657
+ 2. Wraps all public async methods with single-writer consistency
658
+ 3. Registers the entity type with metadata for platform discovery
513
659
  """
514
660
  super().__init_subclass__(**kwargs)
515
661
 
@@ -524,6 +670,12 @@ class Entity:
524
670
  # Create an EntityType for this class, storing the class reference
525
671
  entity_type = EntityType(cls.__name__, entity_class=cls)
526
672
 
673
+ # Extract and set state schema
674
+ state_schema = extract_state_schema(cls)
675
+ if state_schema:
676
+ entity_type.set_state_schema(state_schema)
677
+ logger.debug(f"Extracted state schema for {cls.__name__}")
678
+
527
679
  # Wrap all public async methods and register them
528
680
  for name, method in inspect.getmembers(cls, predicate=inspect.iscoroutinefunction):
529
681
  if not name.startswith('_'):
agnt5/worker.py CHANGED
@@ -484,18 +484,13 @@ class Worker:
484
484
  logger.warning(f"Entity '{entity_class.__name__}' not found in EntityRegistry")
485
485
  continue
486
486
 
487
- method_schemas = {}
488
- for method_name, (input_schema, output_schema) in entity_type._method_schemas.items():
489
- method_metadata = entity_type._method_metadata.get(method_name, {})
490
- method_schemas[method_name] = {
491
- "input_schema": input_schema,
492
- "output_schema": output_schema,
493
- "metadata": method_metadata
494
- }
487
+ # Build complete entity definition with state schema and method schemas
488
+ entity_definition = entity_type.build_entity_definition()
489
+ definition_str = json.dumps(entity_definition)
495
490
 
491
+ # Keep minimal metadata for backward compatibility
496
492
  metadata_dict = {
497
493
  "methods": json.dumps(list(entity_type._method_schemas.keys())),
498
- "method_schemas": json.dumps(method_schemas)
499
494
  }
500
495
 
501
496
  component_info = self._PyComponentInfo(
@@ -503,14 +498,21 @@ class Worker:
503
498
  component_type="entity",
504
499
  metadata=metadata_dict,
505
500
  config={},
506
- input_schema=None,
501
+ input_schema=None, # Entities don't have single input/output schemas
507
502
  output_schema=None,
508
- definition=None,
503
+ definition=definition_str, # Complete entity definition with state and methods
509
504
  )
510
505
  components.append(component_info)
506
+ logger.debug(f"Registered entity '{entity_type.name}' with definition")
511
507
 
512
508
  # Process agents
509
+ from .agent import AgentRegistry
510
+
513
511
  for agent in self._explicit_components['agents']:
512
+ # Register agent in AgentRegistry for execution lookup
513
+ AgentRegistry.register(agent)
514
+ logger.debug(f"Registered agent '{agent.name}' in AgentRegistry for execution")
515
+
514
516
  input_schema_str = json.dumps(agent.input_schema) if hasattr(agent, 'input_schema') and agent.input_schema else None
515
517
  output_schema_str = json.dumps(agent.output_schema) if hasattr(agent, 'output_schema') and agent.output_schema else None
516
518
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agnt5
3
- Version: 0.2.6
3
+ Version: 0.2.8a1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,15 +1,15 @@
1
- agnt5-0.2.6.dist-info/METADATA,sha256=VoL7dDFb9P5ojrU2jUC4r3_qFDea7idhZEJNOUKVdyY,994
2
- agnt5-0.2.6.dist-info/WHEEL,sha256=vpqC0tRn_8bTHidvtrPbrnFQPZnrhuKzsjDdeKwCd58,102
3
- agnt5/__init__.py,sha256=NAziyM0ZKahdzqAP2edFHTbVHYVdIjEGXm0oEHdmiuo,2011
1
+ agnt5-0.2.8a1.dist-info/METADATA,sha256=Qfmo_iWziCmMnenHYNKS9y6kPZE1xrAsXMUHQFzDvo4,996
2
+ agnt5-0.2.8a1.dist-info/WHEEL,sha256=vpqC0tRn_8bTHidvtrPbrnFQPZnrhuKzsjDdeKwCd58,102
3
+ agnt5/__init__.py,sha256=Cscbhye6pA8Jp-sKBGfP4kYXElUdF6aOSHVf-7ph4Dg,2045
4
4
  agnt5/_compat.py,sha256=BGuy3v5VDOHVa5f3Z-C22iMN19lAt0mPmXwF3qSSWxI,369
5
- agnt5/_core.abi3.so,sha256=5nl1dY6TIBSVkfyWKayn0q21kS_pnYOLLehBjEiBSCk,11945360
5
+ agnt5/_core.abi3.so,sha256=rHU0ct25UO6rVguUM79qPt60O_r3P_6qLzz9ADZhYMI,11970304
6
6
  agnt5/_retry_utils.py,sha256=loHsWY5BR4wZy57IzcDEjQAy88DHVwVIr25Cn1d9GPA,5801
7
7
  agnt5/_schema_utils.py,sha256=MR67RW757T4Oq2Jqf4kB61H_b51zwaf3CLWELnkngRo,9572
8
8
  agnt5/_telemetry.py,sha256=bIY9AvBRjJBTHoBPbfR6X1OgaiUf-T0vCoi0_snsWXA,5957
9
- agnt5/agent.py,sha256=I4KqlW02ssRZ3js2lxhQR7_kqhV60GHFqxje88cWhM4,28837
9
+ agnt5/agent.py,sha256=cz9gDB6c-eRJhBihEIuvTnNBwonpH6G8lbm44j_DKgA,36704
10
10
  agnt5/client.py,sha256=kXksazgxdVXWaG9OkjJA4cWruNtcS-ENhtnkrIdw-Nk,23212
11
11
  agnt5/context.py,sha256=S2OzPkhn_jnqSWfT21mSYOux8vHaLKQxcAvggZDHQek,2378
12
- agnt5/entity.py,sha256=dhdxXUxED79u3OlX9yw-2TLCC9VqBcJqES2kx-fDChs,19041
12
+ agnt5/entity.py,sha256=jMnSRTv6MNlK05cJ0FWYQR89ZTz_ywtVuwv-Sjr2Jfc,24925
13
13
  agnt5/exceptions.py,sha256=mZ0q-NK6OKhYxgwBJpIbgpgzk-CJaFIHDbp1EE-pS7I,925
14
14
  agnt5/function.py,sha256=f1vaAlJRwuo8cxCOGEd8XPido00mOhlPS8UJJx-6hJI,11041
15
15
  agnt5/lm.py,sha256=9dFjd6eQ3f3lFZe7H7rWZherYiP_58MT1F5xpwD8PCg,23195
@@ -17,6 +17,6 @@ agnt5/tool.py,sha256=uc4L-Q9QyLzQDe-MZKk2Wo3o5e-mK8tfaQwVDgQdouQ,13133
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=GWskOXOmho_HZdhwAhimIWDHfT809Y3h1W_8s8UKt-w,46244
20
+ agnt5/worker.py,sha256=fWC_N2yP5BlE0W7p0MXFfnQH5OBMU94lyEuImOhBwQI,46470
21
21
  agnt5/workflow.py,sha256=sU8Gk7unxE_Gla7Fe-KlXfcBvYa2326GciuoR26CCr0,19585
22
- agnt5-0.2.6.dist-info/RECORD,,
22
+ agnt5-0.2.8a1.dist-info/RECORD,,
File without changes