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/cli/__init__.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Daita CLI - Command Line Interface for Daita Agents.
|
|
3
|
+
|
|
4
|
+
Simple, git-like CLI for building and deploying AI agents.
|
|
5
|
+
|
|
6
|
+
Example usage:
|
|
7
|
+
# Initialize a new project
|
|
8
|
+
daita init my-project --type analysis
|
|
9
|
+
|
|
10
|
+
# Create components
|
|
11
|
+
daita create agent data_processor
|
|
12
|
+
daita create workflow data_pipeline
|
|
13
|
+
|
|
14
|
+
# Test and develop
|
|
15
|
+
daita test
|
|
16
|
+
daita test --watch
|
|
17
|
+
|
|
18
|
+
# Deploy
|
|
19
|
+
daita push staging
|
|
20
|
+
daita push production --force
|
|
21
|
+
|
|
22
|
+
# Monitor
|
|
23
|
+
daita status
|
|
24
|
+
daita logs production
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# CLI version
|
|
28
|
+
__version__ = "0.1.0"
|
|
29
|
+
|
|
30
|
+
# Import main CLI components
|
|
31
|
+
from .main import cli, main
|
|
32
|
+
|
|
33
|
+
# Import core functions for programmatic access
|
|
34
|
+
from .core.init import initialize_project
|
|
35
|
+
from .core.create import create_from_template
|
|
36
|
+
from .core.test import run_tests
|
|
37
|
+
from .core.deploy import deploy_to_environment
|
|
38
|
+
from .core.status import show_project_status
|
|
39
|
+
from .core.logs import show_deployment_logs
|
|
40
|
+
|
|
41
|
+
# Export main components
|
|
42
|
+
__all__ = [
|
|
43
|
+
# Version
|
|
44
|
+
'__version__',
|
|
45
|
+
|
|
46
|
+
# Main CLI
|
|
47
|
+
'cli',
|
|
48
|
+
'main',
|
|
49
|
+
|
|
50
|
+
# Core functions (for programmatic access)
|
|
51
|
+
'initialize_project',
|
|
52
|
+
'create_from_template',
|
|
53
|
+
'run_tests',
|
|
54
|
+
'deploy_to_environment',
|
|
55
|
+
'show_project_status',
|
|
56
|
+
'show_deployment_logs',
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
# CLI metadata
|
|
60
|
+
CLI_INFO = {
|
|
61
|
+
'name': 'daita',
|
|
62
|
+
'version': __version__,
|
|
63
|
+
'description': 'CLI for AI agent development and deployment',
|
|
64
|
+
'author': 'Daita Team',
|
|
65
|
+
'docs': 'https://docs.daita-tech.io',
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def get_cli_info() -> dict:
|
|
69
|
+
"""
|
|
70
|
+
Get CLI information and metadata.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Dictionary with CLI information
|
|
74
|
+
"""
|
|
75
|
+
return CLI_INFO.copy()
|
|
76
|
+
|
|
77
|
+
def print_banner():
|
|
78
|
+
"""Print CLI banner with version information."""
|
|
79
|
+
print(f"""
|
|
80
|
+
╔══════════════════════════════════════════════╗
|
|
81
|
+
║ Daita CLI ║
|
|
82
|
+
║ AI Agent Framework CLI ║
|
|
83
|
+
║ ║
|
|
84
|
+
║ Version: {__version__:<31} ║
|
|
85
|
+
║ Docs: https://docs.daita-tech.io/cli ║
|
|
86
|
+
╚══════════════════════════════════════════════╝
|
|
87
|
+
""")
|
|
88
|
+
|
|
89
|
+
# Convenience functions for common operations
|
|
90
|
+
def quick_init(project_name: str = None, project_type: str = 'basic') -> None:
|
|
91
|
+
"""
|
|
92
|
+
Quick project initialization.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
project_name: Name of the project
|
|
96
|
+
project_type: Type of project (basic, analysis, pipeline)
|
|
97
|
+
"""
|
|
98
|
+
import asyncio
|
|
99
|
+
|
|
100
|
+
asyncio.run(initialize_project(
|
|
101
|
+
project_name=project_name,
|
|
102
|
+
project_type=project_type,
|
|
103
|
+
verbose=False
|
|
104
|
+
))
|
|
105
|
+
|
|
106
|
+
def quick_status() -> dict:
|
|
107
|
+
"""
|
|
108
|
+
Quick status check for current project.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Dictionary with project status information
|
|
112
|
+
"""
|
|
113
|
+
import asyncio
|
|
114
|
+
from .utils import find_project_root
|
|
115
|
+
|
|
116
|
+
project_root = find_project_root()
|
|
117
|
+
if not project_root:
|
|
118
|
+
return {"error": "Not in a Daita project"}
|
|
119
|
+
|
|
120
|
+
# This would return status info - simplified for MVP
|
|
121
|
+
return {
|
|
122
|
+
"project_root": str(project_root),
|
|
123
|
+
"status": "active"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def quick_test(target: str = None) -> bool:
|
|
127
|
+
"""
|
|
128
|
+
Quick test runner.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
target: Specific agent or workflow to test
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
True if tests passed, False otherwise
|
|
135
|
+
"""
|
|
136
|
+
import asyncio
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
asyncio.run(run_tests(
|
|
140
|
+
target=target,
|
|
141
|
+
verbose=False
|
|
142
|
+
))
|
|
143
|
+
return True
|
|
144
|
+
except Exception:
|
|
145
|
+
return False
|
daita/cli/__main__.py
ADDED
daita/cli/ascii_art.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ASCII art utilities for Daita CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
def get_daita_ascii_art():
|
|
6
|
+
"""Return the main DAITA ASCII art."""
|
|
7
|
+
return """
|
|
8
|
+
██████╗ █████╗ ██╗████████╗ █████╗
|
|
9
|
+
██╔══██╗██╔══██╗██║╚══██╔══╝██╔══██╗
|
|
10
|
+
██║ ██║███████║██║ ██║ ███████║
|
|
11
|
+
██║ ██║██╔══██║██║ ██║ ██╔══██║
|
|
12
|
+
██████╔╝██║ ██║██║ ██║ ██║ ██║
|
|
13
|
+
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
14
|
+
|
|
15
|
+
AI Agent Framework & Platform
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def get_compact_daita_logo():
|
|
19
|
+
"""Return a compact DAITA logo for smaller displays."""
|
|
20
|
+
return """
|
|
21
|
+
█▀▄ ▄▀█ █ ▀█▀ ▄▀█
|
|
22
|
+
█▄▀ █▀█ █ █ █▀█ Agents
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def display_welcome_banner():
|
|
26
|
+
"""Display the full welcome banner with ASCII art."""
|
|
27
|
+
print(get_daita_ascii_art())
|
|
28
|
+
|
|
29
|
+
def display_compact_banner():
|
|
30
|
+
"""Display the compact banner."""
|
|
31
|
+
print(get_compact_daita_logo())
|
|
32
|
+
|
|
33
|
+
def get_version_banner(version="0.1.0"):
|
|
34
|
+
"""Get version banner with ASCII art."""
|
|
35
|
+
return f"""{get_daita_ascii_art()}
|
|
36
|
+
v{version}
|
|
37
|
+
Build, test, and deploy AI agents
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def get_success_banner(message="Project created successfully!"):
|
|
41
|
+
"""Get success banner with ASCII art."""
|
|
42
|
+
return f"""{get_daita_ascii_art()}
|
|
43
|
+
✨ {message}
|
|
44
|
+
"""
|
|
File without changes
|
daita/cli/core/create.py
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple component creation for Daita CLI.
|
|
3
|
+
Creates basic agents and workflows with proper path handling.
|
|
4
|
+
"""
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from ..utils import find_project_root
|
|
8
|
+
|
|
9
|
+
def create_from_template(template, name=None, variant=None, verbose=False):
|
|
10
|
+
"""Create a component from a template."""
|
|
11
|
+
|
|
12
|
+
# Find project root
|
|
13
|
+
project_root = find_project_root()
|
|
14
|
+
if not project_root:
|
|
15
|
+
raise ValueError("Not in a Daita project. Run 'daita init' first.")
|
|
16
|
+
|
|
17
|
+
# Get name if not provided
|
|
18
|
+
if not name:
|
|
19
|
+
name = input(f"Enter {template} name: ").strip()
|
|
20
|
+
|
|
21
|
+
# Validate name
|
|
22
|
+
if not name or not name.replace('_', '').replace('-', '').isalnum():
|
|
23
|
+
raise ValueError(f"Invalid {template} name: {name}")
|
|
24
|
+
|
|
25
|
+
# Convert name to valid Python identifier
|
|
26
|
+
clean_name = name.replace('-', '_').lower()
|
|
27
|
+
|
|
28
|
+
# Create the component
|
|
29
|
+
if template == 'agent':
|
|
30
|
+
_create_agent(project_root, clean_name, verbose)
|
|
31
|
+
elif template == 'workflow':
|
|
32
|
+
_create_workflow(project_root, clean_name, verbose)
|
|
33
|
+
else:
|
|
34
|
+
raise ValueError(f"Unknown template: {template}")
|
|
35
|
+
|
|
36
|
+
print(f" Created {template}: {clean_name}")
|
|
37
|
+
|
|
38
|
+
def _create_agent(project_root, name, verbose=False):
|
|
39
|
+
"""Create a simple agent."""
|
|
40
|
+
class_name = _to_class_name(name)
|
|
41
|
+
|
|
42
|
+
code = f'''"""
|
|
43
|
+
{class_name} Agent
|
|
44
|
+
|
|
45
|
+
Replace this with your own agent logic.
|
|
46
|
+
"""
|
|
47
|
+
from daita import SubstrateAgent
|
|
48
|
+
|
|
49
|
+
def create_agent():
|
|
50
|
+
"""Create the agent instance using direct SubstrateAgent pattern."""
|
|
51
|
+
# Option 1: Simple instantiation (uses defaults)
|
|
52
|
+
agent = SubstrateAgent(name="{class_name}")
|
|
53
|
+
|
|
54
|
+
# Option 2: Direct LLM configuration (uncomment and modify as needed)
|
|
55
|
+
# import os
|
|
56
|
+
# agent = SubstrateAgent(
|
|
57
|
+
# name="{class_name}",
|
|
58
|
+
# llm_provider="openai",
|
|
59
|
+
# model="gpt-4",
|
|
60
|
+
# api_key=os.getenv("OPENAI_API_KEY")
|
|
61
|
+
# )
|
|
62
|
+
|
|
63
|
+
# Optional: Add plugins
|
|
64
|
+
# from daita.plugins import postgresql
|
|
65
|
+
# agent.add_plugin(postgresql(host="localhost", database="mydb"))
|
|
66
|
+
|
|
67
|
+
return agent
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
import asyncio
|
|
71
|
+
|
|
72
|
+
async def main():
|
|
73
|
+
agent = create_agent()
|
|
74
|
+
result = await agent.process("test_task", "Hello, world!")
|
|
75
|
+
print(result)
|
|
76
|
+
|
|
77
|
+
asyncio.run(main())
|
|
78
|
+
'''
|
|
79
|
+
|
|
80
|
+
# Ensure agents directory exists
|
|
81
|
+
agents_dir = project_root / 'agents'
|
|
82
|
+
agents_dir.mkdir(exist_ok=True)
|
|
83
|
+
|
|
84
|
+
# Create agent file
|
|
85
|
+
agent_file = agents_dir / f'{name}.py'
|
|
86
|
+
|
|
87
|
+
if agent_file.exists():
|
|
88
|
+
raise ValueError(f"Agent {name} already exists")
|
|
89
|
+
|
|
90
|
+
agent_file.write_text(code)
|
|
91
|
+
|
|
92
|
+
# Prompt for display name
|
|
93
|
+
default_display = name.replace('_', ' ').title()
|
|
94
|
+
print(f"\n Display name for deployment:")
|
|
95
|
+
try:
|
|
96
|
+
display_name = input(f" Press Enter for '{default_display}' or type custom name: ").strip()
|
|
97
|
+
if not display_name:
|
|
98
|
+
display_name = default_display
|
|
99
|
+
except (EOFError, KeyboardInterrupt):
|
|
100
|
+
# Non-interactive environment or user cancelled
|
|
101
|
+
display_name = default_display
|
|
102
|
+
print(f" Using default: '{default_display}'")
|
|
103
|
+
except Exception:
|
|
104
|
+
# Any other input error
|
|
105
|
+
display_name = default_display
|
|
106
|
+
print(f" Input error, using default: '{default_display}'")
|
|
107
|
+
|
|
108
|
+
# Update project config with display name
|
|
109
|
+
_update_project_config(project_root, 'agents', name, display_name)
|
|
110
|
+
|
|
111
|
+
if verbose:
|
|
112
|
+
print(f" Created: {agent_file.relative_to(project_root)}")
|
|
113
|
+
print(f" Updated project config")
|
|
114
|
+
|
|
115
|
+
print(f" Display name: '{display_name}'")
|
|
116
|
+
|
|
117
|
+
def _create_workflow(project_root, name, verbose=False):
|
|
118
|
+
"""Create a simple workflow."""
|
|
119
|
+
class_name = _to_class_name(name)
|
|
120
|
+
|
|
121
|
+
code = f'''"""
|
|
122
|
+
{class_name} Workflow
|
|
123
|
+
|
|
124
|
+
Replace this with your own workflow logic.
|
|
125
|
+
"""
|
|
126
|
+
from daita import SubstrateAgent, Workflow
|
|
127
|
+
|
|
128
|
+
class {class_name}:
|
|
129
|
+
"""A simple workflow."""
|
|
130
|
+
|
|
131
|
+
def __init__(self):
|
|
132
|
+
self.workflow = Workflow("{name}")
|
|
133
|
+
|
|
134
|
+
# Add your agents here
|
|
135
|
+
# agent = SubstrateAgent(name="Agent")
|
|
136
|
+
# self.workflow.add_agent("agent", agent)
|
|
137
|
+
|
|
138
|
+
async def run(self, data=None):
|
|
139
|
+
"""
|
|
140
|
+
Run the workflow.
|
|
141
|
+
|
|
142
|
+
Replace this with your own logic.
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
await self.workflow.start()
|
|
146
|
+
|
|
147
|
+
# Your workflow logic here
|
|
148
|
+
result = f"Workflow {class_name} processed: {{data}}"
|
|
149
|
+
|
|
150
|
+
return {{
|
|
151
|
+
'status': 'success',
|
|
152
|
+
'result': result
|
|
153
|
+
}}
|
|
154
|
+
|
|
155
|
+
finally:
|
|
156
|
+
await self.workflow.stop()
|
|
157
|
+
|
|
158
|
+
def create_workflow():
|
|
159
|
+
"""Create the workflow instance."""
|
|
160
|
+
return {class_name}()
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
import asyncio
|
|
164
|
+
|
|
165
|
+
async def main():
|
|
166
|
+
workflow = {class_name}()
|
|
167
|
+
result = await workflow.run("test data")
|
|
168
|
+
print(result)
|
|
169
|
+
|
|
170
|
+
asyncio.run(main())
|
|
171
|
+
'''
|
|
172
|
+
|
|
173
|
+
# Ensure workflows directory exists
|
|
174
|
+
workflows_dir = project_root / 'workflows'
|
|
175
|
+
workflows_dir.mkdir(exist_ok=True)
|
|
176
|
+
|
|
177
|
+
# Create workflow file
|
|
178
|
+
workflow_file = workflows_dir / f'{name}.py'
|
|
179
|
+
|
|
180
|
+
if workflow_file.exists():
|
|
181
|
+
raise ValueError(f"Workflow {name} already exists")
|
|
182
|
+
|
|
183
|
+
workflow_file.write_text(code)
|
|
184
|
+
|
|
185
|
+
# Prompt for display name
|
|
186
|
+
default_display = name.replace('_', ' ').title()
|
|
187
|
+
print(f"\n Display name for deployment:")
|
|
188
|
+
try:
|
|
189
|
+
display_name = input(f" Press Enter for '{default_display}' or type custom name: ").strip()
|
|
190
|
+
if not display_name:
|
|
191
|
+
display_name = default_display
|
|
192
|
+
except (EOFError, KeyboardInterrupt):
|
|
193
|
+
# Non-interactive environment or user cancelled
|
|
194
|
+
display_name = default_display
|
|
195
|
+
print(f" Using default: '{default_display}'")
|
|
196
|
+
except Exception:
|
|
197
|
+
# Any other input error
|
|
198
|
+
display_name = default_display
|
|
199
|
+
print(f" Input error, using default: '{default_display}'")
|
|
200
|
+
|
|
201
|
+
# Update project config with display name
|
|
202
|
+
_update_project_config(project_root, 'workflows', name, display_name)
|
|
203
|
+
|
|
204
|
+
if verbose:
|
|
205
|
+
print(f" Created: {workflow_file.relative_to(project_root)}")
|
|
206
|
+
print(f" Updated project config")
|
|
207
|
+
|
|
208
|
+
print(f" Display name: '{display_name}'")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _update_project_config(project_root, component_type, name, display_name=None):
|
|
212
|
+
"""Update daita-project.yaml with new component."""
|
|
213
|
+
import yaml
|
|
214
|
+
from datetime import datetime
|
|
215
|
+
|
|
216
|
+
config_file = project_root / 'daita-project.yaml'
|
|
217
|
+
|
|
218
|
+
if config_file.exists():
|
|
219
|
+
with open(config_file, 'r') as f:
|
|
220
|
+
config = yaml.safe_load(f)
|
|
221
|
+
else:
|
|
222
|
+
config = {}
|
|
223
|
+
|
|
224
|
+
# Ensure arrays exist
|
|
225
|
+
if component_type not in config:
|
|
226
|
+
config[component_type] = []
|
|
227
|
+
|
|
228
|
+
# Generate default display name if not provided
|
|
229
|
+
if not display_name:
|
|
230
|
+
display_name = name.replace('_', ' ').title()
|
|
231
|
+
|
|
232
|
+
# Add component if not already present
|
|
233
|
+
component_entry = {
|
|
234
|
+
'name': name,
|
|
235
|
+
'display_name': display_name,
|
|
236
|
+
'type': 'substrate' if component_type == 'agents' else 'basic',
|
|
237
|
+
'created_at': datetime.now().isoformat()
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Check if already exists
|
|
241
|
+
existing = next((c for c in config[component_type] if c['name'] == name), None)
|
|
242
|
+
if not existing:
|
|
243
|
+
config[component_type].append(component_entry)
|
|
244
|
+
|
|
245
|
+
# Write back to file
|
|
246
|
+
with open(config_file, 'w') as f:
|
|
247
|
+
yaml.dump(config, f, default_flow_style=False)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _to_class_name(name):
|
|
251
|
+
"""Convert snake_case or kebab-case to PascalCase."""
|
|
252
|
+
# Split on underscores and hyphens, capitalize each part
|
|
253
|
+
parts = name.replace('-', '_').split('_')
|
|
254
|
+
return ''.join(word.capitalize() for word in parts if word)
|