pygeai-orchestration 0.1.0b2__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.
Files changed (61) hide show
  1. pygeai_orchestration/__init__.py +99 -0
  2. pygeai_orchestration/cli/__init__.py +7 -0
  3. pygeai_orchestration/cli/__main__.py +11 -0
  4. pygeai_orchestration/cli/commands/__init__.py +13 -0
  5. pygeai_orchestration/cli/commands/base.py +192 -0
  6. pygeai_orchestration/cli/error_handler.py +123 -0
  7. pygeai_orchestration/cli/formatters.py +419 -0
  8. pygeai_orchestration/cli/geai_orch.py +270 -0
  9. pygeai_orchestration/cli/interactive.py +265 -0
  10. pygeai_orchestration/cli/texts/help.py +169 -0
  11. pygeai_orchestration/core/__init__.py +130 -0
  12. pygeai_orchestration/core/base/__init__.py +23 -0
  13. pygeai_orchestration/core/base/agent.py +121 -0
  14. pygeai_orchestration/core/base/geai_agent.py +144 -0
  15. pygeai_orchestration/core/base/geai_orchestrator.py +77 -0
  16. pygeai_orchestration/core/base/orchestrator.py +142 -0
  17. pygeai_orchestration/core/base/pattern.py +161 -0
  18. pygeai_orchestration/core/base/tool.py +149 -0
  19. pygeai_orchestration/core/common/__init__.py +18 -0
  20. pygeai_orchestration/core/common/context.py +140 -0
  21. pygeai_orchestration/core/common/memory.py +176 -0
  22. pygeai_orchestration/core/common/message.py +50 -0
  23. pygeai_orchestration/core/common/state.py +181 -0
  24. pygeai_orchestration/core/composition.py +190 -0
  25. pygeai_orchestration/core/config.py +356 -0
  26. pygeai_orchestration/core/exceptions.py +400 -0
  27. pygeai_orchestration/core/handlers.py +380 -0
  28. pygeai_orchestration/core/utils/__init__.py +37 -0
  29. pygeai_orchestration/core/utils/cache.py +138 -0
  30. pygeai_orchestration/core/utils/config.py +94 -0
  31. pygeai_orchestration/core/utils/logging.py +57 -0
  32. pygeai_orchestration/core/utils/metrics.py +184 -0
  33. pygeai_orchestration/core/utils/validators.py +140 -0
  34. pygeai_orchestration/dev/__init__.py +15 -0
  35. pygeai_orchestration/dev/debug.py +288 -0
  36. pygeai_orchestration/dev/templates.py +321 -0
  37. pygeai_orchestration/dev/testing.py +301 -0
  38. pygeai_orchestration/patterns/__init__.py +15 -0
  39. pygeai_orchestration/patterns/multi_agent.py +237 -0
  40. pygeai_orchestration/patterns/planning.py +219 -0
  41. pygeai_orchestration/patterns/react.py +221 -0
  42. pygeai_orchestration/patterns/reflection.py +134 -0
  43. pygeai_orchestration/patterns/tool_use.py +170 -0
  44. pygeai_orchestration/tests/__init__.py +1 -0
  45. pygeai_orchestration/tests/test_base_classes.py +187 -0
  46. pygeai_orchestration/tests/test_cache.py +184 -0
  47. pygeai_orchestration/tests/test_cli_formatters.py +232 -0
  48. pygeai_orchestration/tests/test_common.py +214 -0
  49. pygeai_orchestration/tests/test_composition.py +265 -0
  50. pygeai_orchestration/tests/test_config.py +301 -0
  51. pygeai_orchestration/tests/test_dev_utils.py +337 -0
  52. pygeai_orchestration/tests/test_exceptions.py +327 -0
  53. pygeai_orchestration/tests/test_handlers.py +307 -0
  54. pygeai_orchestration/tests/test_metrics.py +171 -0
  55. pygeai_orchestration/tests/test_patterns.py +165 -0
  56. pygeai_orchestration-0.1.0b2.dist-info/METADATA +290 -0
  57. pygeai_orchestration-0.1.0b2.dist-info/RECORD +61 -0
  58. pygeai_orchestration-0.1.0b2.dist-info/WHEEL +5 -0
  59. pygeai_orchestration-0.1.0b2.dist-info/entry_points.txt +2 -0
  60. pygeai_orchestration-0.1.0b2.dist-info/licenses/LICENSE +8 -0
  61. pygeai_orchestration-0.1.0b2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,140 @@
1
+ """
2
+ Execution context management for orchestration patterns.
3
+
4
+ This module provides context storage for pattern execution, enabling
5
+ sharing of data, configuration, and state across components.
6
+ """
7
+
8
+ from typing import Any, Dict, Optional
9
+ from pydantic import BaseModel, Field
10
+ from datetime import datetime
11
+
12
+
13
+ class Context(BaseModel):
14
+ """
15
+ Execution context for pattern and agent operations.
16
+
17
+ This Pydantic model provides a simple key-value store for sharing
18
+ data, configuration, and temporary state during execution.
19
+
20
+ :param data: Dict[str, Any] - Context data storage.
21
+ :param created_at: datetime - Timestamp when context was created.
22
+ :param updated_at: datetime - Timestamp of last update.
23
+ """
24
+
25
+ data: Dict[str, Any] = Field(default_factory=dict)
26
+ created_at: datetime = Field(default_factory=datetime.utcnow)
27
+ updated_at: datetime = Field(default_factory=datetime.utcnow)
28
+
29
+ def set(self, key: str, value: Any) -> None:
30
+ """
31
+ Set a context value and update timestamp.
32
+
33
+ :param key: str - Context key.
34
+ :param value: Any - Value to store.
35
+ """
36
+ self.data[key] = value
37
+ self.updated_at = datetime.utcnow()
38
+
39
+ def get(self, key: str, default: Any = None) -> Any:
40
+ """
41
+ Get a context value with optional default.
42
+
43
+ :param key: str - Context key.
44
+ :param default: Any - Default value if key not found.
45
+ :return: Any - Stored value or default.
46
+ """
47
+ return self.data.get(key, default)
48
+
49
+ def has(self, key: str) -> bool:
50
+ """
51
+ Check if a key exists in context.
52
+
53
+ :param key: str - Context key.
54
+ :return: bool - True if key exists, False otherwise.
55
+ """
56
+ return key in self.data
57
+
58
+ def remove(self, key: str) -> None:
59
+ """
60
+ Remove a key from context and update timestamp.
61
+
62
+ :param key: str - Context key to remove.
63
+ """
64
+ if key in self.data:
65
+ del self.data[key]
66
+ self.updated_at = datetime.utcnow()
67
+
68
+ def update(self, data: Dict[str, Any]) -> None:
69
+ """
70
+ Merge data into context and update timestamp.
71
+
72
+ :param data: Dict[str, Any] - Data to merge into context.
73
+ """
74
+ self.data.update(data)
75
+ self.updated_at = datetime.utcnow()
76
+
77
+ def clear(self) -> None:
78
+ """Clear all context data and update timestamp."""
79
+ self.data.clear()
80
+ self.updated_at = datetime.utcnow()
81
+
82
+ class Config:
83
+ json_encoders = {datetime: lambda v: v.isoformat()}
84
+
85
+
86
+ class ContextManager:
87
+ """
88
+ Manager for multiple execution contexts.
89
+
90
+ Provides centralized management of multiple context instances,
91
+ enabling isolated execution environments for different patterns or agents.
92
+ """
93
+
94
+ def __init__(self):
95
+ """Initialize the context manager with empty context registry."""
96
+ self._contexts: Dict[str, Context] = {}
97
+
98
+ def create_context(
99
+ self, context_id: str, initial_data: Optional[Dict[str, Any]] = None
100
+ ) -> Context:
101
+ """
102
+ Create and register a new context.
103
+
104
+ :param context_id: str - Unique identifier for the context.
105
+ :param initial_data: Optional[Dict[str, Any]] - Initial data for the context.
106
+ :return: Context - The newly created context instance.
107
+ """
108
+ context = Context(data=initial_data or {})
109
+ self._contexts[context_id] = context
110
+ return context
111
+
112
+ def get_context(self, context_id: str) -> Optional[Context]:
113
+ """
114
+ Retrieve a context by ID.
115
+
116
+ :param context_id: str - Context identifier.
117
+ :return: Optional[Context] - The context if found, None otherwise.
118
+ """
119
+ return self._contexts.get(context_id)
120
+
121
+ def delete_context(self, context_id: str) -> None:
122
+ """
123
+ Delete a context by ID.
124
+
125
+ :param context_id: str - Context identifier to delete.
126
+ """
127
+ if context_id in self._contexts:
128
+ del self._contexts[context_id]
129
+
130
+ def list_contexts(self) -> list:
131
+ """
132
+ List all registered context IDs.
133
+
134
+ :return: list - List of context identifiers.
135
+ """
136
+ return list(self._contexts.keys())
137
+
138
+ def clear_all(self) -> None:
139
+ """Clear all registered contexts."""
140
+ self._contexts.clear()
@@ -0,0 +1,176 @@
1
+ """
2
+ Memory management for orchestration patterns.
3
+
4
+ This module provides short-term and long-term memory capabilities for agents
5
+ and patterns, including key-value storage, access tracking, and eviction policies.
6
+ """
7
+
8
+ from typing import Any, Dict, List, Optional
9
+ from pydantic import BaseModel, Field
10
+ from datetime import datetime
11
+
12
+
13
+ class MemoryEntry(BaseModel):
14
+ """
15
+ Single memory entry with metadata and access tracking.
16
+
17
+ This Pydantic model represents an individual piece of stored information
18
+ with timestamp, access count, and custom metadata.
19
+
20
+ :param key: str - Unique identifier for this entry.
21
+ :param value: Any - The stored value.
22
+ :param timestamp: datetime - When this entry was created.
23
+ :param access_count: int - Number of times this entry has been accessed.
24
+ :param metadata: Dict[str, Any] - Custom metadata for this entry.
25
+ """
26
+
27
+ key: str = Field(..., description="Memory entry key")
28
+ value: Any = Field(..., description="Memory entry value")
29
+ timestamp: datetime = Field(default_factory=datetime.utcnow)
30
+ access_count: int = Field(0, ge=0)
31
+ metadata: Dict[str, Any] = Field(default_factory=dict)
32
+
33
+ class Config:
34
+ json_encoders = {datetime: lambda v: v.isoformat()}
35
+
36
+
37
+ class Memory(BaseModel):
38
+ """
39
+ Memory storage with size limits and eviction.
40
+
41
+ This Pydantic model provides a bounded key-value store with automatic
42
+ eviction of oldest entries when capacity is reached.
43
+
44
+ :param entries: Dict[str, MemoryEntry] - Stored memory entries.
45
+ :param max_size: Optional[int] - Maximum number of entries. None means unlimited.
46
+ """
47
+
48
+ entries: Dict[str, MemoryEntry] = Field(default_factory=dict)
49
+ max_size: Optional[int] = Field(None, ge=1, description="Maximum number of entries")
50
+
51
+ def store(self, key: str, value: Any, metadata: Optional[Dict[str, Any]] = None) -> None:
52
+ """
53
+ Store a value in memory, evicting oldest if at capacity.
54
+
55
+ :param key: str - Entry key.
56
+ :param value: Any - Value to store.
57
+ :param metadata: Optional[Dict[str, Any]] - Custom metadata for this entry.
58
+ """
59
+ if self.max_size and len(self.entries) >= self.max_size and key not in self.entries:
60
+ oldest_key = min(self.entries.keys(), key=lambda k: self.entries[k].timestamp)
61
+ del self.entries[oldest_key]
62
+
63
+ self.entries[key] = MemoryEntry(key=key, value=value, metadata=metadata or {})
64
+
65
+ def retrieve(self, key: str) -> Optional[Any]:
66
+ """
67
+ Retrieve a value and increment access count.
68
+
69
+ :param key: str - Entry key.
70
+ :return: Optional[Any] - Stored value if found, None otherwise.
71
+ """
72
+ entry = self.entries.get(key)
73
+ if entry:
74
+ entry.access_count += 1
75
+ return entry.value
76
+ return None
77
+
78
+ def has(self, key: str) -> bool:
79
+ """
80
+ Check if a key exists in memory.
81
+
82
+ :param key: str - Entry key.
83
+ :return: bool - True if key exists, False otherwise.
84
+ """
85
+ return key in self.entries
86
+
87
+ def remove(self, key: str) -> None:
88
+ """
89
+ Remove an entry from memory.
90
+
91
+ :param key: str - Entry key to remove.
92
+ """
93
+ if key in self.entries:
94
+ del self.entries[key]
95
+
96
+ def clear(self) -> None:
97
+ """Clear all entries from memory."""
98
+ self.entries.clear()
99
+
100
+ def size(self) -> int:
101
+ """
102
+ Get the current number of entries.
103
+
104
+ :return: int - Number of stored entries.
105
+ """
106
+ return len(self.entries)
107
+
108
+ def get_recent(self, limit: int = 10) -> List[MemoryEntry]:
109
+ """
110
+ Get the most recently created entries.
111
+
112
+ :param limit: int - Maximum number of entries to return.
113
+ :return: List[MemoryEntry] - Recent entries sorted by timestamp (newest first).
114
+ """
115
+ sorted_entries = sorted(self.entries.values(), key=lambda e: e.timestamp, reverse=True)
116
+ return sorted_entries[:limit]
117
+
118
+
119
+ class MemoryStore:
120
+ """
121
+ Manager for multiple memory instances.
122
+
123
+ Provides centralized management of multiple memory instances,
124
+ enabling separate memory spaces for different agents or contexts.
125
+ """
126
+
127
+ def __init__(self, max_size: Optional[int] = None):
128
+ """
129
+ Initialize the memory store.
130
+
131
+ :param max_size: Optional[int] - Default max size for created memories.
132
+ """
133
+ self._memories: Dict[str, Memory] = {}
134
+ self._max_size = max_size
135
+
136
+ def create_memory(self, memory_id: str, max_size: Optional[int] = None) -> Memory:
137
+ """
138
+ Create and register a new memory instance.
139
+
140
+ :param memory_id: str - Unique identifier for the memory.
141
+ :param max_size: Optional[int] - Max size for this memory (overrides default).
142
+ :return: Memory - The newly created memory instance.
143
+ """
144
+ memory = Memory(max_size=max_size or self._max_size)
145
+ self._memories[memory_id] = memory
146
+ return memory
147
+
148
+ def get_memory(self, memory_id: str) -> Optional[Memory]:
149
+ """
150
+ Retrieve a memory instance by ID.
151
+
152
+ :param memory_id: str - Memory identifier.
153
+ :return: Optional[Memory] - The memory if found, None otherwise.
154
+ """
155
+ return self._memories.get(memory_id)
156
+
157
+ def delete_memory(self, memory_id: str) -> None:
158
+ """
159
+ Delete a memory instance.
160
+
161
+ :param memory_id: str - Memory identifier to delete.
162
+ """
163
+ if memory_id in self._memories:
164
+ del self._memories[memory_id]
165
+
166
+ def list_memories(self) -> list:
167
+ """
168
+ List all registered memory IDs.
169
+
170
+ :return: list - List of memory identifiers.
171
+ """
172
+ return list(self._memories.keys())
173
+
174
+ def clear_all(self) -> None:
175
+ """Clear all memory instances."""
176
+ self._memories.clear()
@@ -0,0 +1,50 @@
1
+ from typing import Any, Dict, List, Optional
2
+ from pydantic import BaseModel, Field
3
+ from datetime import datetime
4
+ from enum import Enum
5
+
6
+
7
+ class MessageRole(str, Enum):
8
+ SYSTEM = "system"
9
+ USER = "user"
10
+ ASSISTANT = "assistant"
11
+ TOOL = "tool"
12
+
13
+
14
+ class Message(BaseModel):
15
+ role: MessageRole = Field(..., description="Message role")
16
+ content: str = Field(..., description="Message content")
17
+ timestamp: datetime = Field(default_factory=datetime.utcnow)
18
+ metadata: Dict[str, Any] = Field(default_factory=dict)
19
+ tool_calls: Optional[List[Dict[str, Any]]] = None
20
+ tool_results: Optional[List[Dict[str, Any]]] = None
21
+
22
+ class Config:
23
+ json_encoders = {datetime: lambda v: v.isoformat()}
24
+
25
+
26
+ class Conversation(BaseModel):
27
+ id: str = Field(..., description="Conversation ID")
28
+ messages: List[Message] = Field(default_factory=list)
29
+ created_at: datetime = Field(default_factory=datetime.utcnow)
30
+ updated_at: datetime = Field(default_factory=datetime.utcnow)
31
+ metadata: Dict[str, Any] = Field(default_factory=dict)
32
+
33
+ def add_message(self, message: Message) -> None:
34
+ self.messages.append(message)
35
+ self.updated_at = datetime.utcnow()
36
+
37
+ def get_messages(self, role: Optional[MessageRole] = None) -> List[Message]:
38
+ if role is None:
39
+ return self.messages.copy()
40
+ return [msg for msg in self.messages if msg.role == role]
41
+
42
+ def clear(self) -> None:
43
+ self.messages.clear()
44
+ self.updated_at = datetime.utcnow()
45
+
46
+ def to_dict_list(self) -> List[Dict[str, Any]]:
47
+ return [{"role": msg.role.value, "content": msg.content} for msg in self.messages]
48
+
49
+ class Config:
50
+ json_encoders = {datetime: lambda v: v.isoformat()}
@@ -0,0 +1,181 @@
1
+ """
2
+ State management for orchestration patterns.
3
+
4
+ This module provides state tracking and checkpoint functionality for
5
+ pattern execution, enabling pause/resume and state recovery.
6
+ """
7
+
8
+ from typing import Any, Dict, Optional
9
+ from pydantic import BaseModel, Field
10
+ from datetime import datetime
11
+ from enum import Enum
12
+
13
+
14
+ class StateStatus(str, Enum):
15
+ """
16
+ Enumeration of execution state statuses.
17
+
18
+ Tracks the lifecycle of pattern execution:
19
+ - INITIALIZED: State created, not yet started
20
+ - RUNNING: Actively executing
21
+ - PAUSED: Execution temporarily suspended
22
+ - COMPLETED: Successfully finished
23
+ - FAILED: Execution failed with error
24
+ """
25
+
26
+ INITIALIZED = "initialized"
27
+ RUNNING = "running"
28
+ PAUSED = "paused"
29
+ COMPLETED = "completed"
30
+ FAILED = "failed"
31
+
32
+
33
+ class State(BaseModel):
34
+ """
35
+ State model for tracking pattern execution state.
36
+
37
+ This Pydantic model maintains execution status, data, checkpoints,
38
+ and timestamps for pattern lifecycle management.
39
+
40
+ :param status: StateStatus - Current execution status.
41
+ :param data: Dict[str, Any] - Arbitrary state data storage.
42
+ :param checkpoint: Optional[Dict[str, Any]] - Saved checkpoint for recovery.
43
+ :param created_at: datetime - Timestamp when state was created.
44
+ :param updated_at: datetime - Timestamp of last update.
45
+ """
46
+
47
+ status: StateStatus = Field(StateStatus.INITIALIZED, description="Current state status")
48
+ data: Dict[str, Any] = Field(default_factory=dict)
49
+ checkpoint: Optional[Dict[str, Any]] = None
50
+ created_at: datetime = Field(default_factory=datetime.utcnow)
51
+ updated_at: datetime = Field(default_factory=datetime.utcnow)
52
+
53
+ def update_status(self, status: StateStatus) -> None:
54
+ """
55
+ Update the execution status and timestamp.
56
+
57
+ :param status: StateStatus - New status to set.
58
+ """
59
+ self.status = status
60
+ self.updated_at = datetime.utcnow()
61
+
62
+ def set(self, key: str, value: Any) -> None:
63
+ """
64
+ Set a data value and update timestamp.
65
+
66
+ :param key: str - Data key.
67
+ :param value: Any - Value to store.
68
+ """
69
+ self.data[key] = value
70
+ self.updated_at = datetime.utcnow()
71
+
72
+ def get(self, key: str, default: Any = None) -> Any:
73
+ """
74
+ Get a data value with optional default.
75
+
76
+ :param key: str - Data key.
77
+ :param default: Any - Default value if key not found.
78
+ :return: Any - Stored value or default.
79
+ """
80
+ return self.data.get(key, default)
81
+
82
+ def create_checkpoint(self) -> None:
83
+ """
84
+ Create a checkpoint snapshot of current state.
85
+
86
+ Captures status, data, and timestamp for later restoration.
87
+ """
88
+ self.checkpoint = {
89
+ "status": self.status.value,
90
+ "data": self.data.copy(),
91
+ "timestamp": datetime.utcnow().isoformat(),
92
+ }
93
+
94
+ def restore_checkpoint(self) -> bool:
95
+ """
96
+ Restore state from the most recent checkpoint.
97
+
98
+ :return: bool - True if restored successfully, False if no checkpoint exists.
99
+ """
100
+ if self.checkpoint is None:
101
+ return False
102
+ self.status = StateStatus(self.checkpoint["status"])
103
+ self.data = self.checkpoint["data"].copy()
104
+ self.updated_at = datetime.utcnow()
105
+ return True
106
+
107
+ class Config:
108
+ json_encoders = {datetime: lambda v: v.isoformat()}
109
+
110
+
111
+ class StateManager:
112
+ """
113
+ Manager for multiple pattern execution states.
114
+
115
+ Provides centralized management of multiple state instances,
116
+ enabling orchestration of concurrent pattern executions.
117
+ """
118
+
119
+ def __init__(self):
120
+ """Initialize the state manager with empty state registry."""
121
+ self._states: Dict[str, State] = {}
122
+
123
+ def create_state(self, state_id: str, initial_data: Optional[Dict[str, Any]] = None) -> State:
124
+ """
125
+ Create and register a new state.
126
+
127
+ :param state_id: str - Unique identifier for the state.
128
+ :param initial_data: Optional[Dict[str, Any]] - Initial data for the state.
129
+ :return: State - The newly created state instance.
130
+ """
131
+ state = State(data=initial_data or {})
132
+ self._states[state_id] = state
133
+ return state
134
+
135
+ def get_state(self, state_id: str) -> Optional[State]:
136
+ """
137
+ Retrieve a state by ID.
138
+
139
+ :param state_id: str - State identifier.
140
+ :return: Optional[State] - The state if found, None otherwise.
141
+ """
142
+ return self._states.get(state_id)
143
+
144
+ def update_state(
145
+ self, state_id: str, status: StateStatus, data: Optional[Dict[str, Any]] = None
146
+ ) -> bool:
147
+ """
148
+ Update an existing state's status and data.
149
+
150
+ :param state_id: str - State identifier.
151
+ :param status: StateStatus - New status to set.
152
+ :param data: Optional[Dict[str, Any]] - Data to merge into state.
153
+ :return: bool - True if updated, False if state not found.
154
+ """
155
+ state = self._states.get(state_id)
156
+ if state is None:
157
+ return False
158
+ state.update_status(status)
159
+ if data:
160
+ state.data.update(data)
161
+ return True
162
+
163
+ def delete_state(self, state_id: str) -> None:
164
+ """
165
+ Delete a state by ID.
166
+
167
+ :param state_id: str - State identifier to delete.
168
+ """
169
+ if state_id in self._states:
170
+ del self._states[state_id]
171
+
172
+ def list_states(self) -> list:
173
+ """
174
+ List all registered state IDs.
175
+
176
+ :return: list - List of state identifiers.
177
+ """
178
+ return list(self._states.keys())
179
+
180
+ def clear_all(self) -> None:
181
+ self._states.clear()