daita-agents 0.2.0__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 (69) hide show
  1. daita/__init__.py +216 -0
  2. daita/agents/__init__.py +33 -0
  3. daita/agents/base.py +743 -0
  4. daita/agents/substrate.py +1141 -0
  5. daita/cli/__init__.py +145 -0
  6. daita/cli/__main__.py +7 -0
  7. daita/cli/ascii_art.py +44 -0
  8. daita/cli/core/__init__.py +0 -0
  9. daita/cli/core/create.py +254 -0
  10. daita/cli/core/deploy.py +473 -0
  11. daita/cli/core/deployments.py +309 -0
  12. daita/cli/core/import_detector.py +219 -0
  13. daita/cli/core/init.py +481 -0
  14. daita/cli/core/logs.py +239 -0
  15. daita/cli/core/managed_deploy.py +709 -0
  16. daita/cli/core/run.py +648 -0
  17. daita/cli/core/status.py +421 -0
  18. daita/cli/core/test.py +239 -0
  19. daita/cli/core/webhooks.py +172 -0
  20. daita/cli/main.py +588 -0
  21. daita/cli/utils.py +541 -0
  22. daita/config/__init__.py +62 -0
  23. daita/config/base.py +159 -0
  24. daita/config/settings.py +184 -0
  25. daita/core/__init__.py +262 -0
  26. daita/core/decision_tracing.py +701 -0
  27. daita/core/exceptions.py +480 -0
  28. daita/core/focus.py +251 -0
  29. daita/core/interfaces.py +76 -0
  30. daita/core/plugin_tracing.py +550 -0
  31. daita/core/relay.py +779 -0
  32. daita/core/reliability.py +381 -0
  33. daita/core/scaling.py +459 -0
  34. daita/core/tools.py +554 -0
  35. daita/core/tracing.py +770 -0
  36. daita/core/workflow.py +1144 -0
  37. daita/display/__init__.py +1 -0
  38. daita/display/console.py +160 -0
  39. daita/execution/__init__.py +58 -0
  40. daita/execution/client.py +856 -0
  41. daita/execution/exceptions.py +92 -0
  42. daita/execution/models.py +317 -0
  43. daita/llm/__init__.py +60 -0
  44. daita/llm/anthropic.py +291 -0
  45. daita/llm/base.py +530 -0
  46. daita/llm/factory.py +101 -0
  47. daita/llm/gemini.py +355 -0
  48. daita/llm/grok.py +219 -0
  49. daita/llm/mock.py +172 -0
  50. daita/llm/openai.py +220 -0
  51. daita/plugins/__init__.py +141 -0
  52. daita/plugins/base.py +37 -0
  53. daita/plugins/base_db.py +167 -0
  54. daita/plugins/elasticsearch.py +849 -0
  55. daita/plugins/mcp.py +481 -0
  56. daita/plugins/mongodb.py +520 -0
  57. daita/plugins/mysql.py +362 -0
  58. daita/plugins/postgresql.py +342 -0
  59. daita/plugins/redis_messaging.py +500 -0
  60. daita/plugins/rest.py +537 -0
  61. daita/plugins/s3.py +770 -0
  62. daita/plugins/slack.py +729 -0
  63. daita/utils/__init__.py +18 -0
  64. daita_agents-0.2.0.dist-info/METADATA +409 -0
  65. daita_agents-0.2.0.dist-info/RECORD +69 -0
  66. daita_agents-0.2.0.dist-info/WHEEL +5 -0
  67. daita_agents-0.2.0.dist-info/entry_points.txt +2 -0
  68. daita_agents-0.2.0.dist-info/licenses/LICENSE +56 -0
  69. daita_agents-0.2.0.dist-info/top_level.txt +1 -0
daita/core/focus.py ADDED
@@ -0,0 +1,251 @@
1
+ """
2
+ Focus parameter handling for Daita Agents.
3
+
4
+ This module provides utilities for applying focus parameters to different data types.
5
+ """
6
+ import logging
7
+ from typing import Any, Optional, Union, List, Dict
8
+
9
+ from .exceptions import ValidationError, InvalidDataError
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ def apply_focus(
14
+ data: Any,
15
+ focus: Optional[Union[List[str], str, Dict[str, Any]]]
16
+ ) -> Any:
17
+ """
18
+ Apply focus parameter to data.
19
+
20
+ Args:
21
+ data: Input data
22
+ focus: Focus specification
23
+
24
+ Returns:
25
+ Focused data
26
+
27
+ Raises:
28
+ ValidationError: If focus configuration is invalid
29
+ InvalidDataError: If data cannot be processed with the given focus
30
+ """
31
+ if focus is None or data is None:
32
+ return data
33
+
34
+ # Validate focus parameter first - this will raise ValidationError for empty strings
35
+ _validate_focus_parameter(focus)
36
+
37
+ try:
38
+ # Handle pandas DataFrame
39
+ if hasattr(data, 'columns'):
40
+ return _apply_dataframe_focus(data, focus)
41
+
42
+ # Handle dictionaries
43
+ elif isinstance(data, dict):
44
+ return _apply_dict_focus(data, focus)
45
+
46
+ # Handle lists of dictionaries
47
+ elif isinstance(data, list) and data and isinstance(data[0], dict):
48
+ return _apply_list_dict_focus(data, focus)
49
+
50
+ # For other data types, check if focus makes sense
51
+ else:
52
+ if isinstance(focus, (list, dict)):
53
+ raise InvalidDataError(
54
+ f"Cannot apply structured focus to {type(data).__name__}. "
55
+ f"Focus requires dict, DataFrame, or list of dicts."
56
+ )
57
+ # For simple string focus on other types, just return original data
58
+ logger.info(f"Focus '{focus}' not applicable to {type(data).__name__}, returning original data")
59
+ return data
60
+
61
+ except (ValidationError, InvalidDataError):
62
+ # Re-raise validation errors
63
+ raise
64
+ except Exception as e:
65
+ # Wrap unexpected errors with context
66
+ raise InvalidDataError(f"Failed to apply focus '{focus}' to {type(data).__name__}: {str(e)}")
67
+
68
+ def _validate_focus_parameter(focus: Union[List[str], str, Dict[str, Any]]) -> None:
69
+ """
70
+ Validate focus parameter format.
71
+
72
+ Args:
73
+ focus: Focus parameter to validate
74
+
75
+ Raises:
76
+ ValidationError: If focus format is invalid
77
+ """
78
+ if isinstance(focus, str):
79
+ # Empty or whitespace-only strings are invalid
80
+ if not focus or not focus.strip():
81
+ raise ValidationError("Focus string cannot be empty or whitespace-only")
82
+
83
+ elif isinstance(focus, list):
84
+ if not focus:
85
+ raise ValidationError("Focus list cannot be empty")
86
+
87
+ # Check all items are strings and not empty
88
+ for i, item in enumerate(focus):
89
+ if not isinstance(item, str):
90
+ raise ValidationError(f"Focus list item {i} must be string, got {type(item).__name__}")
91
+ if not item or not item.strip():
92
+ raise ValidationError(f"Focus list item {i} cannot be empty or whitespace-only")
93
+
94
+ elif isinstance(focus, dict):
95
+ if not focus:
96
+ raise ValidationError("Focus dict cannot be empty")
97
+
98
+ # Validate dict structure
99
+ valid_keys = {'include', 'exclude', 'primary', 'secondary'}
100
+ invalid_keys = set(focus.keys()) - valid_keys
101
+ if invalid_keys:
102
+ raise ValidationError(f"Invalid focus keys: {invalid_keys}. Valid keys: {valid_keys}")
103
+
104
+ # Validate include/exclude values
105
+ for key in ['include', 'exclude', 'primary', 'secondary']:
106
+ if key in focus:
107
+ value = focus[key]
108
+ if isinstance(value, str):
109
+ if not value or not value.strip():
110
+ raise ValidationError(f"Focus '{key}' string cannot be empty or whitespace-only")
111
+ elif isinstance(value, list):
112
+ if not value:
113
+ raise ValidationError(f"Focus '{key}' list cannot be empty")
114
+ for i, item in enumerate(value):
115
+ if not isinstance(item, str):
116
+ raise ValidationError(f"Focus '{key}' list item {i} must be string")
117
+ if not item or not item.strip():
118
+ raise ValidationError(f"Focus '{key}' list item {i} cannot be empty or whitespace-only")
119
+ else:
120
+ raise ValidationError(f"Focus '{key}' must be string or list, got {type(value).__name__}")
121
+
122
+ else:
123
+ raise ValidationError(f"Focus must be string, list, or dict, got {type(focus).__name__}")
124
+
125
+ def _apply_dataframe_focus(data, focus):
126
+ """Apply focus to pandas DataFrame."""
127
+ try:
128
+ available_columns = list(data.columns)
129
+
130
+ if isinstance(focus, list):
131
+ # List of column names
132
+ missing_columns = [col for col in focus if col not in available_columns]
133
+ if missing_columns:
134
+ raise InvalidDataError(f"Columns not found in DataFrame: {missing_columns}")
135
+
136
+ return data[focus]
137
+
138
+ elif isinstance(focus, str):
139
+ # Single column name
140
+ if focus not in available_columns:
141
+ raise InvalidDataError(f"Column '{focus}' not found in DataFrame. Available: {available_columns}")
142
+
143
+ return data[[focus]]
144
+
145
+ elif isinstance(focus, dict):
146
+ # Dictionary-based focus
147
+ if 'include' in focus:
148
+ include_cols = focus['include'] if isinstance(focus['include'], list) else [focus['include']]
149
+ missing_columns = [col for col in include_cols if col not in available_columns]
150
+ if missing_columns:
151
+ raise InvalidDataError(f"Include columns not found: {missing_columns}")
152
+
153
+ result = data[include_cols]
154
+
155
+ # Apply exclusions
156
+ if 'exclude' in focus:
157
+ exclude_cols = focus['exclude'] if isinstance(focus['exclude'], list) else [focus['exclude']]
158
+ # Only exclude columns that actually exist in the result
159
+ exclude_cols = [col for col in exclude_cols if col in result.columns]
160
+ if exclude_cols:
161
+ result = result.drop(columns=exclude_cols)
162
+
163
+ return result
164
+
165
+ # Primary/secondary focus
166
+ elif 'primary' in focus:
167
+ primary_cols = focus['primary'] if isinstance(focus['primary'], list) else [focus['primary']]
168
+ missing_columns = [col for col in primary_cols if col not in available_columns]
169
+ if missing_columns:
170
+ raise InvalidDataError(f"Primary columns not found: {missing_columns}")
171
+
172
+ return data[primary_cols]
173
+
174
+ else:
175
+ raise ValidationError("Dict focus must contain 'include' or 'primary' key")
176
+
177
+ return data
178
+
179
+ except Exception as e:
180
+ if isinstance(e, (ValidationError, InvalidDataError)):
181
+ raise
182
+ raise InvalidDataError(f"DataFrame focus application failed: {str(e)}")
183
+
184
+ def _apply_dict_focus(data, focus):
185
+ """Apply focus to dictionary."""
186
+ try:
187
+ available_keys = list(data.keys())
188
+
189
+ if isinstance(focus, list):
190
+ # List of keys
191
+ missing_keys = [key for key in focus if key not in available_keys]
192
+ if missing_keys:
193
+ raise InvalidDataError(f"Keys not found in dict: {missing_keys}")
194
+
195
+ return {k: data[k] for k in focus}
196
+
197
+ elif isinstance(focus, str):
198
+ # Single key
199
+ if focus not in available_keys:
200
+ raise InvalidDataError(f"Key '{focus}' not found in dict. Available: {available_keys}")
201
+
202
+ return {focus: data[focus]}
203
+
204
+ elif isinstance(focus, dict):
205
+ # Dictionary-based focus
206
+ if 'include' in focus:
207
+ include_keys = focus['include'] if isinstance(focus['include'], list) else [focus['include']]
208
+ missing_keys = [key for key in include_keys if key not in available_keys]
209
+ if missing_keys:
210
+ raise InvalidDataError(f"Include keys not found: {missing_keys}")
211
+
212
+ result = {k: data[k] for k in include_keys}
213
+
214
+ # Apply exclusions
215
+ if 'exclude' in focus:
216
+ exclude_keys = focus['exclude'] if isinstance(focus['exclude'], list) else [focus['exclude']]
217
+ result = {k: v for k, v in result.items() if k not in exclude_keys}
218
+
219
+ return result
220
+
221
+ elif 'primary' in focus:
222
+ primary_keys = focus['primary'] if isinstance(focus['primary'], list) else [focus['primary']]
223
+ missing_keys = [key for key in primary_keys if key not in available_keys]
224
+ if missing_keys:
225
+ raise InvalidDataError(f"Primary keys not found: {missing_keys}")
226
+
227
+ return {k: data[k] for k in primary_keys}
228
+
229
+ else:
230
+ raise ValidationError("Dict focus must contain 'include' or 'primary' key")
231
+
232
+ return data
233
+
234
+ except Exception as e:
235
+ if isinstance(e, (ValidationError, InvalidDataError)):
236
+ raise
237
+ raise InvalidDataError(f"Dictionary focus application failed: {str(e)}")
238
+
239
+ def _apply_list_dict_focus(data, focus):
240
+ """Apply focus to list of dictionaries."""
241
+ if not data:
242
+ return data
243
+
244
+ try:
245
+ # Apply focus to first item to validate, then apply to all
246
+ _apply_dict_focus(data[0], focus)
247
+ return [_apply_dict_focus(item, focus) for item in data]
248
+ except Exception as e:
249
+ if isinstance(e, (ValidationError, InvalidDataError)):
250
+ raise
251
+ raise InvalidDataError(f"List of dicts focus application failed: {str(e)}")
@@ -0,0 +1,76 @@
1
+ """
2
+ Core interfaces for Daita Agents.
3
+
4
+ Defines the essential contracts that components must implement.
5
+ """
6
+ from abc import ABC, abstractmethod
7
+ from typing import Any, Dict, List, Optional, Union
8
+ import pandas as pd
9
+
10
+ class Agent(ABC):
11
+ """Base interface for all agents."""
12
+
13
+ @abstractmethod
14
+ async def _process(
15
+ self,
16
+ task: str,
17
+ data: Any = None,
18
+ context: Optional[Dict[str, Any]] = None,
19
+ **kwargs
20
+ ) -> Dict[str, Any]:
21
+ """INTERNAL: Process a task with data and context."""
22
+ pass
23
+
24
+ @abstractmethod
25
+ async def start(self) -> None:
26
+ """Start the agent."""
27
+ pass
28
+
29
+ @abstractmethod
30
+ async def stop(self) -> None:
31
+ """Stop the agent."""
32
+ pass
33
+
34
+ class LLMProvider(ABC):
35
+ """Interface for language model providers."""
36
+
37
+ @abstractmethod
38
+ async def generate(self, prompt: str, **kwargs) -> str:
39
+ """Generate text from prompt."""
40
+ pass
41
+
42
+ @property
43
+ @abstractmethod
44
+ def info(self) -> Dict[str, Any]:
45
+ """Get information about the LLM provider."""
46
+ pass
47
+
48
+ class DatabaseBackend(ABC):
49
+ """Interface for database operations."""
50
+
51
+ @abstractmethod
52
+ async def connect(self) -> None:
53
+ """Establish database connection."""
54
+ pass
55
+
56
+ @abstractmethod
57
+ async def execute_query(
58
+ self,
59
+ query: str,
60
+ params: Optional[Dict[str, Any]] = None
61
+ ) -> Any:
62
+ """Execute database query."""
63
+ pass
64
+
65
+ class DataProcessor(ABC):
66
+ """Interface for data processing operations."""
67
+
68
+ @abstractmethod
69
+ async def process(
70
+ self,
71
+ data: Union[pd.DataFrame, List[Dict[str, Any]], str, bytes],
72
+ focus: Optional[Union[List[str], str, Dict[str, Any]]] = None,
73
+ **kwargs
74
+ ) -> Union[pd.DataFrame, List[Dict[str, Any]], Dict[str, Any]]:
75
+ """Process data with optional focus parameter."""
76
+ pass