|
45 | 45 | from .tools.base import BaseTool, ToolResult, ToolValidationError, validate_tool |
46 | 46 | from .tools.decorator import tool, FunctionTool |
47 | 47 | from .tools.registry import get_registry, register_tool, get_tool, ToolRegistry |
48 | | -from .db import db |
49 | | -from .obs import obs |
| 48 | +# db and obs are lazy-loaded via __getattr__ for performance |
50 | 49 |
|
51 | 50 | # Sub-packages for organized imports (pa.config, pa.tools, etc.) |
52 | 51 | # These enable: import praisonaiagents as pa; pa.config.MemoryConfig |
53 | 52 | from . import config |
54 | 53 | from . import tools |
55 | | -from . import memory |
56 | | -from . import workflows |
57 | | -# Note: knowledge and mcp are lazy-loaded via __getattr__ due to heavy deps |
58 | | - |
59 | | -# Embedding API - explicit import shadows subpackage, enabling: |
60 | | -# from praisonaiagents import embedding, embeddings, EmbeddingResult, get_dimensions |
61 | | -# Note: litellm is still lazy-loaded INSIDE the functions (no performance impact) |
62 | | -from .embedding.embed import embedding, aembedding |
63 | | -from .embedding.result import EmbeddingResult |
64 | | -from .embedding.dimensions import get_dimensions |
65 | | -embeddings = embedding # Plural alias (OpenAI style: client.embeddings.create) |
66 | | -aembeddings = aembedding # Plural alias for async |
67 | | - |
68 | | -# Workflows - lightweight module |
69 | | -from .workflows import ( |
70 | | - Workflow, WorkflowStep, WorkflowContext, StepResult, |
71 | | - Route, Parallel, Loop, Repeat, |
72 | | - route, parallel, loop, repeat, |
73 | | - Pipeline # Alias for Workflow |
74 | | -) |
| 54 | +# Note: db, obs, knowledge and mcp are lazy-loaded via __getattr__ due to heavy deps |
| 55 | + |
| 56 | +# Embedding API - LAZY LOADED via __getattr__ for performance |
| 57 | +# Supports: embedding, embeddings, aembedding, aembeddings, EmbeddingResult, get_dimensions |
| 58 | + |
| 59 | +# Workflows - LAZY LOADED (moved to __getattr__) |
| 60 | +# Workflow, WorkflowStep, WorkflowContext, StepResult, Route, Parallel, Loop, Repeat, etc. |
| 61 | + |
75 | 62 | # Guardrails - LAZY LOADED (imports main.py which imports rich) |
76 | 63 | # GuardrailResult and LLMGuardrail moved to __getattr__ |
77 | 64 |
|
78 | | -# Handoff - lightweight (unified agent-to-agent transfer) |
79 | | -from .agent.handoff import ( |
80 | | - Handoff, handoff, handoff_filters, |
81 | | - RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions, |
82 | | - HandoffConfig, HandoffResult, HandoffInputData, |
83 | | - ContextPolicy, HandoffError, HandoffCycleError, HandoffDepthError, HandoffTimeoutError, |
84 | | -) |
| 65 | +# Handoff - LAZY LOADED (moved to __getattr__) |
| 66 | +# Handoff, handoff, handoff_filters, etc. |
85 | 67 |
|
86 | 68 | # Flow display - LAZY LOADED (moved to __getattr__) |
87 | 69 | # FlowDisplay and track_workflow are now lazy loaded |
@@ -140,6 +122,94 @@ def __getattr__(name): |
140 | 122 | _lazy_cache[name] = value |
141 | 123 | return value |
142 | 124 |
|
| 125 | + # Workflows - lazy loaded for performance |
| 126 | + _workflow_names = { |
| 127 | + 'Workflow', 'WorkflowStep', 'WorkflowContext', 'StepResult', |
| 128 | + 'Route', 'Parallel', 'Loop', 'Repeat', |
| 129 | + 'route', 'parallel', 'loop', 'repeat', 'Pipeline' |
| 130 | + } |
| 131 | + if name in _workflow_names: |
| 132 | + from . import workflows as _workflows_module |
| 133 | + value = getattr(_workflows_module, name) |
| 134 | + _lazy_cache[name] = value |
| 135 | + return value |
| 136 | + |
| 137 | + # Handoff - lazy loaded for performance |
| 138 | + _handoff_names = { |
| 139 | + 'Handoff', 'handoff', 'handoff_filters', |
| 140 | + 'RECOMMENDED_PROMPT_PREFIX', 'prompt_with_handoff_instructions', |
| 141 | + 'HandoffConfig', 'HandoffResult', 'HandoffInputData', |
| 142 | + 'ContextPolicy', 'HandoffError', 'HandoffCycleError', |
| 143 | + 'HandoffDepthError', 'HandoffTimeoutError' |
| 144 | + } |
| 145 | + if name in _handoff_names: |
| 146 | + # Import directly from handoff module to avoid recursion |
| 147 | + from .agent.handoff import ( |
| 148 | + Handoff, handoff, handoff_filters, |
| 149 | + RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions, |
| 150 | + HandoffConfig, HandoffResult, HandoffInputData, |
| 151 | + ContextPolicy, HandoffError, HandoffCycleError, |
| 152 | + HandoffDepthError, HandoffTimeoutError |
| 153 | + ) |
| 154 | + _handoff_exports = { |
| 155 | + 'Handoff': Handoff, 'handoff': handoff, 'handoff_filters': handoff_filters, |
| 156 | + 'RECOMMENDED_PROMPT_PREFIX': RECOMMENDED_PROMPT_PREFIX, |
| 157 | + 'prompt_with_handoff_instructions': prompt_with_handoff_instructions, |
| 158 | + 'HandoffConfig': HandoffConfig, 'HandoffResult': HandoffResult, |
| 159 | + 'HandoffInputData': HandoffInputData, 'ContextPolicy': ContextPolicy, |
| 160 | + 'HandoffError': HandoffError, 'HandoffCycleError': HandoffCycleError, |
| 161 | + 'HandoffDepthError': HandoffDepthError, 'HandoffTimeoutError': HandoffTimeoutError |
| 162 | + } |
| 163 | + for k, v in _handoff_exports.items(): |
| 164 | + _lazy_cache[k] = v |
| 165 | + return _handoff_exports[name] |
| 166 | + |
| 167 | + # db and obs - lazy loaded for performance |
| 168 | + if name == 'db': |
| 169 | + from .db import db |
| 170 | + _lazy_cache[name] = db |
| 171 | + return db |
| 172 | + elif name == 'obs': |
| 173 | + from .obs import obs |
| 174 | + _lazy_cache[name] = obs |
| 175 | + return obs |
| 176 | + |
| 177 | + # memory module - lazy loaded for performance |
| 178 | + if name == 'memory': |
| 179 | + import importlib |
| 180 | + _memory_module = importlib.import_module('.memory', __name__) |
| 181 | + _lazy_cache[name] = _memory_module |
| 182 | + return _memory_module |
| 183 | + |
| 184 | + # workflows module - lazy loaded for performance |
| 185 | + if name == 'workflows': |
| 186 | + import importlib |
| 187 | + _workflows_module = importlib.import_module('.workflows', __name__) |
| 188 | + _lazy_cache[name] = _workflows_module |
| 189 | + return _workflows_module |
| 190 | + |
| 191 | + # Embedding API - lazy loaded for performance |
| 192 | + _embedding_names = {'embedding', 'embeddings', 'aembedding', 'aembeddings', 'EmbeddingResult', 'get_dimensions'} |
| 193 | + if name in _embedding_names: |
| 194 | + if name in ('embedding', 'embeddings'): |
| 195 | + from .embedding.embed import embedding |
| 196 | + _lazy_cache['embedding'] = embedding |
| 197 | + _lazy_cache['embeddings'] = embedding |
| 198 | + return embedding |
| 199 | + elif name in ('aembedding', 'aembeddings'): |
| 200 | + from .embedding.embed import aembedding |
| 201 | + _lazy_cache['aembedding'] = aembedding |
| 202 | + _lazy_cache['aembeddings'] = aembedding |
| 203 | + return aembedding |
| 204 | + elif name == 'EmbeddingResult': |
| 205 | + from .embedding.result import EmbeddingResult |
| 206 | + _lazy_cache[name] = EmbeddingResult |
| 207 | + return EmbeddingResult |
| 208 | + elif name == 'get_dimensions': |
| 209 | + from .embedding.dimensions import get_dimensions |
| 210 | + _lazy_cache[name] = get_dimensions |
| 211 | + return get_dimensions |
| 212 | + |
143 | 213 | # Guardrails - lazy loaded to avoid importing main.py which imports rich |
144 | 214 | if name == 'GuardrailResult': |
145 | 215 | from .guardrails import GuardrailResult |
|
0 commit comments