dacp 0.3.1__tar.gz → 0.3.2__tar.gz

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 (32) hide show
  1. {dacp-0.3.1 → dacp-0.3.2}/PKG-INFO +342 -1
  2. {dacp-0.3.1 → dacp-0.3.2}/README.md +341 -0
  3. {dacp-0.3.1 → dacp-0.3.2}/dacp/__init__.py +3 -5
  4. dacp-0.3.2/dacp/intelligence.py +303 -0
  5. {dacp-0.3.1 → dacp-0.3.2}/dacp/llm.py +13 -6
  6. {dacp-0.3.1 → dacp-0.3.2}/dacp/logging_config.py +17 -16
  7. dacp-0.3.2/dacp/main.py +9 -0
  8. dacp-0.3.2/dacp/orchestrator.py +284 -0
  9. dacp-0.3.2/dacp/tools.py +105 -0
  10. {dacp-0.3.1 → dacp-0.3.2}/dacp.egg-info/PKG-INFO +342 -1
  11. {dacp-0.3.1 → dacp-0.3.2}/pyproject.toml +2 -1
  12. dacp-0.3.2/tests/test_intelligence.py +72 -0
  13. dacp-0.3.2/tests/test_llm.py +86 -0
  14. dacp-0.3.2/tests/test_orchestrator.py +110 -0
  15. {dacp-0.3.1 → dacp-0.3.2}/tests/test_tools.py +30 -22
  16. dacp-0.3.1/dacp/intelligence.py +0 -378
  17. dacp-0.3.1/dacp/main.py +0 -15
  18. dacp-0.3.1/dacp/orchestrator.py +0 -248
  19. dacp-0.3.1/dacp/tools.py +0 -86
  20. dacp-0.3.1/tests/test_intelligence.py +0 -295
  21. dacp-0.3.1/tests/test_llm.py +0 -116
  22. dacp-0.3.1/tests/test_orchestrator.py +0 -310
  23. {dacp-0.3.1 → dacp-0.3.2}/LICENSE +0 -0
  24. {dacp-0.3.1 → dacp-0.3.2}/dacp/exceptions.py +0 -0
  25. {dacp-0.3.1 → dacp-0.3.2}/dacp/protocol.py +0 -0
  26. {dacp-0.3.1 → dacp-0.3.2}/dacp/types.py +0 -0
  27. {dacp-0.3.1 → dacp-0.3.2}/dacp.egg-info/SOURCES.txt +0 -0
  28. {dacp-0.3.1 → dacp-0.3.2}/dacp.egg-info/dependency_links.txt +0 -0
  29. {dacp-0.3.1 → dacp-0.3.2}/dacp.egg-info/requires.txt +0 -0
  30. {dacp-0.3.1 → dacp-0.3.2}/dacp.egg-info/top_level.txt +0 -0
  31. {dacp-0.3.1 → dacp-0.3.2}/setup.cfg +0 -0
  32. {dacp-0.3.1 → dacp-0.3.2}/tests/test_protocol.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dacp
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Declarative Agent Communication Protocol - A protocol for managing LLM/agent communications and tool function calls
5
5
  Author-email: Andrew Whitehouse <andrew.whitehouse@example.com>
6
6
  License: MIT
@@ -443,6 +443,347 @@ orchestrator.register_agent("my-agent", agent)
443
443
  response = orchestrator.send_message("my-agent", {"task": "process"})
444
444
  ```
445
445
 
446
+ ## Usage Patterns: Open Agent Spec vs Independent Client Usage
447
+
448
+ DACP supports two primary usage patterns: integration with Open Agent Specification (OAS) projects and independent client usage. Both provide full access to DACP's capabilities but with different integration approaches.
449
+
450
+ ### Open Agent Specification (OAS) Integration
451
+
452
+ **For OAS developers:** DACP integrates seamlessly with generated agents through YAML configuration and automatic setup.
453
+
454
+ #### YAML Configuration Pattern
455
+
456
+ ```yaml
457
+ # agent_config.yaml (Open Agent Specification)
458
+ apiVersion: "v1"
459
+ kind: "Agent"
460
+ metadata:
461
+ name: "data-analysis-agent"
462
+ type: "smart_analysis"
463
+
464
+ # DACP automatically configures logging
465
+ logging:
466
+ enabled: true
467
+ level: "INFO"
468
+ format_style: "emoji"
469
+ log_file: "./logs/agent.log"
470
+ env_overrides:
471
+ level: "DACP_LOG_LEVEL"
472
+
473
+ # Multi-provider intelligence configuration
474
+ intelligence:
475
+ engine: "anthropic"
476
+ model: "claude-3-haiku-20240618"
477
+ # API key from environment: ANTHROPIC_API_KEY
478
+
479
+ # Define agent capabilities
480
+ capabilities:
481
+ - name: "analyze_data"
482
+ description: "Analyze datasets and generate insights"
483
+ - name: "generate_report"
484
+ description: "Generate analysis reports"
485
+ ```
486
+
487
+ #### Generated Agent Code (OAS Pattern)
488
+
489
+ ```python
490
+ # Generated by OAS with DACP integration
491
+ import dacp
492
+ import yaml
493
+
494
+ class DataAnalysisAgent(dacp.Agent):
495
+ def __init__(self, config_path="agent_config.yaml"):
496
+ # DACP auto-configures logging from YAML
497
+ with open(config_path, 'r') as f:
498
+ self.config = yaml.safe_load(f)
499
+
500
+ # Automatic logging setup
501
+ self.setup_logging()
502
+
503
+ # Load intelligence configuration
504
+ self.intelligence_config = self.config.get('intelligence', {})
505
+
506
+ def setup_logging(self):
507
+ """Auto-configure DACP logging from YAML config."""
508
+ logging_config = self.config.get('logging', {})
509
+ if logging_config.get('enabled', False):
510
+ dacp.setup_dacp_logging(
511
+ level=logging_config.get('level', 'INFO'),
512
+ format_style=logging_config.get('format_style', 'emoji'),
513
+ log_file=logging_config.get('log_file')
514
+ )
515
+
516
+ def handle_message(self, message):
517
+ """Handle capabilities defined in YAML."""
518
+ task = message.get("task")
519
+
520
+ if task == "analyze_data":
521
+ return self.analyze_data(message)
522
+ elif task == "generate_report":
523
+ return self.generate_report(message)
524
+ else:
525
+ return {"error": f"Unknown task: {task}"}
526
+
527
+ def analyze_data(self, message):
528
+ """Analyze data using configured intelligence provider."""
529
+ data = message.get("data", "No data provided")
530
+
531
+ try:
532
+ result = dacp.invoke_intelligence(
533
+ f"Analyze this data and provide insights: {data}",
534
+ self.intelligence_config
535
+ )
536
+ return {"response": result}
537
+ except Exception as e:
538
+ return {"error": f"Analysis failed: {e}"}
539
+
540
+ def generate_report(self, message):
541
+ """Generate reports using DACP's file_writer tool."""
542
+ subject = message.get("subject", "report")
543
+ data = message.get("data", "No data")
544
+
545
+ return {
546
+ "tool_request": {
547
+ "name": "file_writer",
548
+ "args": {
549
+ "path": f"./reports/{subject}.txt",
550
+ "content": f"# Analysis Report: {subject}\n\nData: {data}\n"
551
+ }
552
+ }
553
+ }
554
+
555
+ # Auto-generated main function
556
+ def main():
557
+ # Zero-configuration setup
558
+ orchestrator = dacp.Orchestrator()
559
+ agent = DataAnalysisAgent()
560
+ orchestrator.register_agent("data-analysis-agent", agent)
561
+
562
+ print("🚀 OAS Agent running with DACP integration!")
563
+ # Agent ready for messages via orchestrator
564
+
565
+ if __name__ == "__main__":
566
+ main()
567
+ ```
568
+
569
+ #### OAS Benefits
570
+
571
+ - ✅ **Zero Configuration**: Logging and intelligence work out of the box
572
+ - ✅ **YAML-Driven**: All configuration in standard OAS YAML format
573
+ - ✅ **Auto-Generated**: Complete agents generated from specifications
574
+ - ✅ **Environment Overrides**: Runtime configuration via environment variables
575
+ - ✅ **Standardized**: Consistent interface across all OAS agents
576
+
577
+ ### Independent Client Usage
578
+
579
+ **For independent developers:** Use DACP directly as a flexible agent router and orchestration platform.
580
+
581
+ #### Direct Integration Pattern
582
+
583
+ ```python
584
+ import dacp
585
+ import os
586
+
587
+ class MyCustomAgent(dacp.Agent):
588
+ """Independent client's custom agent."""
589
+
590
+ def __init__(self):
591
+ # Manual setup - full control
592
+ self.setup_intelligence()
593
+ self.setup_logging()
594
+
595
+ def setup_intelligence(self):
596
+ """Configure intelligence providers manually."""
597
+ self.intelligence_configs = {
598
+ "research": {
599
+ "engine": "openai",
600
+ "model": "gpt-4",
601
+ "api_key": os.getenv("OPENAI_API_KEY")
602
+ },
603
+ "analysis": {
604
+ "engine": "anthropic",
605
+ "model": "claude-3-sonnet-20240229",
606
+ "api_key": os.getenv("ANTHROPIC_API_KEY")
607
+ },
608
+ "local": {
609
+ "engine": "local",
610
+ "model": "llama2",
611
+ "endpoint": "http://localhost:11434/api/generate"
612
+ }
613
+ }
614
+
615
+ def setup_logging(self):
616
+ """Configure logging manually."""
617
+ dacp.enable_info_logging(log_file="./logs/custom_agent.log")
618
+
619
+ def handle_message(self, message):
620
+ """Custom business logic."""
621
+ task = message.get("task")
622
+
623
+ if task == "research_topic":
624
+ return self.research_with_multiple_llms(message)
625
+ elif task == "process_data":
626
+ return self.multi_step_processing(message)
627
+ elif task == "custom_workflow":
628
+ return self.handle_custom_workflow(message)
629
+ else:
630
+ return {"error": f"Unknown task: {task}"}
631
+
632
+ def research_with_multiple_llms(self, message):
633
+ """Use multiple LLM providers for comprehensive research."""
634
+ topic = message.get("topic", "AI Research")
635
+
636
+ # Use different LLMs for different aspects
637
+ research_prompt = f"Research the topic: {topic}"
638
+ analysis_prompt = f"Analyze research findings for: {topic}"
639
+
640
+ try:
641
+ # Research with GPT-4
642
+ research = dacp.invoke_intelligence(
643
+ research_prompt,
644
+ self.intelligence_configs["research"]
645
+ )
646
+
647
+ # Analysis with Claude
648
+ analysis = dacp.invoke_intelligence(
649
+ f"Analyze: {research}",
650
+ self.intelligence_configs["analysis"]
651
+ )
652
+
653
+ return {
654
+ "research": research,
655
+ "analysis": analysis,
656
+ "status": "completed"
657
+ }
658
+ except Exception as e:
659
+ return {"error": f"Research failed: {e}"}
660
+
661
+ def multi_step_processing(self, message):
662
+ """Multi-step workflow with tool chaining."""
663
+ data = message.get("data", "sample data")
664
+
665
+ # Step 1: Process and save data
666
+ return {
667
+ "tool_request": {
668
+ "name": "file_writer",
669
+ "args": {
670
+ "path": "./processing/input_data.txt",
671
+ "content": f"Raw data: {data}\nProcessed at: {dacp.time.time()}"
672
+ }
673
+ }
674
+ }
675
+ # In real implementation, would continue workflow in subsequent messages
676
+
677
+ # Independent client setup
678
+ def main():
679
+ # Manual orchestrator setup
680
+ orchestrator = dacp.Orchestrator()
681
+
682
+ # Register multiple custom agents
683
+ research_agent = MyCustomAgent()
684
+ data_agent = MyCustomAgent()
685
+ workflow_agent = MyCustomAgent()
686
+
687
+ orchestrator.register_agent("researcher", research_agent)
688
+ orchestrator.register_agent("processor", data_agent)
689
+ orchestrator.register_agent("workflow", workflow_agent)
690
+
691
+ # Direct control over routing
692
+ print("🚀 Independent client agents running!")
693
+
694
+ # Example: Route complex task across multiple agents
695
+ research_result = orchestrator.send_message("researcher", {
696
+ "task": "research_topic",
697
+ "topic": "Multi-Agent Systems"
698
+ })
699
+
700
+ processing_result = orchestrator.send_message("processor", {
701
+ "task": "process_data",
702
+ "data": research_result
703
+ })
704
+
705
+ # Broadcast updates to all agents
706
+ orchestrator.broadcast_message({
707
+ "task": "status_update",
708
+ "message": "Workflow completed"
709
+ })
710
+
711
+ if __name__ == "__main__":
712
+ main()
713
+ ```
714
+
715
+ #### Advanced Independent Usage
716
+
717
+ ```python
718
+ # Register custom tools for specialized business logic
719
+ def custom_data_processor(args):
720
+ """Client's proprietary data processing tool."""
721
+ data = args.get("data", [])
722
+ algorithm = args.get("algorithm", "default")
723
+
724
+ # Custom processing logic
725
+ processed = [item * 2 for item in data if isinstance(item, (int, float))]
726
+
727
+ return {
728
+ "success": True,
729
+ "processed_data": processed,
730
+ "algorithm_used": algorithm,
731
+ "count": len(processed)
732
+ }
733
+
734
+ # Register with DACP
735
+ dacp.register_tool("custom_processor", custom_data_processor)
736
+
737
+ # Use in agents
738
+ class SpecializedAgent(dacp.Agent):
739
+ def handle_message(self, message):
740
+ if message.get("task") == "process_with_custom_tool":
741
+ return {
742
+ "tool_request": {
743
+ "name": "custom_processor",
744
+ "args": {
745
+ "data": message.get("data", []),
746
+ "algorithm": "proprietary_v2"
747
+ }
748
+ }
749
+ }
750
+ ```
751
+
752
+ #### Independent Client Benefits
753
+
754
+ - ✅ **Full Control**: Manual configuration of all components
755
+ - ✅ **Flexible Architecture**: Design your own agent interactions
756
+ - ✅ **Custom Tools**: Register proprietary business logic tools
757
+ - ✅ **Multi-Provider**: Use different LLMs for different tasks
758
+ - ✅ **Direct API Access**: Call DACP functions directly when needed
759
+ - ✅ **Complex Workflows**: Build sophisticated multi-agent orchestrations
760
+
761
+ ### Choosing Your Pattern
762
+
763
+ | Feature | OAS Integration | Independent Client |
764
+ |---------|----------------|-------------------|
765
+ | **Setup Complexity** | Minimal (auto-generated) | Manual (full control) |
766
+ | **Configuration** | YAML-driven | Programmatic |
767
+ | **Agent Generation** | Automatic from spec | Manual implementation |
768
+ | **Customization** | Template-based | Unlimited flexibility |
769
+ | **Best For** | Rapid prototyping, standard agents | Complex workflows, custom logic |
770
+ | **Learning Curve** | Low | Medium |
771
+
772
+ ### Getting Started
773
+
774
+ **For OAS Integration:**
775
+ 1. Add DACP logging section to your YAML spec
776
+ 2. Generate agents with DACP base class
777
+ 3. Agents work with zero additional configuration
778
+
779
+ **For Independent Usage:**
780
+ 1. `pip install dacp`
781
+ 2. Create agents inheriting from `dacp.Agent`
782
+ 3. Register with `dacp.Orchestrator()`
783
+ 4. Build your custom workflows
784
+
785
+ Both patterns provide full access to DACP's capabilities: multi-provider LLM routing, tool execution, comprehensive logging, conversation history, and multi-agent orchestration.
786
+
446
787
  ## Development
447
788
 
448
789
  ```bash
@@ -396,6 +396,347 @@ orchestrator.register_agent("my-agent", agent)
396
396
  response = orchestrator.send_message("my-agent", {"task": "process"})
397
397
  ```
398
398
 
399
+ ## Usage Patterns: Open Agent Spec vs Independent Client Usage
400
+
401
+ DACP supports two primary usage patterns: integration with Open Agent Specification (OAS) projects and independent client usage. Both provide full access to DACP's capabilities but with different integration approaches.
402
+
403
+ ### Open Agent Specification (OAS) Integration
404
+
405
+ **For OAS developers:** DACP integrates seamlessly with generated agents through YAML configuration and automatic setup.
406
+
407
+ #### YAML Configuration Pattern
408
+
409
+ ```yaml
410
+ # agent_config.yaml (Open Agent Specification)
411
+ apiVersion: "v1"
412
+ kind: "Agent"
413
+ metadata:
414
+ name: "data-analysis-agent"
415
+ type: "smart_analysis"
416
+
417
+ # DACP automatically configures logging
418
+ logging:
419
+ enabled: true
420
+ level: "INFO"
421
+ format_style: "emoji"
422
+ log_file: "./logs/agent.log"
423
+ env_overrides:
424
+ level: "DACP_LOG_LEVEL"
425
+
426
+ # Multi-provider intelligence configuration
427
+ intelligence:
428
+ engine: "anthropic"
429
+ model: "claude-3-haiku-20240618"
430
+ # API key from environment: ANTHROPIC_API_KEY
431
+
432
+ # Define agent capabilities
433
+ capabilities:
434
+ - name: "analyze_data"
435
+ description: "Analyze datasets and generate insights"
436
+ - name: "generate_report"
437
+ description: "Generate analysis reports"
438
+ ```
439
+
440
+ #### Generated Agent Code (OAS Pattern)
441
+
442
+ ```python
443
+ # Generated by OAS with DACP integration
444
+ import dacp
445
+ import yaml
446
+
447
+ class DataAnalysisAgent(dacp.Agent):
448
+ def __init__(self, config_path="agent_config.yaml"):
449
+ # DACP auto-configures logging from YAML
450
+ with open(config_path, 'r') as f:
451
+ self.config = yaml.safe_load(f)
452
+
453
+ # Automatic logging setup
454
+ self.setup_logging()
455
+
456
+ # Load intelligence configuration
457
+ self.intelligence_config = self.config.get('intelligence', {})
458
+
459
+ def setup_logging(self):
460
+ """Auto-configure DACP logging from YAML config."""
461
+ logging_config = self.config.get('logging', {})
462
+ if logging_config.get('enabled', False):
463
+ dacp.setup_dacp_logging(
464
+ level=logging_config.get('level', 'INFO'),
465
+ format_style=logging_config.get('format_style', 'emoji'),
466
+ log_file=logging_config.get('log_file')
467
+ )
468
+
469
+ def handle_message(self, message):
470
+ """Handle capabilities defined in YAML."""
471
+ task = message.get("task")
472
+
473
+ if task == "analyze_data":
474
+ return self.analyze_data(message)
475
+ elif task == "generate_report":
476
+ return self.generate_report(message)
477
+ else:
478
+ return {"error": f"Unknown task: {task}"}
479
+
480
+ def analyze_data(self, message):
481
+ """Analyze data using configured intelligence provider."""
482
+ data = message.get("data", "No data provided")
483
+
484
+ try:
485
+ result = dacp.invoke_intelligence(
486
+ f"Analyze this data and provide insights: {data}",
487
+ self.intelligence_config
488
+ )
489
+ return {"response": result}
490
+ except Exception as e:
491
+ return {"error": f"Analysis failed: {e}"}
492
+
493
+ def generate_report(self, message):
494
+ """Generate reports using DACP's file_writer tool."""
495
+ subject = message.get("subject", "report")
496
+ data = message.get("data", "No data")
497
+
498
+ return {
499
+ "tool_request": {
500
+ "name": "file_writer",
501
+ "args": {
502
+ "path": f"./reports/{subject}.txt",
503
+ "content": f"# Analysis Report: {subject}\n\nData: {data}\n"
504
+ }
505
+ }
506
+ }
507
+
508
+ # Auto-generated main function
509
+ def main():
510
+ # Zero-configuration setup
511
+ orchestrator = dacp.Orchestrator()
512
+ agent = DataAnalysisAgent()
513
+ orchestrator.register_agent("data-analysis-agent", agent)
514
+
515
+ print("🚀 OAS Agent running with DACP integration!")
516
+ # Agent ready for messages via orchestrator
517
+
518
+ if __name__ == "__main__":
519
+ main()
520
+ ```
521
+
522
+ #### OAS Benefits
523
+
524
+ - ✅ **Zero Configuration**: Logging and intelligence work out of the box
525
+ - ✅ **YAML-Driven**: All configuration in standard OAS YAML format
526
+ - ✅ **Auto-Generated**: Complete agents generated from specifications
527
+ - ✅ **Environment Overrides**: Runtime configuration via environment variables
528
+ - ✅ **Standardized**: Consistent interface across all OAS agents
529
+
530
+ ### Independent Client Usage
531
+
532
+ **For independent developers:** Use DACP directly as a flexible agent router and orchestration platform.
533
+
534
+ #### Direct Integration Pattern
535
+
536
+ ```python
537
+ import dacp
538
+ import os
539
+
540
+ class MyCustomAgent(dacp.Agent):
541
+ """Independent client's custom agent."""
542
+
543
+ def __init__(self):
544
+ # Manual setup - full control
545
+ self.setup_intelligence()
546
+ self.setup_logging()
547
+
548
+ def setup_intelligence(self):
549
+ """Configure intelligence providers manually."""
550
+ self.intelligence_configs = {
551
+ "research": {
552
+ "engine": "openai",
553
+ "model": "gpt-4",
554
+ "api_key": os.getenv("OPENAI_API_KEY")
555
+ },
556
+ "analysis": {
557
+ "engine": "anthropic",
558
+ "model": "claude-3-sonnet-20240229",
559
+ "api_key": os.getenv("ANTHROPIC_API_KEY")
560
+ },
561
+ "local": {
562
+ "engine": "local",
563
+ "model": "llama2",
564
+ "endpoint": "http://localhost:11434/api/generate"
565
+ }
566
+ }
567
+
568
+ def setup_logging(self):
569
+ """Configure logging manually."""
570
+ dacp.enable_info_logging(log_file="./logs/custom_agent.log")
571
+
572
+ def handle_message(self, message):
573
+ """Custom business logic."""
574
+ task = message.get("task")
575
+
576
+ if task == "research_topic":
577
+ return self.research_with_multiple_llms(message)
578
+ elif task == "process_data":
579
+ return self.multi_step_processing(message)
580
+ elif task == "custom_workflow":
581
+ return self.handle_custom_workflow(message)
582
+ else:
583
+ return {"error": f"Unknown task: {task}"}
584
+
585
+ def research_with_multiple_llms(self, message):
586
+ """Use multiple LLM providers for comprehensive research."""
587
+ topic = message.get("topic", "AI Research")
588
+
589
+ # Use different LLMs for different aspects
590
+ research_prompt = f"Research the topic: {topic}"
591
+ analysis_prompt = f"Analyze research findings for: {topic}"
592
+
593
+ try:
594
+ # Research with GPT-4
595
+ research = dacp.invoke_intelligence(
596
+ research_prompt,
597
+ self.intelligence_configs["research"]
598
+ )
599
+
600
+ # Analysis with Claude
601
+ analysis = dacp.invoke_intelligence(
602
+ f"Analyze: {research}",
603
+ self.intelligence_configs["analysis"]
604
+ )
605
+
606
+ return {
607
+ "research": research,
608
+ "analysis": analysis,
609
+ "status": "completed"
610
+ }
611
+ except Exception as e:
612
+ return {"error": f"Research failed: {e}"}
613
+
614
+ def multi_step_processing(self, message):
615
+ """Multi-step workflow with tool chaining."""
616
+ data = message.get("data", "sample data")
617
+
618
+ # Step 1: Process and save data
619
+ return {
620
+ "tool_request": {
621
+ "name": "file_writer",
622
+ "args": {
623
+ "path": "./processing/input_data.txt",
624
+ "content": f"Raw data: {data}\nProcessed at: {dacp.time.time()}"
625
+ }
626
+ }
627
+ }
628
+ # In real implementation, would continue workflow in subsequent messages
629
+
630
+ # Independent client setup
631
+ def main():
632
+ # Manual orchestrator setup
633
+ orchestrator = dacp.Orchestrator()
634
+
635
+ # Register multiple custom agents
636
+ research_agent = MyCustomAgent()
637
+ data_agent = MyCustomAgent()
638
+ workflow_agent = MyCustomAgent()
639
+
640
+ orchestrator.register_agent("researcher", research_agent)
641
+ orchestrator.register_agent("processor", data_agent)
642
+ orchestrator.register_agent("workflow", workflow_agent)
643
+
644
+ # Direct control over routing
645
+ print("🚀 Independent client agents running!")
646
+
647
+ # Example: Route complex task across multiple agents
648
+ research_result = orchestrator.send_message("researcher", {
649
+ "task": "research_topic",
650
+ "topic": "Multi-Agent Systems"
651
+ })
652
+
653
+ processing_result = orchestrator.send_message("processor", {
654
+ "task": "process_data",
655
+ "data": research_result
656
+ })
657
+
658
+ # Broadcast updates to all agents
659
+ orchestrator.broadcast_message({
660
+ "task": "status_update",
661
+ "message": "Workflow completed"
662
+ })
663
+
664
+ if __name__ == "__main__":
665
+ main()
666
+ ```
667
+
668
+ #### Advanced Independent Usage
669
+
670
+ ```python
671
+ # Register custom tools for specialized business logic
672
+ def custom_data_processor(args):
673
+ """Client's proprietary data processing tool."""
674
+ data = args.get("data", [])
675
+ algorithm = args.get("algorithm", "default")
676
+
677
+ # Custom processing logic
678
+ processed = [item * 2 for item in data if isinstance(item, (int, float))]
679
+
680
+ return {
681
+ "success": True,
682
+ "processed_data": processed,
683
+ "algorithm_used": algorithm,
684
+ "count": len(processed)
685
+ }
686
+
687
+ # Register with DACP
688
+ dacp.register_tool("custom_processor", custom_data_processor)
689
+
690
+ # Use in agents
691
+ class SpecializedAgent(dacp.Agent):
692
+ def handle_message(self, message):
693
+ if message.get("task") == "process_with_custom_tool":
694
+ return {
695
+ "tool_request": {
696
+ "name": "custom_processor",
697
+ "args": {
698
+ "data": message.get("data", []),
699
+ "algorithm": "proprietary_v2"
700
+ }
701
+ }
702
+ }
703
+ ```
704
+
705
+ #### Independent Client Benefits
706
+
707
+ - ✅ **Full Control**: Manual configuration of all components
708
+ - ✅ **Flexible Architecture**: Design your own agent interactions
709
+ - ✅ **Custom Tools**: Register proprietary business logic tools
710
+ - ✅ **Multi-Provider**: Use different LLMs for different tasks
711
+ - ✅ **Direct API Access**: Call DACP functions directly when needed
712
+ - ✅ **Complex Workflows**: Build sophisticated multi-agent orchestrations
713
+
714
+ ### Choosing Your Pattern
715
+
716
+ | Feature | OAS Integration | Independent Client |
717
+ |---------|----------------|-------------------|
718
+ | **Setup Complexity** | Minimal (auto-generated) | Manual (full control) |
719
+ | **Configuration** | YAML-driven | Programmatic |
720
+ | **Agent Generation** | Automatic from spec | Manual implementation |
721
+ | **Customization** | Template-based | Unlimited flexibility |
722
+ | **Best For** | Rapid prototyping, standard agents | Complex workflows, custom logic |
723
+ | **Learning Curve** | Low | Medium |
724
+
725
+ ### Getting Started
726
+
727
+ **For OAS Integration:**
728
+ 1. Add DACP logging section to your YAML spec
729
+ 2. Generate agents with DACP base class
730
+ 3. Agents work with zero additional configuration
731
+
732
+ **For Independent Usage:**
733
+ 1. `pip install dacp`
734
+ 2. Create agents inheriting from `dacp.Agent`
735
+ 3. Register with `dacp.Orchestrator()`
736
+ 4. Build your custom workflows
737
+
738
+ Both patterns provide full access to DACP's capabilities: multi-provider LLM routing, tool execution, comprehensive logging, conversation history, and multi-agent orchestration.
739
+
399
740
  ## Development
400
741
 
401
742
  ```bash