daita-agents 0.1.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.
Potentially problematic release.
This version of daita-agents might be problematic. Click here for more details.
- daita/__init__.py +208 -0
- daita/agents/__init__.py +33 -0
- daita/agents/base.py +722 -0
- daita/agents/substrate.py +895 -0
- daita/cli/__init__.py +145 -0
- daita/cli/__main__.py +7 -0
- daita/cli/ascii_art.py +44 -0
- daita/cli/core/__init__.py +0 -0
- daita/cli/core/create.py +254 -0
- daita/cli/core/deploy.py +473 -0
- daita/cli/core/deployments.py +309 -0
- daita/cli/core/import_detector.py +219 -0
- daita/cli/core/init.py +382 -0
- daita/cli/core/logs.py +239 -0
- daita/cli/core/managed_deploy.py +709 -0
- daita/cli/core/run.py +648 -0
- daita/cli/core/status.py +421 -0
- daita/cli/core/test.py +239 -0
- daita/cli/core/webhooks.py +172 -0
- daita/cli/main.py +588 -0
- daita/cli/utils.py +541 -0
- daita/config/__init__.py +62 -0
- daita/config/base.py +159 -0
- daita/config/settings.py +184 -0
- daita/core/__init__.py +262 -0
- daita/core/decision_tracing.py +701 -0
- daita/core/exceptions.py +480 -0
- daita/core/focus.py +251 -0
- daita/core/interfaces.py +76 -0
- daita/core/plugin_tracing.py +550 -0
- daita/core/relay.py +695 -0
- daita/core/reliability.py +381 -0
- daita/core/scaling.py +444 -0
- daita/core/tools.py +402 -0
- daita/core/tracing.py +770 -0
- daita/core/workflow.py +1084 -0
- daita/display/__init__.py +1 -0
- daita/display/console.py +160 -0
- daita/execution/__init__.py +58 -0
- daita/execution/client.py +856 -0
- daita/execution/exceptions.py +92 -0
- daita/execution/models.py +317 -0
- daita/llm/__init__.py +60 -0
- daita/llm/anthropic.py +166 -0
- daita/llm/base.py +373 -0
- daita/llm/factory.py +101 -0
- daita/llm/gemini.py +152 -0
- daita/llm/grok.py +114 -0
- daita/llm/mock.py +135 -0
- daita/llm/openai.py +109 -0
- daita/plugins/__init__.py +141 -0
- daita/plugins/base.py +37 -0
- daita/plugins/base_db.py +167 -0
- daita/plugins/elasticsearch.py +844 -0
- daita/plugins/mcp.py +481 -0
- daita/plugins/mongodb.py +510 -0
- daita/plugins/mysql.py +351 -0
- daita/plugins/postgresql.py +331 -0
- daita/plugins/redis_messaging.py +500 -0
- daita/plugins/rest.py +529 -0
- daita/plugins/s3.py +761 -0
- daita/plugins/slack.py +729 -0
- daita/utils/__init__.py +18 -0
- daita_agents-0.1.0.dist-info/METADATA +350 -0
- daita_agents-0.1.0.dist-info/RECORD +69 -0
- daita_agents-0.1.0.dist-info/WHEEL +5 -0
- daita_agents-0.1.0.dist-info/entry_points.txt +2 -0
- daita_agents-0.1.0.dist-info/licenses/LICENSE +56 -0
- daita_agents-0.1.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)}")
|
daita/core/interfaces.py
ADDED
|
@@ -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
|
+
"""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
|