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/cli/core/init.py ADDED
@@ -0,0 +1,481 @@
1
+ """
2
+ Simple project initialization for Daita CLI.
3
+ Creates minimal, universal project template like create-react-app.
4
+ """
5
+ import os
6
+ import yaml
7
+ from pathlib import Path
8
+ from datetime import datetime
9
+ from ..utils import find_project_root
10
+
11
+ async def initialize_project(project_name=None, project_type='basic', template=None, force=False, verbose=False):
12
+ """Initialize a new Daita project with minimal template."""
13
+
14
+ # Get project name
15
+ if not project_name:
16
+ project_name = input("Project name: ").strip()
17
+ if not project_name:
18
+ project_name = Path.cwd().name
19
+
20
+ # Determine project directory
21
+ project_dir = Path.cwd() / project_name
22
+
23
+ # Check if directory exists
24
+ if project_dir.exists() and not force:
25
+ if any(project_dir.iterdir()): # Directory not empty
26
+ confirm = input(f"Directory '{project_name}' exists and is not empty. Continue? (y/N): ")
27
+ if confirm.lower() != 'y':
28
+ print(" Initialization cancelled")
29
+ return
30
+
31
+ # Create project directory
32
+ project_dir.mkdir(exist_ok=True)
33
+
34
+ print(f" Creating Daita project: {project_name}")
35
+ print(f" Location: {project_dir}")
36
+
37
+ # Create minimal project structure
38
+ _create_project_structure(project_dir, verbose)
39
+ _create_project_config(project_dir, project_name, verbose)
40
+ _create_starter_files(project_dir, project_name, verbose)
41
+ _create_supporting_files(project_dir, project_name, verbose)
42
+
43
+ # Import freemium utilities
44
+ try:
45
+ from ..utils import get_freemium_success_message
46
+ print("")
47
+ print(get_freemium_success_message(project_name))
48
+ print("")
49
+ print(" Development setup:")
50
+ print(f" export OPENAI_API_KEY=your_key_here # Configure LLM or another provider")
51
+ print(f" pip install -r requirements.txt # Install dependencies")
52
+ print(f" python agents/my_agent.py # Test example agent")
53
+ except ImportError:
54
+ # Fallback to original message if utils not available
55
+ print(f"")
56
+ print(f"Project created successfully")
57
+ print(f"")
58
+ print(f"Get started:")
59
+ print(f" cd {project_name}")
60
+ print(f" export OPENAI_API_KEY=your_key_here or another provider")
61
+ print(f" pip install -r requirements.txt")
62
+ print(f" python agents/my_agent.py # Test the example agent")
63
+ print(f" daita create agent new_agent # Create a new agent")
64
+ print(f" daita test # Test all components")
65
+ print(f" daita test --watch # Watch for changes while developing")
66
+
67
+ def _create_project_structure(project_dir, verbose):
68
+ """Create minimal directory structure."""
69
+ directories = [
70
+ '.daita',
71
+ 'agents',
72
+ 'workflows',
73
+ 'data',
74
+ 'tests'
75
+ ]
76
+
77
+ for dir_name in directories:
78
+ dir_path = project_dir / dir_name
79
+ dir_path.mkdir(exist_ok=True)
80
+
81
+ # Create __init__.py for Python packages
82
+ if dir_name in ['agents', 'workflows', 'tests']:
83
+ init_file = dir_path / '__init__.py'
84
+ init_file.write_text('"""Daita project components."""\n')
85
+
86
+ if verbose:
87
+ print(f" Created: {dir_name}/")
88
+
89
+ def _create_project_config(project_dir, project_name, verbose):
90
+ """Create minimal daita-project.yaml configuration."""
91
+
92
+ config = {
93
+ 'name': project_name,
94
+ 'version': '1.0.0',
95
+ 'description': f'A Daita AI agent project',
96
+ 'created_at': datetime.utcnow().isoformat(),
97
+
98
+ # Project components (will be populated as user creates them)
99
+ 'agents': [],
100
+ 'workflows': []
101
+ }
102
+
103
+ config_file = project_dir / 'daita-project.yaml'
104
+ with open(config_file, 'w') as f:
105
+ yaml.dump(config, f, default_flow_style=False, sort_keys=False)
106
+
107
+ if verbose:
108
+ print(f" Created: daita-project.yaml")
109
+
110
+ def _create_starter_files(project_dir, project_name, verbose):
111
+ """Create minimal starter agent and workflow files."""
112
+
113
+ # Simple data-focused starter agent
114
+ starter_agent = '''"""
115
+ My Agent - Data Processing Example
116
+
117
+ A simple data processing agent.
118
+ """
119
+ from daita import SubstrateAgent
120
+ from daita.core.tools import tool
121
+
122
+ # Simple data processing tool
123
+ @tool
124
+ async def calculate_stats(data: list) -> dict:
125
+ """Calculate basic statistics for a list of numbers."""
126
+ if not data:
127
+ return {"error": "No data provided"}
128
+
129
+ return {
130
+ "count": len(data),
131
+ "sum": sum(data),
132
+ "avg": sum(data) / len(data),
133
+ "min": min(data),
134
+ "max": max(data)
135
+ }
136
+
137
+ def create_agent():
138
+ """Create the data processing agent."""
139
+ agent = SubstrateAgent(
140
+ name="Data Processor",
141
+ model="gpt-4o-mini",
142
+ prompt="You are a data analyst. Help users analyze and process data."
143
+ )
144
+
145
+ # Register data processing tools
146
+ agent.register_tool(calculate_stats)
147
+
148
+ # Add database plugin (optional - uncomment to use)
149
+ # from daita.plugins import postgresql
150
+ # db = postgresql(host="localhost", database="mydb", user="user", password="pass")
151
+ # agent = SubstrateAgent(name="Data Processor", tools=[db])
152
+
153
+ return agent
154
+
155
+ if __name__ == "__main__":
156
+ import asyncio
157
+
158
+ async def main():
159
+ """Example: Process sample data with the clean API."""
160
+ agent = create_agent()
161
+ await agent.start()
162
+
163
+ try:
164
+ # Sample data
165
+ sales_data = [100, 250, 175, 300, 225]
166
+
167
+ # Simple usage - just get the answer
168
+ answer = await agent.run(
169
+ f"Analyze these sales numbers and tell me the insights: {sales_data}"
170
+ )
171
+ print(f"Analysis: {answer}")
172
+
173
+ # Detailed usage - get full metadata (cost, time, tools used)
174
+ result = await agent.run_detailed(
175
+ f"What's the average and total of: {sales_data}?"
176
+ )
177
+ print(f"\\nDetailed result:")
178
+ print(f" Answer: {result['result']}")
179
+ print(f" Processing time: {result.get('processing_time_ms', 0):.0f}ms")
180
+ print(f" Tools used: {len(result.get('tool_calls', []))}")
181
+
182
+ finally:
183
+ await agent.stop()
184
+
185
+ asyncio.run(main())
186
+ '''
187
+
188
+ # Simple data pipeline workflow
189
+ starter_workflow = '''"""
190
+ My Workflow - Data Pipeline
191
+
192
+ A simple data processing pipeline.
193
+ """
194
+ from daita import SubstrateAgent, Workflow
195
+
196
+ def create_workflow():
197
+ """Create a data processing pipeline."""
198
+ workflow = Workflow("Data Pipeline")
199
+
200
+ # Agent 1: Data validator
201
+ validator = SubstrateAgent(
202
+ name="Data Validator",
203
+ model="gpt-4o-mini",
204
+ prompt="You validate data quality and flag issues."
205
+ )
206
+
207
+ # Agent 2: Data analyzer
208
+ analyzer = SubstrateAgent(
209
+ name="Data Analyzer",
210
+ model="gpt-4o-mini",
211
+ prompt="You analyze data and extract insights."
212
+ )
213
+
214
+ # Add agents to workflow
215
+ workflow.add_agent("validator", validator)
216
+ workflow.add_agent("analyzer", analyzer)
217
+
218
+ # Connect: validator -> analyzer
219
+ workflow.connect("validator", "validated_data", "analyzer")
220
+
221
+ return workflow
222
+
223
+ async def run_workflow(data=None):
224
+ """Run the data pipeline."""
225
+ workflow = create_workflow()
226
+
227
+ try:
228
+ await workflow.start()
229
+
230
+ # Sample data
231
+ sample_data = data or {
232
+ "records": [
233
+ {"id": 1, "amount": 100, "status": "completed"},
234
+ {"id": 2, "amount": 250, "status": "pending"}
235
+ ]
236
+ }
237
+
238
+ await workflow.inject_data("validator", sample_data)
239
+
240
+ return {
241
+ 'status': 'success',
242
+ 'message': f'Processed {len(sample_data.get("records", []))} records'
243
+ }
244
+
245
+ finally:
246
+ await workflow.stop()
247
+
248
+ if __name__ == "__main__":
249
+ import asyncio
250
+
251
+ async def main():
252
+ result = await run_workflow()
253
+ print(f"Result: {result}")
254
+
255
+ asyncio.run(main())
256
+ '''
257
+
258
+ # Write starter files
259
+ (project_dir / 'agents' / 'my_agent.py').write_text(starter_agent)
260
+ (project_dir / 'workflows' / 'my_workflow.py').write_text(starter_workflow)
261
+
262
+ if verbose:
263
+ print(f" Created: agents/my_agent.py")
264
+ print(f" Created: workflows/my_workflow.py")
265
+
266
+ def _create_supporting_files(project_dir, project_name, verbose):
267
+ """Create supporting files (requirements, README, etc.)."""
268
+
269
+ # Minimal requirements.txt
270
+ requirements = '''# Daita Agents Framework
271
+ daita-agents>=0.1.0
272
+
273
+ # LLM provider (choose one)
274
+ openai>=1.0.0
275
+
276
+ # Development
277
+ pytest>=7.0.0
278
+ pytest-asyncio>=0.21.0
279
+ '''
280
+
281
+ # Simple .gitignore
282
+ gitignore = '''# Python
283
+ __pycache__/
284
+ *.py[cod]
285
+ *.so
286
+ .Python
287
+ build/
288
+ dist/
289
+ *.egg-info/
290
+
291
+ # Virtual environments
292
+ .env
293
+ .venv
294
+ venv/
295
+
296
+ # IDE
297
+ .vscode/
298
+ .idea/
299
+
300
+ # OS
301
+ .DS_Store
302
+
303
+ # API keys
304
+ .env.local
305
+ '''
306
+
307
+ # README with freemium messaging
308
+ readme = f'''# {project_name}
309
+
310
+ A Daita AI agent project.
311
+
312
+ ## Quick Setup
313
+
314
+ 1. Install dependencies:
315
+ ```bash
316
+ pip install -r requirements.txt
317
+ ```
318
+
319
+ 2. Set your LLM API key:
320
+ ```bash
321
+ export OPENAI_API_KEY=your_key_here
322
+ ```
323
+
324
+ ## Free Local Development
325
+
326
+ Build and test your agents locally - completely free:
327
+
328
+ ```bash
329
+ # Test the example agent
330
+ python agents/my_agent.py
331
+
332
+ # Test all components
333
+ daita test
334
+
335
+ # Watch for changes while developing
336
+ daita test --watch
337
+
338
+ # Create new components
339
+ daita create agent my_new_agent
340
+ daita create workflow my_new_workflow
341
+ ```
342
+
343
+ ## Production Cloud Hosting
344
+
345
+ Ready to deploy to the cloud? Get 24/7 hosting, monitoring, and insights:
346
+
347
+ ```bash
348
+ # Get your API key at daita-tech.io
349
+ export DAITA_API_KEY='your-key-here'
350
+
351
+ # Deploy to cloud
352
+ daita push # Deploy to production
353
+
354
+ # Monitor your deployments
355
+ daita status # Deployment status
356
+ daita logs # View execution logs
357
+ ```
358
+
359
+ ## Project Structure
360
+
361
+ ```
362
+ {project_name}/
363
+ ├── agents/ # Your AI agents (free to create & test)
364
+ │ └── my_agent.py
365
+ ├── workflows/ # Your workflows (free to create & test)
366
+ │ └── my_workflow.py
367
+ ├── data/ # Data files
368
+ ├── tests/ # Tests
369
+ └── daita-project.yaml # Project config
370
+ ```
371
+
372
+ ## Command Reference
373
+
374
+ **Free Commands (Local Development):**
375
+ - `daita test` - Test all agents and workflows
376
+ - `daita test --watch` - Development mode with auto-reload
377
+ - `daita create agent <name>` - Create new agent
378
+ - `daita create workflow <name>` - Create new workflow
379
+
380
+ **Premium Commands (Cloud Hosting):**
381
+ - `daita push <env>` - Deploy to cloud
382
+ - `daita status` - Monitor deployments
383
+ - `daita logs <env>` - View execution logs
384
+ - `daita run <agent>` - Execute remotely
385
+
386
+ ## Learn More
387
+
388
+ - [Get API Key](https://daita-tech.io) - Start your free trial
389
+ - [Documentation](https://docs.daita-tech.io)
390
+ '''
391
+
392
+ # Simple test file for data processing
393
+ test_file = '''"""
394
+ Basic tests for data processing agents and workflows.
395
+ """
396
+ import pytest
397
+ import asyncio
398
+
399
+ @pytest.mark.asyncio
400
+ async def test_agent_run():
401
+ """Test agent with run() API."""
402
+ from agents.my_agent import create_agent
403
+
404
+ agent = create_agent()
405
+ await agent.start()
406
+
407
+ try:
408
+ # Test data processing
409
+ answer = await agent.run("Calculate the average of [10, 20, 30]")
410
+ assert isinstance(answer, str)
411
+ assert "20" in answer or "average" in answer.lower()
412
+
413
+ finally:
414
+ await agent.stop()
415
+
416
+ @pytest.mark.asyncio
417
+ async def test_agent_run_detailed():
418
+ """Test agent with run_detailed() API."""
419
+ from agents.my_agent import create_agent
420
+
421
+ agent = create_agent()
422
+ await agent.start()
423
+
424
+ try:
425
+ # Test with metadata
426
+ result = await agent.run_detailed("What's the sum of [5, 10, 15]?")
427
+
428
+ assert "result" in result
429
+ assert isinstance(result["result"], str)
430
+ assert "processing_time_ms" in result
431
+ assert "agent_id" in result
432
+
433
+ finally:
434
+ await agent.stop()
435
+
436
+ @pytest.mark.asyncio
437
+ async def test_workflow():
438
+ """Test data pipeline workflow."""
439
+ from workflows.my_workflow import run_workflow
440
+
441
+ result = await run_workflow({
442
+ "records": [
443
+ {"id": 1, "amount": 100},
444
+ {"id": 2, "amount": 200}
445
+ ]
446
+ })
447
+
448
+ assert result["status"] == "success"
449
+ assert "records" in result["message"]
450
+
451
+ if __name__ == "__main__":
452
+ async def main():
453
+ print("Running agent tests...")
454
+ await test_agent_run()
455
+ await test_agent_run_detailed()
456
+ print(" Agent tests passed!")
457
+
458
+ print("Running workflow tests...")
459
+ await test_workflow()
460
+ print(" Workflow tests passed!")
461
+
462
+ print("\\n All tests passed!")
463
+
464
+ asyncio.run(main())
465
+ '''
466
+
467
+ # Write all supporting files
468
+ (project_dir / 'requirements.txt').write_text(requirements)
469
+ (project_dir / '.gitignore').write_text(gitignore)
470
+ (project_dir / 'README.md').write_text(readme)
471
+ (project_dir / 'tests' / 'test_basic.py').write_text(test_file)
472
+
473
+ # Create empty data directory with placeholder
474
+ (project_dir / 'data' / '.gitkeep').write_text('')
475
+
476
+ if verbose:
477
+ print(f" Created: requirements.txt")
478
+ print(f" Created: .gitignore")
479
+ print(f" Created: README.md")
480
+ print(f" Created: tests/test_basic.py")
481
+