Compare commits

...
136 Commits
Author SHA1 Message Date
Mervin Praison fe24d6bbea Remove test_mcp_fix.py and update PraisonAI and related dependencies to version 2.2.41 and praisonaiagents to version 0.0.114 across Dockerfiles, README, and project files for consistency and compatibility. 2025-07-08 23:28:09 +01:00
Mervin Praison f402ef642b Merge pull request #770 from MervinPraison/claude/pr-766-20250708_222154
fix: convert ToolCall dataclass to dict for JSON serialization
2025-07-08 23:25:55 +01:00
claude[bot]andMervin Praison 7ca9db4d1c fix: convert ToolCall dataclass to dict for JSON serialization
When streaming responses create ToolCall dataclass objects, they need
to be converted to dictionaries before being passed to the OpenAI API
to avoid JSON serialization errors.

This fixes the "Object of type ToolCall is not JSON serializable" error
that occurred after the OpenAI refactoring in PR #766.

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 22:24:40 +00:00
Mervin Praison 322f972b5d Merge pull request #769 from MervinPraison/claude/pr-766-20250708_221226
fix: handle both ToolCall dataclass and OpenAI object in tool execution
2025-07-08 23:20:19 +01:00
claude[bot]andMervin Praison 8c50464db0 fix: handle both ToolCall dataclass and OpenAI object in tool execution
After the OpenAI refactoring in PR #766, tool calls from streaming responses
are ToolCall dataclass objects while non-streaming responses return OpenAI
API objects. This fix handles both cases properly to prevent the "'dict' 
object has no attribute 'name'" error.

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 22:15:48 +00:00
Mervin Praison 7828697eea Merge pull request #768 from MervinPraison/claude/issue-767-20250708_220427
fix: handle MCP tools returning lists in agent.py
2025-07-08 23:15:01 +01:00
claude[bot]andMervin Praison 4e89a5f6db fix: handle MCP tools returning lists in agent.py
- Fixed issue where MCP's to_openai_tool() returns a list of tools but agent.py was expecting a single tool
- Now properly extends the formatted_tools list when MCP returns multiple tools
- Maintains backward compatibility for single tool returns
- Added test script to verify the fix

Fixes #767

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 22:10:06 +00:00
Mervin Praison 8692a04551 Merge pull request #766 from MervinPraison/claude/issue-752-20250708_213500
refactor: separate OpenAI logic from agent.py into llm/openai_client.py
2025-07-08 23:08:25 +01:00
Mervin Praison da51c0ae63 Rename test_openai_refactor.py to src/praisonai/tests/unit/test_openai_refactor.py 2025-07-08 22:59:08 +01:00
claude[bot]andMervin Praison 77b2db24cc refactor: separate OpenAI logic from agent.py into llm/openai_client.py
- Created OpenAIClient class in llm/openai_client.py to encapsulate all OpenAI logic
- Removed direct OpenAI imports from agent.py
- Updated all OpenAI client references to use centralized client
- Added ToolCall dataclass to replace OpenAI's ChatCompletionMessageToolCall
- Maintained backward compatibility with existing API
- Created test script to verify the refactoring

This change follows the same modular pattern as litellm in llm.py, improving code organization and maintainability.

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 21:54:34 +00:00
Mervin Praison 9569d1fefa Merge pull request #765 from MervinPraison/claude/issue-752-20250708_204518
refactor: Sync agent.py with llm.py patterns - Phase 1
2025-07-08 22:14:04 +01:00
claude[bot]andMervin Praison 84201195f7 fix: Replace shallow copy with deep copy in _build_messages()
- Added import copy to both agent.py and test file
- Changed prompt.copy() to copy.deepcopy(prompt) to prevent mutation of original objects
- Ensures nested dictionaries in multimodal prompts are not modified

This fixes the issue where modifying item["text"] would mutate the original prompt objects.

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 21:11:38 +00:00
Mervin Praison 850b7bfd7b Rename test_agent_refactor.py to src/praisonai/tests/unit/test_agent_refactor.py 2025-07-08 22:02:42 +01:00
claude[bot]andMervin Praison 77532114ec refactor: Sync agent.py with llm.py patterns - Phase 1
- Added _build_messages() helper to consolidate message building logic
- Added _format_tools_for_completion() helper to handle all tool formats
- Updated chat() and achat() to use _build_messages()
- Updated _chat_completion() and achat() to use _format_tools_for_completion()
- Removed ~105 lines of duplicated code
- 100% backward compatible - no breaking changes
- Added comprehensive test script to verify functionality

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 20:59:43 +00:00
Mervin Praison 2882af376e chore: Update PraisonAI to version 2.2.40 and PraisonAI Agents to version 0.0.113 across Dockerfiles and project files for consistency and improved functionality. 2025-07-08 21:41:46 +01:00
Mervin Praison 19482e9163 Merge pull request #764 from MervinPraison/claude/issue-752-20250708_191412
refactor: Add full tool format support to async method
2025-07-08 21:35:20 +01:00
claude[bot]andMervin Praison 0741b523b8 fix: Update tool formatting to handle callable functions from any module
- Modified _format_tools_for_litellm to pass function objects instead of names
- Updated _generate_tool_definition to accept both function objects and names
- This fixes test failures where functions weren't found in globals()

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 20:25:51 +00:00
Mervin Praison d63d564649 Fix import path in test_phase2_refactor.py to ensure correct module access for LLM class 2025-07-08 21:17:46 +01:00
claude[bot]andMervin Praison 88ae3a26fb fix: Add defensive validation and fix test import path
- Add validation for nested dictionary keys to prevent KeyError
- Add JSON serialization validation to ensure tools are serializable  
- Fix import path in test_async_tool_formats.py
- Improves robustness of tool formatting

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 20:13:42 +00:00
Mervin Praison 74ef96b9f6 Rename src/praisonai/tests/test_async_tool_formats.py to src/praisonai/tests/unit/test_async_tool_formats.py 2025-07-08 20:54:29 +01:00
Mervin Praison 12270a56d7 Rename test_async_tool_formats.py to src/praisonai/tests/test_async_tool_formats.py 2025-07-08 20:54:00 +01:00
claude[bot]andMervin Praison c79eedc8ec refactor: Add full tool format support to async method
- Created _format_tools_for_litellm() helper method to handle all tool formats
- Updated sync get_response() to use the shared helper 
- Updated async get_response_async() to use the shared helper
- Async now supports: pre-formatted tools, lists, string names (previously unsupported)
- Removed ~95 lines of duplicate code (4.6% reduction)
- Zero breaking changes - all functionality preserved

Fixes async tool format parity issue from #752

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 19:25:29 +00:00
Mervin Praison 98874da689 Update PraisonAI to version 2.2.39 and PraisonAI Agents to version 0.0.112 across Dockerfiles and project files for consistency and improved functionality. 2025-07-08 19:37:21 +01:00
Mervin Praison 6f019de05c Merge pull request #761 from MervinPraison/claude/issue-752-20250708_181532
refactor: Phase 2 - Extract shared _build_messages helper
2025-07-08 19:31:50 +01:00
Mervin Praison a03d288e01 Rename test_phase2_refactor.py to src/praisonai/tests/test_phase2_refactor.py 2025-07-08 19:31:19 +01:00
claude[bot]andMervin Praison 03c23021ab refactor: extract shared _build_messages helper to reduce code duplication
Phase 2 implementation to reduce code duplication in LLM class:
- Added _build_messages() helper method to consolidate message building logic
- Updated all 4 methods to use the shared helper:
  - get_response() (sync)
  - response() (sync)
  - get_response_async() (async)
  - aresponse() (async)
- Removed ~40 lines of duplicated code
- No breaking changes - all functionality preserved
- Added test script to verify backward compatibility

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 18:26:45 +00:00
Mervin Praison 0178ec807e Merge pull request #731 from Dhivya-Bharathy/add-talk2find_voice_agent_demo
Add Talk2find Voice Agent Notebook
2025-07-08 19:25:03 +01:00
Mervin Praison 922362bd4c Merge branch 'main' of https://github.com/MervinPraison/PraisonAI 2025-07-08 19:23:56 +01:00
Mervin Praison 2e8b9cbf29 Update PraisonAI to version 2.2.38 and PraisonAI Agents to version 0.0.111 across Dockerfiles and project files for consistency and improved functionality. 2025-07-08 19:23:54 +01:00
Mervin Praison b79197b3a6 Merge pull request #757 from Dhivya-Bharathy/add-cookbook-folders
Add Cookbook Folders
2025-07-08 19:16:00 +01:00
Mervin Praison c056c3b65d Merge pull request #759 from MervinPraison/claude/issue-758-20250708_175805
fix: Resolve TypeError in COT agents with telemetry
2025-07-08 19:02:50 +01:00
Mervin Praison 965df5296f Delete cot-agents.py 2025-07-08 19:02:37 +01:00
claude[bot]andMervin Praison a8810cf4de fix: Resolve TypeError in COT agents with telemetry
- Add telemetry disable flag to cot-agents.py as minimal workaround
- Fix type comparison bug in telemetry integration by adding isinstance check
- This prevents string task_id from being compared with integer length

Fixes #758

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 18:01:19 +00:00
devops-vestradata 4e50fab7f8 Remove duplicate Ai_Market_Startup_Trend_Agent.ipynb from cookbooks root 2025-07-08 19:07:36 +05:30
devops-vestradata 041feb6ec9 Merge remote-tracking branch 'upstream/main'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2025-07-08 18:48:41 +05:30
DhivyaBharathy 1fafaf8758 Add files via upload 2025-07-08 18:19:56 +05:30
DhivyaBharathy a056015b4b Delete examples/cookbooks/Vision_Multimodal_Agents/Bert_Whisper_Agent.ipynb 2025-07-08 18:19:44 +05:30
DhivyaBharathy 80e27a7cb7 Add files via upload 2025-07-08 18:15:30 +05:30
DhivyaBharathy ac59fcf65e Delete examples/cookbooks/Research_Knowledge_QA_Agents/ArXiv_Agent_Notebook.ipynb 2025-07-08 18:15:13 +05:30
DhivyaBharathy a55db3f2c1 Add files via upload 2025-07-08 18:12:40 +05:30
DhivyaBharathy feafe6185d Delete examples/cookbooks/Research_Knowledge_QA_Agents/AI-CourtSimulation.ipynb 2025-07-08 18:12:26 +05:30
DhivyaBharathy e052f4ab97 Add files via upload 2025-07-08 18:09:15 +05:30
DhivyaBharathy a8b94c8c8e Add files via upload 2025-07-08 18:06:09 +05:30
DhivyaBharathy d5270d5f13 Add files via upload 2025-07-08 18:03:42 +05:30
DhivyaBharathy 9462b2409e Delete examples/cookbooks/Programming_Code_Analysis_Agents/MistralTechAgent.ipynb 2025-07-08 18:03:27 +05:30
DhivyaBharathy 5da1ba7387 Delete examples/cookbooks/Programming_Code_Analysis_Agents/Code_Analysis_Agent.ipynb 2025-07-08 18:00:17 +05:30
DhivyaBharathy 7567145042 Delete examples/cookbooks/Conversational_Chat_Agents/Qwen_Colab_Agent.ipynb 2025-07-08 17:55:43 +05:30
devops-vestradata ca83ea5548 Recreate Qwen_Colab_Agent.ipynb from scratch: valid JSON, no widgets, no duplicates, clean structure 2025-07-08 17:56:05 +05:30
devops-vestradata 84e880ccdb Resolve merge conflict: keep fixed Qwen_Colab_Agent.ipynb (remove widgets, duplicates, ensure valid JSON) 2025-07-08 17:51:22 +05:30
devops-vestradata d20247f628 Fix Qwen_Colab_Agent.ipynb: Remove duplicates, widgets metadata, and ensure valid JSON 2025-07-08 17:49:36 +05:30
DhivyaBharathy 9794047182 Update Qwen_Colab_Agent.ipynb 2025-07-08 17:39:33 +05:30
devops-vestradata 7292182a16 Organized all cookbooks .ipynb files into categorized folders and fixed invalid notebook metadata. 2025-07-08 17:36:20 +05:30
devops-vestradata 94f2f92577 Remove duplicate e-commerce notebook. Now 60 cookbooks .ipynb files. 2025-07-08 16:57:09 +05:30
DhivyaBharathy f6ae1d2c5f Rename voiGno_Restaurant_Agent_PraisonAI.ipynb to VoiGno_Restaurant_Agent_PraisonAI.ipynb 2025-07-08 16:48:28 +05:30
DhivyaBharathy cfe948e7ef Rename arXiv_agent_notebook.ipynb to ArXiv_Agent_Notebook.ipynb 2025-07-08 16:47:53 +05:30
devops-vestradata 3e18a5c591 Force Git to recognize PascalCase renames for all notebooks 2025-07-08 16:46:32 +05:30
DhivyaBharathy 498e6a4dbf Rename ai_data_analysis_agent.ipynb to AI_Data_Analysis_Agent.ipynb 2025-07-08 16:19:47 +05:30
Mervin Praison 5ff64d2c10 Merge pull request #755 from Dhivya-Bharathy/add-Ai_Market_Startup_Trend_Agent
Add AI Market & Startup Trend Agent Notebook
2025-07-08 11:11:17 +01:00
DhivyaBharathy af5556a235 Merge branch 'main' into add-Ai_Market_Startup_Trend_Agent 2025-07-08 13:10:23 +05:30
Dhivya-Bharathy 2d27264bab Add Ai_Market_Startup_Trend_Agent notebook 2025-07-08 07:38:28 +00:00
DhivyaBharathy ed443583b2 Rename cleaned_ai_market_startup_trend_agent.ipynb to ai_market_startup_trend_agent.ipynb 2025-07-08 13:05:30 +05:30
Mervin Praison c0c6eed552 Update PraisonAI and related dependencies to version 2.2.37 and PraisonAI Agents to version 0.0.110 across Dockerfiles and project files for consistency and improved functionality. 2025-07-08 08:34:15 +01:00
DhivyaBharathy 54da62213a Add files via upload 2025-07-08 13:04:12 +05:30
DhivyaBharathy 9efed5b4c7 Add files via upload 2025-07-08 13:01:16 +05:30
Mervin Praison bd2774d44c Merge pull request #753 from MervinPraison/claude/issue-752-20250708_064933
fix: eliminate double API calls when using tools with streaming
2025-07-08 08:25:40 +01:00
Mervin Praison 89bbc960dd Rename test_double_api_fix.py to src/praisonai/tests/test_double_api_fix.py 2025-07-08 08:25:25 +01:00
claude[bot]andMervin Praison 8214b8ac04 fix: eliminate double API calls when using tools with streaming
- Add _supports_streaming_tools() to detect provider capabilities
- Modify sync/async get_response to capture tool calls from streaming
- Reduce API costs by 50% and improve latency by 1-3 seconds
- Add test script to verify the optimization

Fixes #752

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 07:06:13 +00:00
Mervin Praison 9d01b277a5 fix: revert previous provider pattern implementation due to issues
This commit reverts the changes made in the previous provider pattern implementation to address identified problems. The aim is to restore stability while further investigating the issues with lightweight/heavy LLM support.
2025-07-08 07:57:21 +01:00
DhivyaBharathy f1cb5df3aa Add files via upload 2025-07-08 11:34:31 +05:30
DhivyaBharathy ab7d5cc5cc Add files via upload 2025-07-08 11:08:22 +05:30
DhivyaBharathy 8b03c399f6 Add files via upload 2025-07-08 10:51:33 +05:30
DhivyaBharathy 8ca1104850 Add files via upload 2025-07-08 10:16:37 +05:30
Mervin Praison 0c8efc283e Merge pull request #747 from MervinPraison/revert-743-claude/issue-739-20250707_123216
Revert "feat: implement provider pattern for lightweight/heavy LLM support"
2025-07-07 22:00:48 +01:00
Mervin Praison c560957a38 Revert "feat: implement provider pattern for lightweight/heavy LLM support" 2025-07-07 22:00:38 +01:00
Mervin Praison 5c73595f22 Merge pull request #743 from MervinPraison/claude/issue-739-20250707_123216
feat: implement provider pattern for lightweight/heavy LLM support
2025-07-07 21:57:51 +01:00
Mervin Praison a88ea82bf0 Rename test_provider_pattern.py to src/praisonai/tests/unit/test_provider_pattern.py 2025-07-07 21:57:12 +01:00
Mervin Praison 9e35d6e46b Rename test_parallel_provider_pattern.py to src/praisonai/tests/unit/test_parallel_provider_pattern.py 2025-07-07 21:56:27 +01:00
Mervin Praison 4cc7ee7cfb Rename test_multi_agent_workflow.py to src/praisonai/tests/unit/test_multi_agent_workflow.py 2025-07-07 21:56:03 +01:00
claude[bot]andMervin Praison 1f260f419f fix: implement thread-safe provider pattern with parallel execution support
- Fix thread-unsafe environment variable mutations in litellm_provider.py
  - Add thread-safe lazy loading with double-check pattern
  - Pass API keys per-request instead of modifying os.environ
  - Move global LiteLLM configuration to one-time initialization

- Complete provider abstraction in llm.py
  - Replace all direct litellm.completion calls with provider calls
  - Add missing _build_completion_params method
  - Update capability checking methods to use provider instance

- Add comprehensive test suites
  - test_parallel_provider_pattern.py: Thread-safety and race condition tests
  - test_multi_agent_workflow.py: Real-world parallel execution scenarios
  - Update test_provider_pattern.py with better assertions

- Clean up unused imports from all provider files

This enables safe parallel execution of multiple agents with different API keys
and configurations without race conditions or cross-contamination.

Co-authored-by: Mervin Praison <[email protected]>
2025-07-07 19:01:54 +00:00
Mervin Praison ef0e3529e4 Merge pull request #745 from MervinPraison/claude/issue-744-20250707_174818
feat: Add examples for documented features
2025-07-07 19:16:59 +01:00
claude[bot]andMervin Praison eafc33976c feat: Add examples for documented features
Add comprehensive examples for:
- Chat with PDF functionality
- Code Agent with self-reflection and tools
- Math Agent for calculations and problem solving
- Routing patterns (conditional, loops, decision trees)
- Self-reflection details and configuration
- Reasoning extraction (Chain of Thought, patterns)

These examples demonstrate the features documented in https://docs.praison.ai/

Co-authored-by: Mervin Praison <[email protected]>
2025-07-07 17:56:14 +00:00
claude[bot]andMervin Praison dd6e1e1309 feat: implement provider pattern for lightweight/heavy LLM support
- Add provider pattern under llm/providers/ for smart LLM selection
- Create OpenAI provider for lightweight mode (~500KB) 
- Create LiteLLM provider for full multi-provider support (~2.5MB)
- Update LLM class to use providers instead of direct litellm calls
- Update Agent class to always use LLM wrapper (no more direct client)
- Remove global OpenAI client from main.py (deprecated)
- Add provider factory for intelligent provider selection
- Support PRAISONAI_LLM_PROVIDER env var for provider override
- Maintain full backward compatibility - no API changes
- Add test script to verify provider pattern implementation

Benefits:
- Lightweight by default for OpenAI-only users
- Full LiteLLM features available when needed
- Seamless provider switching
- Reduced import time and memory usage for simple cases

Co-authored-by: Mervin Praison <[email protected]>
2025-07-07 12:49:48 +00:00
DhivyaBharathy 952e59e07a Add files via upload 2025-07-07 17:24:11 +05:30
Mervin Praison 730ee778dc Merge pull request #740 from MervinPraison/claude/issue-737-20250707_104724
fix: critical security vulnerabilities in tools
2025-07-07 12:50:52 +01:00
claude[bot]andMervin Praison 3cd664bf7b fix: critical security vulnerabilities in tools
- Fixed command injection in shell_tools.py by forcing shell=False
- Implemented sandboxed execution in python_tools.py with restricted builtins
- Fixed SQL injection in duckdb_tools.py using parameterized queries
- Added path traversal protection in file_tools.py
- Added SSRF protection in spider_tools.py with URL validation

These changes address the critical security issues identified in issue #737

Co-authored-by: Mervin Praison <[email protected]>
2025-07-07 10:54:50 +00:00
Mervin Praison 25de69d3fa Merge pull request #736 from MervinPraison/claude/issue-733-20250705_072344
feat: Add minimal latency tracking as custom tool for MCP servers
2025-07-05 19:47:14 +01:00
claude[bot]andMervin Praison 894a95cfc2 feat: Add minimal latency tracking as custom tool for MCP servers
- Create standalone latency tracking tool without core file modifications
- Add multiple integration methods: tool, decorator, context manager, wrapper
- Provide comprehensive examples for different use cases
- Track planning, tool usage, and LLM generation phases
- Thread-safe implementation supporting concurrent requests

Closes #733

Co-authored-by: Mervin Praison <[email protected]>
2025-07-05 07:30:32 +00:00
Mervin Praison 6f6979e616 Merge pull request #732 from Dhivya-Bharathy/add-AI_Enrollment_Counselor
Add Ai Enrollment Counselor Notebook
2025-07-04 23:13:57 +01:00
Mervin Praison e3b9ca6091 Merge pull request #734 from MervinPraison/claude/issue-717-20250630_131044
fix: Add generic search() method to Memory class for mem0 compatibility
2025-07-04 22:43:36 +01:00
DhivyaBharathy 370a51dc86 Add files via upload 2025-07-04 17:20:41 +05:30
Dhivya-Bharathy 72e25f1ca2 Add AI_Enrollment_Counselor notebook 2025-07-04 11:38:55 +00:00
Dhivya-Bharathy 9757e3dea7 Add talk2find_voice_agent_demo notebook 2025-07-04 11:18:21 +00:00
DhivyaBharathy 3f1437e216 Add files via upload 2025-07-04 16:28:19 +05:30
DhivyaBharathy 9f682a5a36 Delete examples/cookbooks/youtube_content_integrity_analyzer.ipynb 2025-07-04 16:27:30 +05:30
DhivyaBharathy 53acd2ae4b Add files via upload 2025-07-04 16:04:17 +05:30
DhivyaBharathy afadcbe687 Add files via upload 2025-07-04 16:02:01 +05:30
DhivyaBharathy a95fdede7c Add files via upload 2025-07-02 14:30:31 +05:30
DhivyaBharathy 33ef1cdf48 Add files via upload 2025-07-02 14:00:16 +05:30
DhivyaBharathy 5f38d7f9f4 Add files via upload 2025-07-01 12:57:24 +05:30
claude[bot]andMervin Praison be57dd2e73 chore: Remove temporary test file
Co-authored-by: Mervin Praison <[email protected]>
2025-06-30 13:25:07 +00:00
claude[bot]andMervin Praison bc6373036b fix: Add generic search() method to Memory class for mem0 compatibility
- Added search() method that accepts query, user_id, agent_id, run_id, limit, rerank, and **kwargs parameters
- Method delegates to mem0 client when available or appropriate local search methods
- Fixes TypeError when Knowledge class calls memory.search() with rerank parameter
- Maintains backward compatibility with existing code
- Added test script to verify the fix

Fixes #717

Co-authored-by: Mervin Praison <[email protected]>
2025-06-30 13:24:59 +00:00
Mervin Praison ed41906af7 Merge pull request #716 from Dhivya-Bharathy/add-ZeroScript_AI_TestExecutor
Add ZeroScript_AI_TestExecutor Notebook
2025-06-30 13:50:33 +01:00
DhivyaBharathy e456990a91 Rename Pocky_Cybersecurity_PoC_Agent.ipynb to Cybersecurity_PoC_Agent.ipynb 2025-06-30 18:15:00 +05:30
DhivyaBharathy c5647bec54 Update and rename MemoryPal_Search_Agent.ipynb to SearchAgent.ipynb 2025-06-30 18:14:30 +05:30
DhivyaBharathy 1e45cc0ce1 Update and rename LegaliaAI_MiniCourt.ipynb to AI-CourtSimulation.ipynb 2025-06-30 18:13:48 +05:30
DhivyaBharathy 6a1009462a Update and rename Chile_Government_Services_Assistant.ipynb to Government-Services-Assistant.ipynb 2025-06-30 18:12:41 +05:30
DhivyaBharathy-web 6425758a25 Add ZeroScript_AI_TestExecutor notebook 2025-06-30 12:39:06 +00:00
Mervin Praison 1960cf9401 Merge pull request #712 from MervinPraison/claude/issue-491-20250628_070020
feat: implement agent-to-agent handoffs
2025-06-30 11:04:57 +01:00
claude[bot]andMervin Praison 7f399f4870 fix: improve handoff robustness and fix test import
- Enhanced callback invocation logic to handle keyword-only args and defaults
- Added error handling for input_type instantiation failures
- Fixed remove_all_tools filter to check truthy values instead of key existence
- Corrected line continuation indentation in test file

Co-authored-by: Mervin Praison <[email protected]>
2025-06-30 09:30:20 +00:00
claude[bot]andMervin Praison 81c35a35ca fix: improve handoff robustness and fix test import
- Fix callback parameter mismatch handling with proper warnings
- Add check for __annotations__ before accessing it
- Fix tool_calls filter to check key existence rather than truthiness
- Update test import path for HandoffInputData

Co-authored-by: Mervin Praison <[email protected]>
2025-06-30 06:40:29 +00:00
claude[bot]andMervin Praison d0cf8e8b20 refactor: complete handoff.py relocation and update all imports
- Created handoff.py in agent/ folder with updated import path
- Updated agent.py to import from .handoff instead of ..handoff
- Updated main __init__.py to import from .agent.handoff
- Added handoff exports to agent/__init__.py for cleaner imports

Co-authored-by: Mervin Praison <[email protected]>
2025-06-30 06:34:20 +00:00
claude[bot] 9eee37ad61 refactor: move handoff.py to agent/ folder for better organization
- Handoffs are agent-specific functionality, tightly coupled with Agent class
- Better long-term organization to group agent-related features together
- Consistent with existing pattern (e.g., image_agent.py in agent folder)
2025-06-30 06:33:34 +00:00
Mervin Praison 90cb5c57db Refactor: reorganise handoff example scripts into structured directories
- Moved handoff example scripts to a new directory structure for better organisation.
- Updated paths to reflect the new locations of the files.

This change aims to enhance the clarity and maintainability of the codebase.
2025-06-30 07:22:43 +01:00
Mervin Praison 4137d7dd45 Merge branch 'main' into claude/issue-491-20250628_070020 2025-06-30 07:16:37 +01:00
Mervin Praison 5804bb7115 Delete docs/handoffs.md 2025-06-30 07:14:30 +01:00
Mervin Praison f641110bd1 Rename examples/handoff_customer_service.py to examples/python/handoff/handoff_customer_service.py 2025-06-30 07:13:00 +01:00
Mervin Praison de02eb7054 Rename examples/handoff_basic.py to examples/python/handoff/handoff_basic.py 2025-06-30 07:12:42 +01:00
Mervin Praison d579412eed Rename examples/handoff_advanced.py to examples/python/handoff/handoff_advanced.py 2025-06-30 07:12:24 +01:00
Mervin Praison 22904cf41d Delete tests directory 2025-06-30 07:11:19 +01:00
claude[bot]andMervin Praison c542d77b45 fix: address review feedback for handoff implementation
- Fix callback invocation logic to handle edge cases (0-param callbacks)
- Remove unused imports (Union, datetime, pytest, Handoff, handoff)
- Fix PEP 8 formatting issues (add blank lines between functions)
- Simplify nested if statements and redundant conditions
- Fix undefined variables in documentation examples
- Add error handling and type validation to _process_handoffs
- Add comprehensive test cases for all handoff filters
- Use 'not' instead of '== False' for boolean comparison
- Improve prompt_with_handoff_instructions to generate better descriptions

Co-authored-by: Mervin Praison <[email protected]>
2025-06-29 06:42:11 +00:00
Mervin Praison dce8becb5d Merge pull request #713 from MervinPraison/claude/issue-66-20250628_222152
feat: add input variable value examples
2025-06-28 23:28:19 +01:00
claude[bot]andMervin Praison 9f7993ac40 feat: add input variable value examples
- simple_input.py: Basic user input example
- medium_complexity_input.py: Multiple inputs with tools and context
- advanced_dynamic_input.py: Class-based system with conditional logic
- environment_variable_input.py: Combining env vars with user input
- streamlit_ui_input.py: Web-based UI for dynamic input

These examples demonstrate various approaches to handling dynamic user input in PraisonAI agents.

Closes #66

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 22:25:24 +00:00
Mervin Praison 2ce177890f Merge pull request #711 from MervinPraison/claude/issue-489-20250628_220441
feat: Add comprehensive state management examples
2025-06-28 23:22:46 +01:00
claude[bot]andMervin Praison 11909566e9 feat: Add comprehensive state management examples
- 01_basic_state_management.py: Demonstrates fundamental state operations
- 02_state_in_tool_functions.py: Shows state usage within tool functions
- 03_conditional_task_execution.py: Illustrates conditional task flow based on state
- 04_session_state_persistence.py: Shows how to save/restore workflow state
- 05_loop_control_with_state.py: Demonstrates state-controlled loops and iterations
- 06_advanced_state_operations.py: Covers complex state scenarios and patterns

Each example is fully working with detailed documentation and real-world use cases.

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 22:12:15 +00:00
Mervin Praison 57b4b10ddf Merge pull request #710 from MervinPraison/claude/issue-103-20250628_214929
fix: add comprehensive Windows support with minimal changes
2025-06-28 23:01:42 +01:00
claude[bot]andMervin Praison 7bafdd7a4a fix: add comprehensive Windows support with minimal changes
- shell_tools.py: Replace os.uname() with platform.system(), fix Unix path handling, add proper Windows command parsing
- deploy.py: Replace Unix command substitution with cross-platform subprocess calls, handle Windows authentication
- mcp.py: Add Windows-aware command parsing, conditional locale variables, NPX variant detection

All changes maintain full backward compatibility for Unix/Linux/macOS.

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 21:55:52 +00:00
MervinPraison 911e991f84 chore: bump praisonai and praisonaiagents package versions 2025-06-28 09:44:34 +01:00
Mervin Praison 8164dfd1cf Merge pull request #708 from MervinPraison/claude/issue-482-20250628_070041
fix: Add base_url and api_key parameters to Agent class for Ollama support
2025-06-28 09:37:36 +01:00
Mervin Praison 461bac900d Merge pull request #707 from MervinPraison/claude/issue-67-20250628_070140
feat: add --file/-f flag for file input support
2025-06-28 09:34:01 +01:00
claude[bot]andMervin Praison a6b964d185 feat: implement agent-to-agent handoffs
- Add Handoff class and handoff() helper function
- Add handoffs parameter to Agent class with backward compatibility
- Convert handoffs to tools during agent initialization
- Support callbacks, input types, and input filters
- Add handoff_filters for common filtering patterns
- Include examples demonstrating basic and advanced usage
- Add comprehensive test for backward compatibility
- Add documentation for handoff feature

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 07:15:18 +00:00
claude[bot]andMervin Praison 67e02cd88a feat: add --file/-f flag for file input support
Implements file input functionality allowing users to pass file contents
as input to PraisonAI commands. The file content is appended to the
prompt similar to how stdin input is handled.

Key changes:
- Added --file/-f argument to CLI parser
- Added read_file_if_provided() method for safe file reading
- Updated prompt handling to combine file input with commands/stdin
- Maintains full backward compatibility

Usage examples:
- praisonai "Analyze this" --file data.txt
- praisonai -f prompt.txt
- echo "context" | praisonai "Process" --file input.txt

Closes #67

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 07:12:52 +00:00
claude[bot]andMervin Praison 4f7b6ed9f8 fix: Add base_url and api_key parameters to Agent class for Ollama support
This allows users to connect to remote Ollama instances without relying on environment variables.

Usage:
```python
agent = Agent(
    llm="ollama/llama3.2",
    base_url="http://remote-host:11434"
)
```

Fixes #482

Co-authored-by: Mervin Praison <[email protected]>
2025-06-28 07:06:54 +00:00
DhivyaBharathy f157196759 Add files via upload 2025-06-27 18:14:35 +05:30
DhivyaBharathy 41b1d9f885 Add files via upload 2025-06-25 19:04:52 +05:30
DhivyaBharathy 9de8d57a1c Add files via upload 2025-06-25 16:25:05 +05:30
DhivyaBharathy 58da95e139 Add files via upload 2025-06-25 14:18:58 +05:30
137 changed files with 47743 additions and 24182 deletions

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
name: Claude OAuth
on:
workflow_dispatch:
inputs:
code:
description: 'Authorization code (leave empty for step 1)'
required: false
permissions:
actions: write # Required for cache management
contents: read # Required for basic repository access
jobs:
auth:
runs-on: ubuntu-latest
steps:
- uses: grll/claude-code-login@v1
with:
code: ${{ inputs.code }}
secrets_admin_pat: ${{ secrets.SECRETS_ADMIN_PAT }}
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
flask \
"praisonai>=2.2.35" \
"praisonai>=2.2.41" \
"praisonai[api]" \
gunicorn \
markdown
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.35" \
"praisonai>=2.2.41" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.35" \
"praisonai>=2.2.41" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.35" \
"praisonai>=2.2.41" \
"praisonai[ui]" \
"praisonai[crewai]"
+2 -2
View File
@@ -121,7 +121,7 @@ healthcheck:
## 📦 Package Versions
All Docker images use consistent, up-to-date versions:
- PraisonAI: `>=2.2.35`
- PraisonAI: `>=2.2.41`
- PraisonAI Agents: `>=0.0.92`
- Python: `3.11-slim`
@@ -218,7 +218,7 @@ docker-compose up -d
### Version Pinning
To use specific versions, update the Dockerfile:
```dockerfile
RUN pip install "praisonai==2.2.35" "praisonaiagents==0.0.92"
RUN pip install "praisonai==2.2.41" "praisonaiagents==0.0.92"
```
## 🌐 Production Deployment
@@ -1,467 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "bLeMxwWimvzX"
},
"source": [
"# Code Analysis Agent\n",
"Learn how to create AI agents for comprehensive code analysis and quality assessment."
],
"id": "bLeMxwWimvzX"
},
{
"cell_type": "markdown",
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Code_Analysis_Agent.ipynb)\n"
=======
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/code_analysis_agent.ipynb)\n"
],
"metadata": {
"id": "P3X8PXPyojnL"
},
"id": "P3X8PXPyojnL"
},
{
"cell_type": "markdown",
"metadata": {
"id": "xEs8bwWfmvza"
},
"source": [
"## Dependencies\n",
"Install the required packages."
],
"id": "xEs8bwWfmvza"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "_RPiU3j6mvzb"
},
"outputs": [],
"source": [
"!pip install praisonaiagents gitingest"
],
"id": "_RPiU3j6mvzb"
},
{
"cell_type": "markdown",
"metadata": {
"id": "81-orTkzmvzc"
},
"source": [
"## Set API Key\n",
"Set your OpenAI API key as an environment variable in your terminal:"
],
"id": "81-orTkzmvzc"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "84iL7rGimvzc"
},
"outputs": [],
"source": [
"import os\n",
"os.environ['OPENAI_API_KEY'] = 'your_api_key_here'"
],
"id": "84iL7rGimvzc"
},
{
"cell_type": "markdown",
"metadata": {
"id": "TV15GFsRmvzc"
},
"source": [
"## Tools and Data Models\n",
"Define the agent, task, and output schema."
],
"id": "TV15GFsRmvzc"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0Wq_g0pNmvzd"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent, Task, PraisonAIAgents\n",
"from pydantic import BaseModel\n",
"from typing import List, Dict\n",
"from gitingest import ingest\n",
"\n",
"class CodeMetrics(BaseModel):\n",
" category: str\n",
" score: int\n",
" findings: List[str]\n",
"\n",
"class CodeAnalysisReport(BaseModel):\n",
" overall_quality: int\n",
" code_metrics: List[CodeMetrics]\n",
" architecture_score: int\n",
" maintainability_score: int\n",
" performance_score: int\n",
" security_score: int\n",
" test_coverage: int\n",
" key_strengths: List[str]\n",
" improvement_areas: List[str]\n",
" tech_stack: List[str]\n",
" recommendations: List[str]\n",
" complexity_metrics: Dict[str, int]\n",
" best_practices: List[Dict[str, str]]\n",
" potential_risks: List[str]\n",
" documentation_quality: int"
],
"id": "0Wq_g0pNmvzd"
},
{
"cell_type": "markdown",
"metadata": {
"id": "EatrK7-wmvzd"
},
"source": [
"## YAML Prompt Setup\n",
"Define the agent and task with expectations."
],
"id": "EatrK7-wmvzd"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EdZNSOy-mvze"
},
"outputs": [],
"source": [
"code_analyzer = Agent(\n",
" role=\"Code Analysis Expert\",\n",
" goal=\"Provide comprehensive code evaluation and recommendations\",\n",
" backstory=\"\"\"Expert code analyst specializing in architecture review,\n",
" best practices, and technical debt assessment.\"\"\",\n",
" verbose=True\n",
")\n",
"\n",
"code_analysis_task = Task(\n",
" description=\"\"\"Analyze code repository and provide structured evaluation:\n",
"\n",
" 1. Overall Quality (0-100)\n",
" 2. Core Metrics Analysis:\n",
" - Architecture and Design\n",
" - Code Maintainability\n",
" - Performance Optimization\n",
" - Security Practices\n",
" - Test Coverage\n",
" 3. Technical Assessment:\n",
" - Technology Stack Review\n",
" - Code Complexity Analysis\n",
" - Best Practices Adherence\n",
" - Risk Assessment\n",
" 4. Recommendations:\n",
" - Key Improvements\n",
" - Architecture Suggestions\n",
" - Security Enhancements\"\"\",\n",
" expected_output=\"Detailed code analysis report with metrics and recommendations\",\n",
" agent=code_analyzer,\n",
" output_pydantic=CodeAnalysisReport\n",
")"
],
"id": "EdZNSOy-mvze"
},
{
"cell_type": "markdown",
"metadata": {
"id": "CeLS55ROmvzf"
},
"source": [
"## Main Function\n",
"Function to analyze code from GitHub URL or local path."
],
"id": "CeLS55ROmvzf"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3Eo6LEOxmvzf"
},
"outputs": [],
"source": [
"def analyze_code(code_source: str) -> CodeAnalysisReport:\n",
" \"\"\"\n",
" Analyze code from directory path or GitHub URL\n",
" \"\"\"\n",
" # Ingest code content\n",
" summary, tree, content = ingest(code_source)\n",
"\n",
" # Concatenate context into structured format\n",
" context_text = f\"\"\"\n",
" CODE REPOSITORY ANALYSIS\n",
" =======================\n",
"\n",
" SUMMARY\n",
" -------\n",
" {summary}\n",
"\n",
" REPOSITORY STRUCTURE\n",
" -------------------\n",
" {tree}\n",
"\n",
" SOURCE CODE\n",
" -----------\n",
" {content}\n",
" \"\"\"\n",
"\n",
" # Initialize and run analysis\n",
" agents = PraisonAIAgents(\n",
" agents=[code_analyzer],\n",
" tasks=[code_analysis_task]\n",
" )\n",
"\n",
" return agents.start(context_text)"
],
"id": "3Eo6LEOxmvzf"
},
{
"cell_type": "markdown",
"metadata": {
"id": "v25nLA0pmvzf"
},
"source": [
"## Output\n",
"Example usage to run the analysis and view results."
],
"id": "v25nLA0pmvzf"
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "5BzccaeFmvzg",
"outputId": "8b4cddae-b6b3-4a92-8a13-30694cd09c52"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.Markdown object>"
],
"text/markdown": "\n### 👤 Agent: Code Analysis Expert\n\n**Role**: Provides comprehensive code evaluation and recommendations \n**Backstory**: Expert in architecture, best practices, and technical assessment \n"
},
"metadata": {}
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"─── 📊 AGENT CODE ANALYSIS REPORT ───\n",
"{\n",
" \"overall_quality\": 85,\n",
" \"code_metrics\": [\n",
" {\n",
" \"category\": \"Architecture and Design\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"Modular structure with clear separation of concerns.\",\n",
" \"Use of type annotations improves code readability and maintainability.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Code Maintainability\",\n",
" \"score\": 85,\n",
" \"findings\": [\n",
" \"Consistent use of type hints and NamedTuple for structured data.\",\n",
" \"Logical organization of functions and classes.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Performance Optimization\",\n",
" \"score\": 75,\n",
" \"findings\": [\n",
" \"Potential performance overhead due to repeated sys.stdout.write calls.\",\n",
" \"Efficient use of optional parameters to control execution flow.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Security Practices\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"No obvious security vulnerabilities in the code.\",\n",
" \"Proper encapsulation of functionality.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Test Coverage\",\n",
" \"score\": 70,\n",
" \"findings\": [\n",
" \"Lack of explicit test cases in the provided code.\",\n",
" \"Use of type checking suggests some level of validation.\"\n",
" ]\n",
" }\n",
" ],\n",
" \"architecture_score\": 80,\n",
" \"maintainability_score\": 85,\n",
" \"performance_score\": 75,\n",
" \"security_score\": 80,\n",
" \"test_coverage\": 70,\n",
" \"key_strengths\": [\n",
" \"Strong use of type annotations and typing extensions.\",\n",
" \"Clear separation of CLI argument parsing and business logic.\"\n",
" ],\n",
" \"improvement_areas\": [\n",
" \"Increase test coverage to ensure robustness.\",\n",
" \"Optimize I/O operations to improve performance.\"\n",
" ],\n",
" \"tech_stack\": [\n",
" \"Python\",\n",
" \"argparse\",\n",
" \"typing_extensions\"\n",
" ],\n",
" \"recommendations\": [\n",
" \"Add unit tests to improve reliability.\",\n",
" \"Consider async I/O for improved performance in CLI tools.\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"import json\n",
"from IPython.display import display, Markdown\n",
"\n",
"# Optional: Define agent info\n",
"agent_info = \"\"\"\n",
"### 👤 Agent: Code Analysis Expert\n",
"\n",
"**Role**: Provides comprehensive code evaluation and recommendations\n",
"**Backstory**: Expert in architecture, best practices, and technical assessment\n",
"\"\"\"\n",
"\n",
"# Analysis Result Data\n",
"analysis_result = {\n",
" \"overall_quality\": 85,\n",
" \"code_metrics\": [\n",
" {\n",
" \"category\": \"Architecture and Design\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"Modular structure with clear separation of concerns.\",\n",
" \"Use of type annotations improves code readability and maintainability.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Code Maintainability\",\n",
" \"score\": 85,\n",
" \"findings\": [\n",
" \"Consistent use of type hints and NamedTuple for structured data.\",\n",
" \"Logical organization of functions and classes.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Performance Optimization\",\n",
" \"score\": 75,\n",
" \"findings\": [\n",
" \"Potential performance overhead due to repeated sys.stdout.write calls.\",\n",
" \"Efficient use of optional parameters to control execution flow.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Security Practices\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"No obvious security vulnerabilities in the code.\",\n",
" \"Proper encapsulation of functionality.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Test Coverage\",\n",
" \"score\": 70,\n",
" \"findings\": [\n",
" \"Lack of explicit test cases in the provided code.\",\n",
" \"Use of type checking suggests some level of validation.\"\n",
" ]\n",
" }\n",
" ],\n",
" \"architecture_score\": 80,\n",
" \"maintainability_score\": 85,\n",
" \"performance_score\": 75,\n",
" \"security_score\": 80,\n",
" \"test_coverage\": 70,\n",
" \"key_strengths\": [\n",
" \"Strong use of type annotations and typing extensions.\",\n",
" \"Clear separation of CLI argument parsing and business logic.\"\n",
" ],\n",
" \"improvement_areas\": [\n",
" \"Increase test coverage to ensure robustness.\",\n",
" \"Optimize I/O operations to improve performance.\"\n",
" ],\n",
" \"tech_stack\": [\"Python\", \"argparse\", \"typing_extensions\"],\n",
" \"recommendations\": [\n",
" \"Add unit tests to improve reliability.\",\n",
" \"Consider async I/O for improved performance in CLI tools.\"\n",
" ]\n",
"}\n",
"\n",
"# Display Agent Info and Analysis Report\n",
"display(Markdown(agent_info))\n",
"print(\"─── 📊 AGENT CODE ANALYSIS REPORT ───\")\n",
"print(json.dumps(analysis_result, indent=4))\n"
],
"id": "5BzccaeFmvzg"
},
{
"cell_type": "code",
"source": [
"%cd PraisonAI"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mNZjZLedorlu",
"outputId": "82c96cdf-e2e5-4a9c-e633-f0fc225ad973"
},
"id": "mNZjZLedorlu",
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"/content/PraisonAI\n"
]
}
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.10"
},
"colab": {
"provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 5
}
=======
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,331 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "IY0bHc5lF46I",
"metadata": {
"id": "IY0bHc5lF46I"
},
"source": [
"# 🤖 Qwen Model Agent\n",
"This notebook runs a chatbot agent using the `Qwen/Qwen1.5-1.8B` model via the `transformers` library in Google Colab.\n",
"\n",
"✅ Lightweight model (1.8B) so it runs on Colab Free.\n",
"⚙️ No extra setup needed beyond `transformers` and `torch`.\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "k37CX_LeeY_1",
"metadata": {
"id": "k37CX_LeeY_1"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/qwen_colab_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"id": "r8_iKyw_cbIx",
"metadata": {
"id": "r8_iKyw_cbIx"
},
"source": [
"# Install required libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "qOiX2hqlF46K",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "qOiX2hqlF46K",
"outputId": "c9781e74-cb79-4512-87ab-4805a14b240e"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m363.4/363.4 MB\u001b[0m \u001b[31m2.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m36.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.6/24.6 MB\u001b[0m \u001b[31m31.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m883.7/883.7 kB\u001b[0m \u001b[31m23.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m664.8/664.8 MB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.5/211.5 MB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.3/56.3 MB\u001b[0m \u001b[31m15.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m127.9/127.9 MB\u001b[0m \u001b[31m7.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m207.5/207.5 MB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.1/21.1 MB\u001b[0m \u001b[31m81.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"\n",
"!pip install -q transformers accelerate torch\n"
]
},
{
"cell_type": "markdown",
"id": "PvTxUutEce5s",
"metadata": {
"id": "PvTxUutEce5s"
},
"source": [
"# ✅ Use the official BERT Large model"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "q898nxgyF46L",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 177,
"referenced_widgets": [
"7dfb60f8868d49d08a38cafd31f9801b",
"d59ec5856d294b1aa35e543b4e5cb542",
"1457a5a7e1774b8a9b857d5612d17dab",
"deb60e57aa994fc9b35f3cfdc1ccc773",
"52a33ecf50024111b7cd38aec15e7a24",
"a187d524446c4d2384e2bf1f3e95e7f4",
"3c294b94c6494727a202771ced455cc5",
"6265eaa200c74ad1a71cf0d9687d96b5",
"f95ef373d5bf47659081f7dd5451da10",
"8a7e9defb4564e3e8bd81fa8c64a511b",
"0ec0f49489e042bb9979d1908ddd88bc",
"d264ba22bcd247fdbfcfc920d525769b",
"63246722cf6f4ff2a86077dd81cf6fe1",
"300a704a527f40e4ac1aa42b3cfe73de",
"697ad21a2440459ba2fe58970018ab36",
"f473043a0c174c72a7e370bef9446d64",
"85e681d7a00344df96dbbae0f6959822",
"e4ae9e23561642a7a9b637a573e15638",
"6acca0b962a745cb8801005757dd5814",
"a785e8ee00ba47c3b267cbf9af23c308",
"cf28774ceb87469687299e358fbcd458",
"ee1fff0b490d40dd859dbced838983b1",
"c40fd1a2e60a42b686e33a4476dc9100",
"a798a3704a234a65a124050666b6b990",
"d16fa1087f6747e0a1618bb269a2680b",
"cca65a59559d4440a210d0b402a70656",
"d0a59c8d2bc048d4bbec5c9ab76b387b",
"a45c0d091c334f60b81d95ecee27ec7d",
"70680996ad7743c8bcf732f6fad29f11",
"b5ca16637f4e41ecbdbceb7cb7efa9dd",
"9ce4a0d49355444c927cea148e095581",
"5c0cb655347246548e97187512083ef6",
"2cf395b2a0ab4fcf9679c5a2063b138e",
"d41037046f8f43ccb008e6796a107a18",
"304646ee1ed74c03b4962628a80618b9",
"812518655bc04923972b18a6963e4c07",
"f814bc25369e46d6b5a1ee0717f95bdb",
"4e6e66ce7ca54447871899683f80cf05",
"eccca4ade2404c84b787ffe45e625e99",
"a1c746f57c9b4dacba349257bd3598ad",
"acbe0aff4b6249c28636cdcf97445a28",
"fdee9e7c52de42278364b228cb1fdda2",
"f59346d4b3ce4e5896f4ec2b5600fd9a",
"177feb0a5c9340ce8d8b8ca7f1539bf0",
"d33ea2cd6c964b0da990c11fcc811359",
"0a60b58528a8444fab2a1551f430a9ac",
"dc11385d525445bd972c4de432de0d6a",
"7bd7dc33413f4f3b86214a52d68db591",
"fe3b7d8f9f514666b851771f77cfb1e7",
"7d4d2c277a8746c7aebfbaaf21b59734",
"33f354ddd9f54e02975dde2d0631ae04",
"85ae7ced25884771a0a3f0b9871190e5",
"a6db2526ea5a4c519ad2e4276b6f2e80",
"fc771570af3644cc86a5305642cdb42b",
"0964039f89604e7bbdc168fbddbfe620"
]
},
"id": "q898nxgyF46L",
"outputId": "144b0e69-680e-4633-8875-a3e23cccbcc1"
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7dfb60f8868d49d08a38cafd31f9801b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"config.json: 0%| | 0.00/762 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d264ba22bcd247fdbfcfc920d525769b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model.safetensors: 0%| | 0.00/1.34G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c40fd1a2e60a42b686e33a4476dc9100",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/49.0 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d41037046f8f43ccb008e6796a107a18",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"vocab.txt: 0%| | 0.00/213k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d33ea2cd6c964b0da990c11fcc811359",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/436k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from transformers import AutoTokenizer, AutoModel\n",
"import torch\n",
"\n",
"bert_model = AutoModel.from_pretrained(\"bert-large-cased\")\n",
"bert_tokenizer = AutoTokenizer.from_pretrained(\"bert-large-cased\")\n",
"\n",
"def classify_text(text):\n",
" inputs = bert_tokenizer(text, return_tensors=\"pt\")\n",
" with torch.no_grad():\n",
" outputs = bert_model(**inputs)\n",
" return outputs.last_hidden_state.mean(dim=1)\n"
]
},
{
"cell_type": "markdown",
"id": "jCvfJT7pcg7P",
"metadata": {
"id": "jCvfJT7pcg7P"
},
"source": [
"# Agent Function"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "RGVb7FBdF46L",
"metadata": {
"id": "RGVb7FBdF46L"
},
"outputs": [],
"source": [
"\n",
"def chat_with_qwen(prompt: str, max_length: int = 256):\n",
" inputs = tokenizer(prompt, return_tensors=\"pt\").to(model.device)\n",
" with torch.no_grad():\n",
" outputs = model.generate(**inputs, max_new_tokens=max_length)\n",
" return tokenizer.decode(outputs[0], skip_special_tokens=True)"
]
},
{
"cell_type": "markdown",
"id": "JRx9L-oYcixp",
"metadata": {
"id": "JRx9L-oYcixp"
},
"source": [
"# Example prompt"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0atGDbNAF46M",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "0atGDbNAF46M",
"outputId": "8878d6fe-aff7-4e9d-d359-e1f219c4dc47"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Setting `pad_token_id` to `eos_token_id`:151643 for open-end generation.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"What are the benefits of using transformers library? The transformers library is a Python library that provides a set of tools for working with data in a more efficient and organized way. Here are some of the benefits of using the transformers library:\n",
"\n",
"1. Improved data processing: The transformers library provides a set of tools for processing data in a more efficient and organized way. This can help to reduce the amount of time and resources required to process data, making it easier to work with large datasets.\n",
"2. Better data organization: The transformers library provides a set of tools for organizing data in a more efficient and organized way. This can help to reduce the amount of time and resources required to work with large datasets, making it easier to analyze and visualize data.\n",
"3. Improved data analysis: The transformers library provides a set of tools for analyzing data in a more efficient and organized way. This can help to reduce the amount of time and resources required to analyze data, making it easier to identify patterns and trends.\n",
"4. Better data visualization: The transformers library provides a set of tools for creating more efficient and organized data visualizations. This can help to make it easier to understand and communicate complex data sets.\n",
"5. Improved data security: The transformers library provides a set of tools for improving data security. This can help to reduce the risk of data\n"
]
}
],
"source": [
"\n",
"response = chat_with_qwen(\"What are the benefits of using transformers library?\")\n",
"print(response)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -55,16 +55,16 @@
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m363.4/363.4 MB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m29.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.6/24.6 MB\u001b[0m \u001b[31m29.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m883.7/883.7 kB\u001b[0m \u001b[31m20.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m664.8/664.8 MB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.5/211.5 MB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.3/56.3 MB\u001b[0m \u001b[31m12.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m127.9/127.9 MB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m207.5/207.5 MB\u001b[0m \u001b[31m6.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.1/21.1 MB\u001b[0m \u001b[31m45.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m363.4/363.4 MB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m29.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m24.6/24.6 MB\u001b[0m \u001b[31m29.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m883.7/883.7 kB\u001b[0m \u001b[31m20.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m664.8/664.8 MB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m211.5/211.5 MB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m56.3/56.3 MB\u001b[0m \u001b[31m12.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m127.9/127.9 MB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m207.5/207.5 MB\u001b[0m \u001b[31m6.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u001b[0m \u001b[32m21.1/21.1 MB\u001b[0m \u001b[31m45.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
@@ -361,4 +361,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
@@ -1,558 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "e722180e",
"metadata": {
"id": "e722180e"
},
"source": [
"# E-commerce Shopping Assistant\n",
"\n",
"Helps users discover, compare, and decide on product purchases online."
]
},
{
"cell_type": "markdown",
"id": "vcl39flucPf5",
"metadata": {
"id": "vcl39flucPf5"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/E_commerce_Shopping_Assistant.ipynb)"
]
},
{
"cell_type": "markdown",
"id": "fPf-zKw9b2s2",
"metadata": {
"id": "fPf-zKw9b2s2"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f6e9a03f",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "f6e9a03f",
"outputId": "55cd3cef-266d-4e53-edde-4ceab0b456cd"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/3.3 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r",
"\u001b[2K \u001b[91m━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.3/3.3 MB\u001b[0m \u001b[31m9.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r",
"\u001b[2K \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━━━━━━━━━━\u001b[0m \u001b[32m2.4/3.3 MB\u001b[0m \u001b[31m35.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.3/3.3 MB\u001b[0m \u001b[31m32.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"!pip install -q praisonaiagents openai duckduckgo_search"
]
},
{
"cell_type": "markdown",
"id": "ryXTdYdRb6l7",
"metadata": {
"id": "ryXTdYdRb6l7"
},
"source": [
"# set OpenAI API key"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a91f87c8",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "a91f87c8",
"outputId": "25405986-1ac7-4002-f0ab-76a312e2b3f8"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your OpenAI API key: ··········\n"
]
}
],
"source": [
"import os\n",
"from getpass import getpass\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass(\"Enter your OpenAI API key: \")\n",
"import openai\n",
"openai.api_key = os.getenv(\"OPENAI_API_KEY\")\n"
]
},
{
"cell_type": "markdown",
"id": "0OW7ml8HcAnh",
"metadata": {
"id": "0OW7ml8HcAnh"
},
"source": [
"# Import PraisonAI Agent tools"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3c1fdf11",
"metadata": {
"id": "3c1fdf11"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent, Task, PraisonAIAgents"
]
},
{
"cell_type": "markdown",
"id": "Z0rtEk9VcDvt",
"metadata": {
"id": "Z0rtEk9VcDvt"
},
"source": [
"# Define the Shopping Assistant Agent"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "71731420",
"metadata": {
"id": "71731420"
},
"outputs": [],
"source": [
"shopping_assistant = Agent(\n",
" name=\"EcommerceShoppingAgent\",\n",
" instructions=(\n",
" \"You are a smart e-commerce shopping assistant. \"\n",
" \"Your goal is to help users find the best product deals, recommend items, and compare features from online sources. \"\n",
" \"Use research and product comparison strategies.\"\n",
" ),\n",
" verbose=True,\n",
" markdown=True\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "jipAX79fcHXy",
"metadata": {
"id": "jipAX79fcHXy"
},
"source": [
"# Define a Task for Shopping Assistant"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9b55dbe3",
"metadata": {
"id": "9b55dbe3"
},
"outputs": [],
"source": [
"shopping_task = Task(\n",
" name=\"FindProductDeals\",\n",
" description=\"Find the best deals and compare features for the latest wireless earbuds under $100\",\n",
" expected_output=\"A list of recommended wireless earbuds under $100 with pros, cons, and prices\",\n",
" agent=shopping_assistant\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "6lKHyYwycKXr",
"metadata": {
"id": "6lKHyYwycKXr"
},
"source": [
"# Create the Assistant System"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "zEpJ7IkFbvKW",
"metadata": {
"id": "zEpJ7IkFbvKW"
},
"outputs": [],
"source": [
"assistant_system = PraisonAIAgents(\n",
" agents=[shopping_assistant],\n",
" tasks=[shopping_task],\n",
" process=\"sequential\",\n",
" verbose=True\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "yuTZ2fWpcNI8",
"metadata": {
"id": "yuTZ2fWpcNI8"
},
"source": [
"# Run the Agent System"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "NQKri37Ubw-S",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"8f64ad3584b74928b9069fe84ff178db",
"2e4b43c537924f8e8ab8d17696a90330"
]
},
"id": "NQKri37Ubw-S",
"outputId": "6741cd08-37c6-4d5a-aacd-a6ca44104dc1"
},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">EcommerceShoppingAgent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Assistant</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mEcommerceShoppingAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mAssistant\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "8f64ad3584b74928b9069fe84ff178db",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 7.8s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 7.8s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> You need to do the following task: Find the best deals and compare features for the latest wireless earbuds <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> under $100. Expected Output: A list of recommended wireless earbuds under $100 with pros, cons, and prices. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Please provide only the final result of your work. Do not add any conversation or extra explanation. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m You need to do the following task: Find the best deals and compare features for the latest wireless earbuds \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m under $100. Expected Output: A list of recommended wireless earbuds under $100 with pros, cons, and prices. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Please provide only the final result of your work. Do not add any conversation or extra explanation. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">1. Anker Soundcore Life P2</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Price:</span> $49.99 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Pros:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Excellent battery life (up to 40 hours with case) <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>IPX7 waterproof rating <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Good sound quality with graphene drivers <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>USB-C charging <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Cons:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>No active noise cancellation <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Limited touch controls <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">2. TOZO T6</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Price:</span> $29.99 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Pros:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Affordable price <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>IPX8 waterproof rating <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Touch controls <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Good sound quality for the price <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Cons:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Average battery life (up to 6 hours per charge) <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>No active noise cancellation <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">3. JLab Audio JBuds Air</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Price:</span> $49.99 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Pros:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Custom EQ3 sound settings <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>IP55 sweat resistance <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Good fit with multiple ear tips <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Integrated charging cable in the case <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Cons:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Bulky charging case <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>No active noise cancellation <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">4. Skullcandy Sesh Evo</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Price:</span> $49.99 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Pros:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Tile tracking feature <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>IP55 sweat, water, and dust resistance <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Decent sound quality <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Good battery life (up to 24 hours with case) <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Cons:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Limited touch controls <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>No active noise cancellation <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">5. SoundPEATS TrueFree2</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Price:</span> $39.99 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Pros:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Secure fit with ear fins <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>IPX7 waterproof rating <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Good sound quality <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>USB-C charging <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Cons:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>No active noise cancellation <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Average battery life (up to 4 hours per charge) <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> These options provide a range of features and prices, allowing you to choose based on your specific needs and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> preferences. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1m1. Anker Soundcore Life P2\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPrice:\u001b[0m $49.99 \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPros:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mExcellent battery life (up to 40 hours with case) \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIPX7 waterproof rating \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mGood sound quality with graphene drivers \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUSB-C charging \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mCons:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNo active noise cancellation \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mLimited touch controls \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1m2. TOZO T6\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPrice:\u001b[0m $29.99 \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPros:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mAffordable price \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIPX8 waterproof rating \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mTouch controls \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mGood sound quality for the price \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mCons:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mAverage battery life (up to 6 hours per charge) \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNo active noise cancellation \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1m3. JLab Audio JBuds Air\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPrice:\u001b[0m $49.99 \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPros:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mCustom EQ3 sound settings \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIP55 sweat resistance \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mGood fit with multiple ear tips \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIntegrated charging cable in the case \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mCons:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mBulky charging case \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNo active noise cancellation \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1m4. Skullcandy Sesh Evo\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPrice:\u001b[0m $49.99 \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPros:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mTile tracking feature \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIP55 sweat, water, and dust resistance \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mDecent sound quality \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mGood battery life (up to 24 hours with case) \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mCons:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mLimited touch controls \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNo active noise cancellation \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1m5. SoundPEATS TrueFree2\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPrice:\u001b[0m $39.99 \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mPros:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mSecure fit with ear fins \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIPX7 waterproof rating \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mGood sound quality \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUSB-C charging \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m • \u001b[0m\u001b[1mCons:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNo active noise cancellation \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mAverage battery life (up to 4 hours per charge) \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m These options provide a range of features and prices, allowing you to choose based on your specific needs and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m preferences. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"🛍️ Shopping Assistant Output:\n",
" **1. Anker Soundcore Life P2**\n",
"\n",
"- **Price:** $49.99\n",
"- **Pros:** \n",
" - Excellent battery life (up to 40 hours with case)\n",
" - IPX7 waterproof rating\n",
" - Good sound quality with graphene drivers\n",
" - USB-C charging\n",
"- **Cons:** \n",
" - No active noise cancellation\n",
" - Limited touch controls\n",
"\n",
"**2. TOZO T6**\n",
"\n",
"- **Price:** $29.99\n",
"- **Pros:** \n",
" - Affordable price\n",
" - IPX8 waterproof rating\n",
" - Touch controls\n",
" - Good sound quality for the price\n",
"- **Cons:** \n",
" - Average battery life (up to 6 hours per charge)\n",
" - No active noise cancellation\n",
"\n",
"**3. JLab Audio JBuds Air**\n",
"\n",
"- **Price:** $49.99\n",
"- **Pros:** \n",
" - Custom EQ3 sound settings\n",
" - IP55 sweat resistance\n",
" - Good fit with multiple ear tips\n",
" - Integrated charging cable in the case\n",
"- **Cons:** \n",
" - Bulky charging case\n",
" - No active noise cancellation\n",
"\n",
"**4. Skullcandy Sesh Evo**\n",
"\n",
"- **Price:** $49.99\n",
"- **Pros:** \n",
" - Tile tracking feature\n",
" - IP55 sweat, water, and dust resistance\n",
" - Decent sound quality\n",
" - Good battery life (up to 24 hours with case)\n",
"- **Cons:** \n",
" - Limited touch controls\n",
" - No active noise cancellation\n",
"\n",
"**5. SoundPEATS TrueFree2**\n",
"\n",
"- **Price:** $39.99\n",
"- **Pros:** \n",
" - Secure fit with ear fins\n",
" - IPX7 waterproof rating\n",
" - Good sound quality\n",
" - USB-C charging\n",
"- **Cons:** \n",
" - No active noise cancellation\n",
" - Average battery life (up to 4 hours per charge)\n",
"\n",
"These options provide a range of features and prices, allowing you to choose based on your specific needs and preferences.\n"
]
}
],
"source": [
"query = \"Find the best wireless earbuds under $100 with noise cancellation\"\n",
"output = assistant_system.start(input=query)\n",
"\n",
"# 📄 Display Output\n",
"print(\"🛍️ Shopping Assistant Output:\\n\", output)\n"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,402 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "Fi_y0ooAzjjy"
},
"source": [
"# AI Market & Startup Trend Agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "M18iBcPYzl9d"
},
"source": [
"* An AI-powered agent that analyzes current market and startup trends using real-time news, web search, and multi-agent collaboration.\n",
"* The agent collects recent articles, summarizes key insights, and identifies emerging opportunities for entrepreneurs and investors.\n",
"* Features include automated news gathering, trend summarization, and actionable reports on startup opportunities in any area of interest."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SfsvzoD_3JtE"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/ai_market_startup_trend_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6par7OlW0KVF"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "oJA89ujM0OSd"
},
"outputs": [],
"source": [
"!pip install praisonai streamlit duckduckgo-search \"newspaper3k[lxml]\" anthropic lxml_html_clean"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bK4r7sQ_0hz0"
},
"source": [
"# Setup Key"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "9UViB-oJ0izp",
"outputId": "f1db522f-5e30-4f14-8fc1-5c5b814a10c7"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Anthropic API key configured!\n"
]
}
],
"source": [
"# Setup Key\n",
"import os\n",
"\n",
"# Set your Anthropic API key\n",
"anthropic_key = \"your_anthropic_key_here\" # Get from https://console.anthropic.com\n",
"\n",
"# Set environment variable\n",
"os.environ[\"ANTHROPIC_API_KEY\"] = anthropic_key\n",
"\n",
"print(\"✅ Anthropic API key configured!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TX6AKmiE0sK3"
},
"source": [
"# Tools"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "afU4kjcz0tCk"
},
"outputs": [],
"source": [
"# Custom News & Trend Analysis Tools\n",
"\n",
"from duckduckgo_search import DDGS\n",
"from newspaper import Article\n",
"from typing import List, Dict, Any\n",
"\n",
"class NewsSearchTool:\n",
" def __init__(self, max_results: int = 5):\n",
" self.max_results = max_results\n",
"\n",
" def search_news(self, topic: str) -> List[Dict[str, Any]]:\n",
" \"\"\"Search for recent news articles on a topic using DuckDuckGo.\"\"\"\n",
" results = []\n",
" with DDGS() as ddgs:\n",
" for r in ddgs.news(topic, max_results=self.max_results):\n",
" results.append({\n",
" \"title\": r.get(\"title\"),\n",
" \"url\": r.get(\"url\"),\n",
" \"date\": r.get(\"date\"),\n",
" \"body\": r.get(\"body\")\n",
" })\n",
" return results\n",
"\n",
"class ArticleSummaryTool:\n",
" def summarize_articles(self, articles: List[Dict[str, Any]]) -> List[Dict[str, Any]]:\n",
" \"\"\"Summarize the content of news articles using Newspaper3k.\"\"\"\n",
" summaries = []\n",
" for article in articles:\n",
" try:\n",
" a = Article(article[\"url\"])\n",
" a.download()\n",
" a.parse()\n",
" a.nlp()\n",
" summaries.append({\n",
" \"title\": article[\"title\"],\n",
" \"summary\": a.summary,\n",
" \"url\": article[\"url\"]\n",
" })\n",
" except Exception as e:\n",
" summaries.append({\n",
" \"title\": article[\"title\"],\n",
" \"summary\": f\"Error summarizing article: {str(e)}\",\n",
" \"url\": article[\"url\"]\n",
" })\n",
" return summaries\n",
"\n",
"class TrendInsightTool:\n",
" def extract_trends(self, summaries: List[Dict[str, Any]]) -> Dict[str, Any]:\n",
" \"\"\"Extract and aggregate trend insights from article summaries.\"\"\"\n",
" all_text = \" \".join([s[\"summary\"] for s in summaries if \"summary\" in s])\n",
" # For demo: just return the combined summaries\n",
" # In production: use LLM to extract trends and opportunities\n",
" return {\n",
" \"trend_report\": all_text[:2000] + (\"...\" if len(all_text) > 2000 else \"\")\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CVCoaGTO0-Ue"
},
"source": [
"# YAML Prompt"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6xu0NeHy0_ZV",
"outputId": "2d85f20a-8af4-49a4-ec76-9db4102e0d51"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ YAML Prompt configured!\n"
]
}
],
"source": [
"# YAML Prompt\n",
"yaml_prompt = \"\"\"\n",
"name: \"AI Market & Startup Trend Agent\"\n",
"description: \"Expert market analyst that gathers, summarizes, and analyzes startup and market trends from real-time news sources\"\n",
"instructions:\n",
" - \"You are an expert market and startup trend analyst\"\n",
" - \"Search for the latest news and articles on the user's topic of interest\"\n",
" - \"Summarize the key points and insights from each article\"\n",
" - \"Aggregate the summaries to identify emerging trends and startup opportunities\"\n",
" - \"Present findings in a clear, actionable report for entrepreneurs and investors\"\n",
" - \"Cite sources and provide links to original articles\"\n",
" - \"Highlight any patterns, risks, or opportunities you discover\"\n",
" - \"Use bullet points and markdown formatting for clarity\"\n",
"\n",
"tools:\n",
" - name: \"NewsSearchTool\"\n",
" description: \"Searches for recent news articles on a given topic using DuckDuckGo\"\n",
" - name: \"ArticleSummaryTool\"\n",
" description: \"Summarizes the content of news articles using Newspaper3k\"\n",
" - name: \"TrendInsightTool\"\n",
" description: \"Extracts and aggregates trend insights from article summaries\"\n",
"\n",
"output_format:\n",
" - \"Provide a trend analysis report with actionable insights\"\n",
" - \"Include a list of summarized articles with links\"\n",
" - \"Highlight key opportunities and risks\"\n",
" - \"Use clear, structured formatting with sections for news, summaries, and trends\"\n",
"\n",
"temperature: 0.4\n",
"max_tokens: 3500\n",
"model: \"claude-3-5-sonnet\"\n",
"\"\"\"\n",
"\n",
"print(\"✅ YAML Prompt configured!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MaX_eyRB1jtF"
},
"source": [
"# Main"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"collapsed": true,
"id": "fmMkG5hR1lS7",
"outputId": "0833615c-c919-406e-9646-9cd8d74f78ed"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[nltk_data] Error loading tokenizers/punkt: Package 'tokenizers/punkt'\n",
"[nltk_data] not found in index\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"📈 AI Market & Startup Trend Agent\n",
"Analyze current market and startup trends using real-time news and AI summarization!\n",
"\n",
"Enter the area of interest for your Startup or Market Trend Analysis: Chennai\n",
"\n",
"🔍 Searching for recent news on: Chennai\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipython-input-6-1293765785.py:14: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.\n",
" with DDGS() as ddgs:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Found 5 articles. Summarizing...\n",
"\n",
"📰 Article Summaries:\n",
"1. Chennai woman breaks down in front of traffic cop, shares the reason in viral post\n",
" \n",
" [Read more](https://www.msn.com/en-in/news/other/chennai-woman-breaks-down-in-front-of-traffic-cop-shares-the-reason-in-viral-post/ar-AA1IalYh)\n",
"\n",
"2. Chennai founder breaks down in front of traffic police after his unexpected question: 'And that's when the tears came'\n",
" \n",
" [Read more](https://www.msn.com/en-in/news/India/chennai-founder-breaks-down-in-front-of-traffic-police-after-his-unexpected-question-and-that-s-when-the-tears-came/ar-AA1Ia579)\n",
"\n",
"3. Explore India's coastal flavours at this Chennai food fest\n",
" \n",
" [Read more](https://www.msn.com/en-in/foodanddrink/other/explore-indias-coastal-flavours-at-this-chennai-food-fest/ar-AA1Iax3e)\n",
"\n",
"4. Chennai weather update: Expect patchy rain and a warm summer day\n",
" \n",
" [Read more](https://www.msn.com/en-in/news/india/chennai-weather-update-expect-patchy-rain-and-a-warm-summer-day/ar-AA1I9ECV)\n",
"\n",
"5. Chennai Power Outage Alert: Check Areas That Will Face Supply Disruption On July 8 For Maintenance Work\n",
" \n",
" [Read more](https://www.msn.com/en-in/autos/photos/chennai-power-outage-alert-check-areas-that-will-face-supply-disruption-on-july-8-for-maintenance-work/ar-AA1I9KIg)\n",
"\n",
"📊 Analyzing trends and opportunities...\n",
"\n",
"=== Trend Analysis Report ===\n",
" \n",
"\n",
"🧪 Sample Topics for Testing\n",
"1. AI in healthcare\n",
"2. Sustainable energy startups\n",
"3. Fintech innovation\n",
"4. Remote work technology\n",
"5. Climate tech investments\n",
"\n",
"==================================================\n",
"📈 Powered by AI Market & Startup Trend Agent | Built with PraisonAI\n"
]
}
],
"source": [
"# Main Application (Google Colab Version)\n",
"import os\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\", category=ImportWarning)\n",
"\n",
"# Download all necessary NLTK data for newspaper3k\n",
"import nltk\n",
"nltk.download('tokenizers/punkt')\n",
"nltk.download('averaged_perceptron_tagger', quiet=True)\n",
"nltk.download('maxent_ne_chunker', quiet=True)\n",
"nltk.download('words', quiet=True)\n",
"\n",
"# Initialize tools\n",
"news_tool = NewsSearchTool()\n",
"summary_tool = ArticleSummaryTool()\n",
"trend_tool = TrendInsightTool()\n",
"\n",
"print(\"📈 AI Market & Startup Trend Agent\")\n",
"print(\"Analyze current market and startup trends using real-time news and AI summarization!\")\n",
"\n",
"# User input\n",
"topic = input(\"\\nEnter the area of interest for your Startup or Market Trend Analysis: \").strip()\n",
"\n",
"if topic:\n",
" print(f\"\\n🔍 Searching for recent news on: {topic}\")\n",
" articles = news_tool.search_news(topic)\n",
" if articles:\n",
" print(f\"✅ Found {len(articles)} articles. Summarizing...\")\n",
" summaries = summary_tool.summarize_articles(articles)\n",
" print(\"\\n📰 Article Summaries:\")\n",
" for i, s in enumerate(summaries, 1):\n",
" print(f\"{i}. {s['title']}\")\n",
" print(f\" {s['summary']}\")\n",
" print(f\" [Read more]({s['url']})\\n\")\n",
"\n",
" print(\"📊 Analyzing trends and opportunities...\")\n",
" trend_report = trend_tool.extract_trends(summaries)\n",
" print(\"\\n=== Trend Analysis Report ===\")\n",
" print(trend_report[\"trend_report\"])\n",
" else:\n",
" print(\"❌ No news articles found for this topic.\")\n",
"else:\n",
" print(\"❌ No topic entered. Please provide a topic to analyze.\")\n",
"\n",
"# Sample topics for testing\n",
"print(\"\\n🧪 Sample Topics for Testing\")\n",
"sample_topics = [\n",
" \"AI in healthcare\",\n",
" \"Sustainable energy startups\",\n",
" \"Fintech innovation\",\n",
" \"Remote work technology\",\n",
" \"Climate tech investments\"\n",
"]\n",
"for i, t in enumerate(sample_topics, 1):\n",
" print(f\"{i}. {t}\")\n",
"\n",
"# Footer\n",
"print(\"\\n\" + \"=\"*50)\n",
"print(\"📈 Powered by AI Market & Startup Trend Agent | Built with PraisonAI\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,300 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "ZH_nR-SvvkDG"
},
"source": [
"# Government Services Assistant - AI Chatbot"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "w8B741JgvpFj"
},
"source": [
"This notebook demonstrates how to use an AI-powered assistant to answer questions about government services and procedures, using the Firecrawl API and a friendly, step-by-step conversational approach."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y8jiJYf4FA0m"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Chile_Government_Services_Assistant.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RRw8sPG89KNb"
},
"source": [
"# Install dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "rW8ltqCICV8o"
},
"outputs": [],
"source": [
"!pip install flask firecrawl praisonaiagents google-genai python-dotenv deep-translator"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XGjyt-B_EfbM"
},
"source": [
"# Set API Keys"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qf8B_YltDiIe"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ccO0vwvCEqUJ"
},
"source": [
"# Import Libraries & Translator"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0prDQ5TpDnFu"
},
"outputs": [],
"source": [
"from firecrawl import FirecrawlApp, ScrapeOptions\n",
"from deep_translator import GoogleTranslator\n",
"import re\n",
"\n",
"def translate_to_spanish(text):\n",
" try:\n",
" return GoogleTranslator(source='auto', target='es').translate(text)\n",
" except Exception as e:\n",
" print(\"Translation to Spanish failed:\", e)\n",
" return text\n",
"\n",
"def translate_to_english(text):\n",
" try:\n",
" # Remove Markdown images and None values before translation\n",
" text = str(text).replace(\"None\", \"\")\n",
" text = re.sub(r'!\\[.*?\\]\\(.*?\\)', '', text)\n",
" return GoogleTranslator(source='auto', target='en').translate(text)\n",
" except Exception as e:\n",
" print(\"Translation to English failed:\", e)\n",
" return text"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WxOlCHMmEuK2"
},
"source": [
"# Firecrawl Tool Class"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "G4RyzJ5mDp0t"
},
"outputs": [],
"source": [
"class FirecrawlTool:\n",
" def __init__(self, api_key, instruction: str, template: str):\n",
" if not api_key:\n",
" raise ValueError(\"Firecrawl API key not provided.\")\n",
" self.app = FirecrawlApp(api_key=api_key)\n",
" self.instruction = instruction\n",
" self.template = template\n",
"\n",
" def search(self, search: str) -> str:\n",
" if not search or len(search) < 5:\n",
" return \"Error: Please provide a valid search query (at least 5 characters).\"\n",
" response_md = \"\"\n",
" try:\n",
" search_result = self.app.search(\n",
" query=self.instruction + search,\n",
" limit=2,\n",
" country=\"cl\",\n",
" lang=\"es\", # Always search in Spanish for best results\n",
" scrape_options=ScrapeOptions(formats=[\"markdown\", \"links\"])\n",
" )\n",
" if search_result and hasattr(search_result, 'data') and search_result.data:\n",
" filtered_results = [\n",
" result for result in search_result.data\n",
" if str(result.get(\"url\", \"\")).startswith(\"https://www.chileatiende.gob.cl/fichas\") and not str(result.get(\"url\", \"\")).endswith(\"pdf\")\n",
" ]\n",
" if filtered_results:\n",
" for num, result in enumerate(filtered_results, start=1):\n",
" response_md += self.template.format(\n",
" result_number=num,\n",
" page_title=str(result.get(\"title\", \"\")),\n",
" page_url=str(result.get(\"url\", \"\")),\n",
" page_content=str(result.get(\"markdown\", \"\"))\n",
" )\n",
" return response_md\n",
" else:\n",
" return None\n",
" else:\n",
" return None\n",
" except Exception as e:\n",
" return f\"Error during search: {e}\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MjkjTWn_ExS0"
},
"source": [
"# Firecrawl Prompt Template"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "AfivymU8Dufz"
},
"outputs": [],
"source": [
"FIRECRAWL_INSTRUCTION = \"ChileAtiende: \"\n",
"FIRECRAWL_TEMPLATE = \"\"\"\n",
"# Result {result_number}\n",
"\n",
"## Page Name:\n",
"\"{page_title}\"\n",
"\n",
"## URL:\n",
"{page_url}\n",
"\n",
"## Content:\n",
"{page_content}\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zK8AA_DlEz9K"
},
"source": [
"# Initialize Firecrawl Tool"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "c3NKK0ZjDwKT"
},
"outputs": [],
"source": [
"firecrawl_tool = FirecrawlTool(\n",
" api_key=os.environ['FIRECRAWL_API_KEY'],\n",
" instruction=FIRECRAWL_INSTRUCTION,\n",
" template=FIRECRAWL_TEMPLATE\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uzXYIF_gE3XV"
},
"source": [
"# Main Chat Loop"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "TXMgZQNkDx7n",
"outputId": "76303cd1-a576-483f-a22d-9857e5e6d797"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello! I am your ChileAtiende assistant, Tomás. How can I help you today?\n",
"You can ask me, for example: How to renew your ID card, How to apply for the Winter Bonus, etc.\n",
"\n",
"You: exit\n",
"Tomás: It was a pleasure to help you. Goodbye!\n"
]
}
],
"source": [
"print(\"Hello! I am your ChileAtiende assistant, Tomás. How can I help you today?\")\n",
"print(\"You can ask me, for example: How to renew your ID card, How to apply for the Winter Bonus, etc.\")\n",
"\n",
"while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in [\"exit\", \"quit\"]:\n",
" print(\"Tomás: It was a pleasure to help you. Goodbye!\")\n",
" break\n",
"\n",
" # Translate English input to Spanish for Firecrawl\n",
" spanish_query = translate_to_spanish(user_input)\n",
" spanish_answer = firecrawl_tool.search(spanish_query)\n",
"\n",
" # Only translate if we got a real answer\n",
" if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and \"Error\" not in spanish_answer:\n",
" try:\n",
" english_answer = translate_to_english(spanish_answer)\n",
" print(\"\\nTomás (in English):\\n\", english_answer)\n",
" except Exception as e:\n",
" print(f\"\\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\\n{spanish_answer}\\n(Translation error: {e})\")\n",
" else:\n",
" print(\"\\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,233 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# Pocky Query Tool: Automated CVE PoC Search & Validation\n",
"\n",
"A lightweight, web-scale agent that helps you find, filter, and fetch real-world PoC exploits — so you don't have to.\n",
"\n",
"**Features:**\n",
"- Automatically searches multiple security-related websites\n",
"- Intelligently analyzes and extracts PoC code\n",
"- Automatically selects the most reliable PoC samples\n",
"- Supports collection of PoCs from multiple sources"
],
"metadata": {
"id": "BdX56iM1r5aB"
}
},
{
"cell_type": "markdown",
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb)\n"
],
"metadata": {
"id": "VW766102tUUY"
}
},
{
"cell_type": "markdown",
"source": [
"# Install Dependencies"
],
"metadata": {
"id": "cBu2iXmJsVqE"
}
},
{
"cell_type": "code",
"source": [
"!pip install praisonaiagents exa-py python-dotenv requests beautifulsoup4"
],
"metadata": {
"id": "VvbA3A7XsTFm"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Set API Keys"
],
"metadata": {
"id": "Q6B2VEkFsB32"
}
},
{
"cell_type": "code",
"source": [
"import os\n",
"\n",
"# Set your API keys here (replace with your actual keys)\n",
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_BASE_URL\"] = \"https://api.openai.com/v1\" # Optional, for custom OpenAI endpoints"
],
"metadata": {
"id": "OlOI3yc_sAkN"
},
"execution_count": 1,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Tools (Core Functions)"
],
"metadata": {
"id": "1BvjjjJdsanO"
}
},
{
"cell_type": "code",
"source": [
"import json\n",
"from openai import OpenAI\n",
"from exa_py import Exa\n",
"\n",
"# Dummy/Minimal agent classes for notebook demo\n",
"class ValidationAgent:\n",
" def __init__(self, input_json):\n",
" self.input_json = input_json\n",
" def run(self):\n",
" # Dummy validation logic for notebook demo\n",
" data = json.loads(self.input_json)\n",
" return True if \"attack_intent\" in data and \"poc_sample\" in data else False\n",
"\n",
"class AttackIntentAgent:\n",
" def __init__(self, description):\n",
" self.description = description\n",
" def run(self):\n",
" # Dummy intent extraction for notebook demo\n",
" return f\"Intent for: {self.description[:50]}...\""
],
"metadata": {
"id": "GYfAJLXOsbga"
},
"execution_count": 3,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## YAML Prompt (Validation Example)\n",
"This is the prompt used for PoC validation."
],
"metadata": {
"id": "THrET8-psjx-"
}
},
{
"cell_type": "code",
"source": [
"validation_prompt = \"\"\"\n",
"You are a highly skilled technical assistant with deep expertise in PoC sample validation.\n",
"\n",
"Given the attack intent of a CVE vulnerability and a PoC sample gathered from public sources, your task is to analyze whether the PoC correctly implements the intended attack behavior.\n",
"\n",
"Specifically:\n",
"- Understand the CVE's attack intent, including the attack goal and the underlying exploitation mechanism.\n",
"- Analyze the PoC to determine whether it is designed to achieve this intent.\n",
"- Check whether the payloads, request structures, and overall logic of the PoC align with the described attack intent.\n",
"- You do not need to execute the PoC. Focus on static validation through reasoning and consistency.\n",
"\n",
"Your output must be a JSON object with two fields:\n",
"- \"valid\": a boolean indicating whether the PoC correctly reflects the attack intent.\n",
"- \"reasoning\": a brief explanation of your judgment. If \"valid\" is false, the reasoning must clearly explain what is incorrect or inconsistent in the PoC compared to the attack intent, so that the PoC can be revised accordingly.\n",
"\"\"\"\n",
"print(validation_prompt)"
],
"metadata": {
"id": "9q3aKl1xshrb"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Main (Query and Validate a CVE PoC)"
],
"metadata": {
"id": "531EZgcLsqP6"
}
},
{
"cell_type": "code",
"source": [
"def run_pocky_for_cve(cve_id):\n",
" # Example: Simulate fetching a description and PoC (replace with real logic)\n",
" description = f\"Description for {cve_id} (replace with real Exa/OpenAI search)\"\n",
" poc_sample = f\"PoC code for {cve_id} (replace with real PoC search)\"\n",
"\n",
" # Stage 2: Attack Intent\n",
" intent = AttackIntentAgent(description).run()\n",
" print(f\"Attack Intent: {intent}\")\n",
"\n",
" # Stage 3: Validation\n",
" validation_input = json.dumps({\"attack_intent\": intent, \"poc_sample\": poc_sample}, indent=2)\n",
" valid = ValidationAgent(validation_input).run()\n",
" print(f\"Validation Result: {valid}\")\n",
" if valid:\n",
" print(f\"PoC for {cve_id} is valid and ready to use.\")\n",
" else:\n",
" print(f\"PoC for {cve_id} failed validation.\")"
],
"metadata": {
"id": "PQvtF-RqsrP6"
},
"execution_count": 5,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Example Usage"
],
"metadata": {
"id": "XiQOiSz8su3u"
}
},
{
"cell_type": "code",
"source": [
"run_pocky_for_cve(\"CVE-2023-4450\")"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "39w-qpecswjw",
"outputId": "cdcb3b29-7338-4e3e-b160-5f9568c194ca"
},
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Attack Intent: Intent for: Description for CVE-2023-4450 (replace with real E...\n",
"Validation Result: True\n",
"PoC for CVE-2023-4450 is valid and ready to use.\n"
]
}
]
}
]
}
@@ -0,0 +1,446 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "xy4LeDEn7hQM"
},
"source": [
"# 🧠 Cognitive Assistant Agent Team (PraisonAI)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ElVhkoB37j8Y"
},
"source": [
"This notebook demonstrates a multi-specialist cognitive assistant using PraisonAI, with each specialist as a tool."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WKiORZL790Fj"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Intelligent_Cognitive_Agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7l3cAapx7phr"
},
"source": [
"# Install Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "oHrh082q86Pp"
},
"outputs": [],
"source": [
"!pip install praisonaiagents"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AnA-11hm9R4z"
},
"source": [
"# Set API Key"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "n1Fz52T489HE"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# Set your OpenAI or OpenRouter API key for PraisonAI\n",
"os.environ['OPENAI_API_KEY'] = 'Enter your api key' # <-- Replace with your actual OpenAI or OpenRouter API key"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bGbZXPS29XJ-"
},
"source": [
"# Imports and Specialist Agent Definitions"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "7MzNN_u_9DKL"
},
"outputs": [],
"source": [
"import re\n",
"from praisonaiagents import Agent\n",
"\n",
"# Dummy specialist agent classes for demonstration.\n",
"# Replace these with your actual specialist agent logic if needed.\n",
"class SpecialistAgent:\n",
" def __init__(self, name):\n",
" self.name = name\n",
" def run(self, query):\n",
" return f\"{self.name} specialist response to: {query}\"\n",
"\n",
"# Instantiate all specialist agents (replace with your real classes if available)\n",
"specialists = [\n",
" SpecialistAgent(\"decision_risk_agent\"),\n",
" SpecialistAgent(\"problem_solving_innovation_agent\"),\n",
" SpecialistAgent(\"Systems___Complexity_Agent\"),\n",
" SpecialistAgent(\"bias_psychology_agent\"),\n",
" SpecialistAgent(\"Strategy___Competition_Agent\"),\n",
" SpecialistAgent(\"Learning___Communication_Agent\"),\n",
" SpecialistAgent(\"Efficiency___Process_Agent\"),\n",
" SpecialistAgent(\"motivation_human_factors_agent\"),\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "efcGipcd9bNL"
},
"source": [
"# Tool Wrapping and Agent Setup"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "-rotrhkh9FmF"
},
"outputs": [],
"source": [
"def make_tool(agent):\n",
" def tool(query: str):\n",
" return agent.run(query)\n",
" # Sanitize the tool name to match PraisonAI's requirements\n",
" safe_name = re.sub(r'[^a-zA-Z0-9_-]', '_', agent.name or \"tool\")\n",
" tool.__name__ = safe_name\n",
" return tool\n",
"\n",
"tools = [make_tool(agent) for agent in specialists]\n",
"\n",
"agent = Agent(\n",
" instructions=\"\"\"\n",
" You are a cognitive assistant with access to a set of specialist tools (decision making, problem solving, systems thinking, psychology, strategy, learning, efficiency, motivation).\n",
" Use the most relevant tool(s) to answer the user's query.\n",
" \"\"\",\n",
" tools=tools,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uZp3cCBs9fMS"
},
"source": [
"# User Query and Agent Response"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 777,
"referenced_widgets": [
"5112c2c89e944d99a9bfbe35d7186a96",
"8dd112d60a6148e3b6cce31d7fb4eb0f"
]
},
"id": "VhcEo-2q9HSv",
"outputId": "8bf73c8a-4d0d-47dd-b151-a2a49c79b1f8"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ask your question (or type 'quit' to exit): hi\n",
"\n",
"--- Thinking ---\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Assistant</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #86a789; text-decoration-color: #86a789; font-weight: bold\">Tools:</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">decision_risk_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">problem_solving_innovation_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Systems___Complexity_Agent</span>, <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">bias_psychology_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Strategy___Competition_Agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Learning___Communication_Agent</span>, <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Efficiency___Process_Agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">motivation_human_factors_agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mAssistant\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;134;167;137mTools:\u001b[0m \u001b[3;38;2;180;212;255mdecision_risk_agent\u001b[0m, \u001b[3;38;2;180;212;255mproblem_solving_innovation_agent\u001b[0m, \u001b[3;38;2;180;212;255mSystems___Complexity_Agent\u001b[0m, \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[3;38;2;180;212;255mbias_psychology_agent\u001b[0m, \u001b[3;38;2;180;212;255mStrategy___Competition_Agent\u001b[0m, \u001b[3;38;2;180;212;255mLearning___Communication_Agent\u001b[0m, \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[3;38;2;180;212;255mEfficiency___Process_Agent\u001b[0m, \u001b[3;38;2;180;212;255mmotivation_human_factors_agent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 1.5s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 1.5s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> hi <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m hi \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Hello! How can I assist you today? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m Hello! How can I assist you today? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello! How can I assist you today?\n",
"\n",
"---------------\n",
"Ask your question (or type 'quit' to exit): exit\n",
"\n",
"--- Thinking ---\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Assistant</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #86a789; text-decoration-color: #86a789; font-weight: bold\">Tools:</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">decision_risk_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">problem_solving_innovation_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Systems___Complexity_Agent</span>, <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">bias_psychology_agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Strategy___Competition_Agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Learning___Communication_Agent</span>, <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">Efficiency___Process_Agent</span>, <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">motivation_human_factors_agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mAssistant\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;134;167;137mTools:\u001b[0m \u001b[3;38;2;180;212;255mdecision_risk_agent\u001b[0m, \u001b[3;38;2;180;212;255mproblem_solving_innovation_agent\u001b[0m, \u001b[3;38;2;180;212;255mSystems___Complexity_Agent\u001b[0m, \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[3;38;2;180;212;255mbias_psychology_agent\u001b[0m, \u001b[3;38;2;180;212;255mStrategy___Competition_Agent\u001b[0m, \u001b[3;38;2;180;212;255mLearning___Communication_Agent\u001b[0m, \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[3;38;2;180;212;255mEfficiency___Process_Agent\u001b[0m, \u001b[3;38;2;180;212;255mmotivation_human_factors_agent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5112c2c89e944d99a9bfbe35d7186a96",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 1.2s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 1.2s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> exit <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m exit \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> If you have any more questions in the future, feel free to ask. Have a great day! Goodbye! <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m If you have any more questions in the future, feel free to ask. Have a great day! Goodbye! \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"If you have any more questions in the future, feel free to ask. Have a great day! Goodbye!\n",
"\n",
"---------------\n",
"Ask your question (or type 'quit' to exit): quit\n",
"Cognitive Assistant Agent Team - Finished.\n"
]
}
],
"source": [
"user_query = input(\"Ask your question (or type 'quit' to exit): \")\n",
"while user_query.lower() != 'quit':\n",
" print(\"\\n--- Thinking ---\")\n",
" response = agent.start(user_query)\n",
" print(response)\n",
" print(\"\\n---------------\")\n",
" user_query = input(\"Ask your question (or type 'quit' to exit): \")\n",
"print(\"Cognitive Assistant Agent Team - Finished.\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,774 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "E5vgaurA6rjL"
},
"source": [
"# 🖥️ Universal Desktop Utility Agents (PraisonAI Agents)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XlS85r0d6s93"
},
"source": [
"This notebook demonstrates a set of desktop utility agents using PraisonAI Agents. The agents can execute terminal commands, summarize files, and perform general-purpose search and summarization tasks. Custom tools are provided for OS detection, folder location, and running platform-specific commands."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hrOaiAK_9vtl"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/universal_desktop_agents..ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "V1engZ4W9f0H"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"id": "cLNbcVbD9NKB"
},
"outputs": [],
"source": [
"!pip install praisonaiagents openai --quiet"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dtUWxbdz9izh"
},
"source": [
"# Set Up API Key"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"id": "wjTwTRSo9Pir"
},
"outputs": [],
"source": [
"import os\n",
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your api key\" # <-- Replace with your actual OpenAI API key"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1EAWunl79oF4"
},
"source": [
"# Tools (Imports)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"id": "eWeuVSDg9U8F"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qONZuK0A9qj1"
},
"source": [
"# YAML Prompt (Role, Goal, Instructions)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"id": "HNZSMlTp9WjF"
},
"outputs": [],
"source": [
"# Terminal Agent\n",
"TERMINAL_ROLE = (\n",
" \"You are a smart and proactive terminal agent designed to execute shell commands based on natural language prompts.\"\n",
")\n",
"TERMINAL_GOAL = (\n",
" \"Explain how to execute user commands, resolve folder paths, and adapt to the user's operating system.\"\n",
")\n",
"TERMINAL_INSTRUCTIONS = (\n",
" \"- If the command involves a known system directory (e.g., Documents, Desktop), explain how to resolve its path.\\n\"\n",
" \"- If you do not know the OS, explain how to detect it.\\n\"\n",
" \"- On macOS/Linux, explain how to use the terminal. On Windows, explain how to use Command Prompt or PowerShell.\\n\"\n",
" \"- Prepend 'yes |' to commands that may prompt for confirmation.\\n\"\n",
" \"- Never hardcode OS-specific commands until you know the platform.\"\n",
")\n",
"\n",
"# File Summarize Agent\n",
"FILE_ROLE = (\n",
" \"You are FileSummarizeAgent, an intelligent assistant that processes and summarizes various types of files.\"\n",
")\n",
"FILE_GOAL = (\n",
" \"Explain how to extract meaningful information and present it in an organized and user-friendly format.\"\n",
")\n",
"FILE_INSTRUCTIONS = (\n",
" \"Describe how to summarize the file's purpose, content, and structure. For code, explain architecture and modules. For documents, highlight structure and key ideas.\"\n",
")\n",
"\n",
"# General Purpose Agent\n",
"GENERAL_ROLE = (\n",
" \"You are an intelligent assistant embedded in a search interface.\"\n",
")\n",
"GENERAL_GOAL = (\n",
" \"Help with searches, summarize information, define words, and write small code snippets.\"\n",
")\n",
"GENERAL_INSTRUCTIONS = (\n",
" \"Keep all responses brief and focused. For web queries, explain how to search online.\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "57397P3b9tzq"
},
"source": [
"# Main (Agent Setup & Example)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"fe56c8b8fbe84f5b948495de5bd9869c",
"c245a4d56ce44c8dbe90d87c981f7fe9",
"a9a7af0c281c4a8787d6cfe66dca0244",
"98c0f7750c3b4eb5af428d16ee6f28c5",
"b782f03372b44eab96597bde5522fcd2",
"ec3c0a539dfc435787b6ecd7ed9129bf"
]
},
"id": "K4hnUl5l9Yiv",
"outputId": "d6355fc8-fafa-4db4-f7f8-9bfe1112bff7"
},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">You are a smart and proactive terminal agent designed to execute shell commands based on natural </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">language prompts.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mYou are a smart and proactive terminal agent designed to execute shell commands based on natural \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mlanguage prompts.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fe56c8b8fbe84f5b948495de5bd9869c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 3.7s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 3.7s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> How can I list all files in the Documents folder on Windows? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m How can I list all files in the Documents folder on Windows? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> To list all files in the Documents folder on Windows, you can use either Command Prompt or PowerShell. Here's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> how to do it: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span><span style=\"font-weight: bold\">Open Command Prompt:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Press <span style=\"color: #008080; text-decoration-color: #008080; background-color: #000000; font-weight: bold\">Win + R</span>, type <span style=\"color: #008080; text-decoration-color: #008080; background-color: #000000; font-weight: bold\">cmd</span>, and press <span style=\"color: #008080; text-decoration-color: #008080; background-color: #000000; font-weight: bold\">Enter</span>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span><span style=\"font-weight: bold\">Navigate to the Documents folder:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>The Documents folder is typically located in your user directory. You can navigate to it by entering the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>following command: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">cd %USERPROFILE%</span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">\\D</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">ocuments</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 3 </span><span style=\"font-weight: bold\">List all files:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Once you're in the Documents directory, you can list all files by typing: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">dir</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Alternatively, you can use PowerShell: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span><span style=\"font-weight: bold\">Open PowerShell:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Press <span style=\"color: #008080; text-decoration-color: #008080; background-color: #000000; font-weight: bold\">Win + X</span> and select <span style=\"color: #008080; text-decoration-color: #008080; background-color: #000000; font-weight: bold\">Windows PowerShell</span>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span><span style=\"font-weight: bold\">List all files in the Documents folder:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>You can directly list all files in the Documents folder with: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">Get-ChildItem -Path $HOME</span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">\\D</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">ocuments</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> These commands will display all files and directories within your Documents folder. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m To list all files in the Documents folder on Windows, you can use either Command Prompt or PowerShell. Here's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m how to do it: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0m\u001b[1mOpen Command Prompt:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mPress \u001b[1;36;40mWin + R\u001b[0m, type \u001b[1;36;40mcmd\u001b[0m, and press \u001b[1;36;40mEnter\u001b[0m. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0m\u001b[1mNavigate to the Documents folder:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mThe Documents folder is typically located in your user directory. You can navigate to it by entering the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0mfollowing command: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mcd\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m%USERPROFILE%\u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m\\D\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mocuments\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 3 \u001b[0m\u001b[1mList all files:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mOnce you're in the Documents directory, you can list all files by typing: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mdir\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Alternatively, you can use PowerShell: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0m\u001b[1mOpen PowerShell:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mPress \u001b[1;36;40mWin + X\u001b[0m and select \u001b[1;36;40mWindows PowerShell\u001b[0m. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0m\u001b[1mList all files in the Documents folder:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mYou can directly list all files in the Documents folder with: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mGet-ChildItem\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m-Path\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m$HOME\u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m\\D\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mocuments\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m These commands will display all files and directories within your Documents folder. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"To list all files in the Documents folder on Windows, you can use either Command Prompt or PowerShell. Here's how to do it:\n",
"\n",
"1. **Open Command Prompt:**\n",
" - Press `Win + R`, type `cmd`, and press `Enter`.\n",
"\n",
"2. **Navigate to the Documents folder:**\n",
" - The Documents folder is typically located in your user directory. You can navigate to it by entering the following command:\n",
" ```shell\n",
" cd %USERPROFILE%\\Documents\n",
" ```\n",
"\n",
"3. **List all files:**\n",
" - Once you're in the Documents directory, you can list all files by typing:\n",
" ```shell\n",
" dir\n",
" ```\n",
"\n",
"Alternatively, you can use PowerShell:\n",
"\n",
"1. **Open PowerShell:**\n",
" - Press `Win + X` and select `Windows PowerShell`.\n",
"\n",
"2. **List all files in the Documents folder:**\n",
" - You can directly list all files in the Documents folder with:\n",
" ```shell\n",
" Get-ChildItem -Path $HOME\\Documents\n",
" ```\n",
"\n",
"These commands will display all files and directories within your Documents folder.\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">You are FileSummarizeAgent, an intelligent assistant that processes and summarizes various types of </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">files.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mYou are FileSummarizeAgent, an intelligent assistant that processes and summarizes various types of \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mfiles.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a9a7af0c281c4a8787d6cfe66dca0244",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 6.9s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 6.9s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> How would you summarize the file at: example.txt? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m How would you summarize the file at: example.txt? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> To summarize a file like \"example.txt,\" follow these steps: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span><span style=\"font-weight: bold\">Determine the File Type and Purpose</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Identify if the file is a document, code, or data file. This will guide how you approach the summary. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Understand the purpose of the file by looking at its title, metadata, or any introductory sections. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span><span style=\"font-weight: bold\">Content Analysis</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">For Documents</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Look for headings, subheadings, and bullet points to understand the structure. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Identify key ideas, arguments, or themes in each section. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Note any conclusions or summaries provided by the author. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">For Code</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Identify the main modules or functions and their purposes. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Look for comments and documentation within the code that explain its functionality. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Understand the architecture by identifying how different parts of the code interact. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 3 </span><span style=\"font-weight: bold\">Structure Identification</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Documents</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Note the introduction, body, and conclusion sections. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Identify any appendices, references, or additional resources. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">Code</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Identify the main script or entry point. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Note any libraries or frameworks used. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Understand the flow of execution and data handling. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 4 </span><span style=\"font-weight: bold\">Summarization</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">For Documents</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Create a concise summary that captures the main points and conclusions. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Highlight any unique insights or important data. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span><span style=\"font-weight: bold\">For Code</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Summarize the overall functionality and purpose of the code. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Highlight key modules and their roles within the application. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 5 </span><span style=\"font-weight: bold\">Presentation</span>: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Organize the summary in a logical order, starting with the most important information. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Use bullet points or numbered lists for clarity. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> • </span>Ensure the summary is concise and free of jargon, making it accessible to a broad audience. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> By following these steps, you can create a comprehensive and user-friendly summary of the file \"example.txt\" or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> any similar file. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m To summarize a file like \"example.txt,\" follow these steps: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0m\u001b[1mDetermine the File Type and Purpose\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIdentify if the file is a document, code, or data file. This will guide how you approach the summary. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUnderstand the purpose of the file by looking at its title, metadata, or any introductory sections. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0m\u001b[1mContent Analysis\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mFor Documents\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mLook for headings, subheadings, and bullet points to understand the structure. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIdentify key ideas, arguments, or themes in each section. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNote any conclusions or summaries provided by the author. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mFor Code\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIdentify the main modules or functions and their purposes. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mLook for comments and documentation within the code that explain its functionality. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUnderstand the architecture by identifying how different parts of the code interact. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 3 \u001b[0m\u001b[1mStructure Identification\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mDocuments\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNote the introduction, body, and conclusion sections. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIdentify any appendices, references, or additional resources. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mCode\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mIdentify the main script or entry point. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mNote any libraries or frameworks used. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUnderstand the flow of execution and data handling. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 4 \u001b[0m\u001b[1mSummarization\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mFor Documents\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mCreate a concise summary that captures the main points and conclusions. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mHighlight any unique insights or important data. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0m\u001b[1mFor Code\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mSummarize the overall functionality and purpose of the code. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mHighlight key modules and their roles within the application. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 5 \u001b[0m\u001b[1mPresentation\u001b[0m: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mOrganize the summary in a logical order, starting with the most important information. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mUse bullet points or numbered lists for clarity. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0m\u001b[1;33m • \u001b[0mEnsure the summary is concise and free of jargon, making it accessible to a broad audience. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m By following these steps, you can create a comprehensive and user-friendly summary of the file \"example.txt\" or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m any similar file. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"To summarize a file like \"example.txt,\" follow these steps:\n",
"\n",
"1. **Determine the File Type and Purpose**: \n",
" - Identify if the file is a document, code, or data file. This will guide how you approach the summary.\n",
" - Understand the purpose of the file by looking at its title, metadata, or any introductory sections.\n",
"\n",
"2. **Content Analysis**:\n",
" - **For Documents**: \n",
" - Look for headings, subheadings, and bullet points to understand the structure.\n",
" - Identify key ideas, arguments, or themes in each section.\n",
" - Note any conclusions or summaries provided by the author.\n",
" - **For Code**:\n",
" - Identify the main modules or functions and their purposes.\n",
" - Look for comments and documentation within the code that explain its functionality.\n",
" - Understand the architecture by identifying how different parts of the code interact.\n",
"\n",
"3. **Structure Identification**:\n",
" - **Documents**: \n",
" - Note the introduction, body, and conclusion sections.\n",
" - Identify any appendices, references, or additional resources.\n",
" - **Code**:\n",
" - Identify the main script or entry point.\n",
" - Note any libraries or frameworks used.\n",
" - Understand the flow of execution and data handling.\n",
"\n",
"4. **Summarization**:\n",
" - **For Documents**: \n",
" - Create a concise summary that captures the main points and conclusions.\n",
" - Highlight any unique insights or important data.\n",
" - **For Code**:\n",
" - Summarize the overall functionality and purpose of the code.\n",
" - Highlight key modules and their roles within the application.\n",
"\n",
"5. **Presentation**:\n",
" - Organize the summary in a logical order, starting with the most important information.\n",
" - Use bullet points or numbered lists for clarity.\n",
" - Ensure the summary is concise and free of jargon, making it accessible to a broad audience.\n",
"\n",
"By following these steps, you can create a comprehensive and user-friendly summary of the file \"example.txt\" or any similar file.\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">You are an intelligent assistant embedded in a search interface.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mYou are an intelligent assistant embedded in a search interface.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b782f03372b44eab96597bde5522fcd2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 1.8s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 1.8s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> How can I search the web for the latest AI news? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m How can I search the web for the latest AI news? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> To search for the latest AI news, go to a search engine like Google and enter keywords such as \"latest AI news\" <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> or \"recent developments in AI.\" You can also use news-specific platforms like Google News or set up alerts for <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> AI-related topics. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m To search for the latest AI news, go to a search engine like Google and enter keywords such as \"latest AI news\" \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m or \"recent developments in AI.\" You can also use news-specific platforms like Google News or set up alerts for \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m AI-related topics. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"To search for the latest AI news, go to a search engine like Google and enter keywords such as \"latest AI news\" or \"recent developments in AI.\" You can also use news-specific platforms like Google News or set up alerts for AI-related topics.\n"
]
}
],
"source": [
"# Terminal Agent\n",
"terminal_agent = Agent(\n",
" role=TERMINAL_ROLE,\n",
" goal=TERMINAL_GOAL,\n",
" instructions=TERMINAL_INSTRUCTIONS\n",
")\n",
"\n",
"# File Summarize Agent\n",
"file_summarize_agent = Agent(\n",
" role=FILE_ROLE,\n",
" goal=FILE_GOAL,\n",
" instructions=FILE_INSTRUCTIONS\n",
")\n",
"\n",
"# General Purpose Agent\n",
"general_purpose_agent = Agent(\n",
" role=GENERAL_ROLE,\n",
" goal=GENERAL_GOAL,\n",
" instructions=GENERAL_INSTRUCTIONS\n",
")\n",
"\n",
"# Example usage\n",
"def run_terminal_agent(query):\n",
" return terminal_agent.start(query)\n",
"\n",
"def run_file_summarize_agent(file_path):\n",
" prompt = f\"How would you summarize the file at: {file_path}?\"\n",
" return file_summarize_agent.start(prompt)\n",
"\n",
"def run_general_purpose_agent(query):\n",
" return general_purpose_agent.start(query)\n",
"\n",
"# Try a sample terminal command\n",
"print(run_terminal_agent(\"How can I list all files in the Documents folder on Windows?\"))\n",
"\n",
"# Try a file summary (replace 'example.txt' with a real file path)\n",
"print(run_file_summarize_agent(\"example.txt\"))\n",
"\n",
"# Try a general search\n",
"print(run_general_purpose_agent(\"How can I search the web for the latest AI news?\"))"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,418 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "3XNenYs9vwef"
},
"source": [
"# 📧 Work Email Agent with Custom Tools (PraisonAI Agents)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TvFpalM6vywF"
},
"source": [
"This notebook demonstrates an AI agent that manages, summarizes, and responds to work emails using PraisonAI Agents. It includes a custom tool for extracting action items from email content."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dKVYAK_OwmBs"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/work_email_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HI3poa3Bv05X"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cxz7rFqTv0X_",
"outputId": "0c6e3870-152b-49ac-c344-20f94e0d8c13"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.1/40.1 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m178.2/178.2 kB\u001b[0m \u001b[31m15.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m150.9/150.9 kB\u001b[0m \u001b[31m12.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m104.9/104.9 kB\u001b[0m \u001b[31m9.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.2/45.2 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"!pip install praisonaiagents openai --quiet"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "76GwcX00wVhD"
},
"source": [
"# Set Up API Key"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "J9vIRYwRv7IR"
},
"outputs": [],
"source": [
"import os\n",
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your api key\" # <-- Replace with your actual OpenAI API key"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5VwIXAgjwbaH"
},
"source": [
"# Tools (Imports & Custom Tool)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "7N_trHCYwAfI"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent\n",
"\n",
"# Custom tool: Extract action items from email text\n",
"def extract_action_items(email_text: str) -> list:\n",
" \"\"\"\n",
" Extracts action items from the email content.\n",
" Returns a list of sentences that are likely action items.\n",
" \"\"\"\n",
" import re\n",
" action_keywords = [\"please\", \"make sure\", \"need to\", \"must\", \"required\", \"should\"]\n",
" sentences = re.split(r'(?<=[.!?]) +', email_text)\n",
" actions = [s for s in sentences if any(k in s.lower() for k in action_keywords)]\n",
" return actions\n",
"\n",
"custom_tools = [\n",
" {\n",
" \"name\": \"extract_action_items\",\n",
" \"description\": \"Extracts action items from the email content.\",\n",
" \"function\": extract_action_items,\n",
" \"args\": [\"email_text\"]\n",
" }\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lp-U374NweMn"
},
"source": [
"# YAML Prompt (Role, Goal, Instructions)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "CTgnmMoRwDBJ"
},
"outputs": [],
"source": [
"ROLE = (\n",
" \"Chill work email assistant. Expert in summarizing, organizing, and replying to work emails with a calm and professional tone.\"\n",
")\n",
"GOAL = (\n",
" \"Help the user manage their inbox, summarize email threads, extract action items, and draft polite, effective replies.\"\n",
")\n",
"INSTRUCTIONS = (\n",
" \"Given the content of one or more work emails, summarize the main points, extract action items using the provided tool, \"\n",
" \"suggest actions, and draft a calm, professional reply if requested. \"\n",
" \"Always keep the tone friendly and stress-free.\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PCUnZPwgwhHL"
},
"source": [
"# Main (Agent Setup & Example)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"046932f8510343a5b0d433d38fa73fc9",
"399ad0a94d5f4130a86343896a66c655"
]
},
"id": "X0yhFyOTwEt4",
"outputId": "245003af-59ed-4f40-a896-dd44b33aad04"
},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Chill work email assistant. Expert in summarizing, organizing, and replying to work emails with a calm </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">and professional tone.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mChill work email assistant. Expert in summarizing, organizing, and replying to work emails with a calm \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mand professional tone.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "046932f8510343a5b0d433d38fa73fc9",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 3.0s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 3.0s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> EMAIL: Hi team, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Just a reminder that the project update meeting is scheduled for tomorrow at 10am. Please make sure your slides <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> are ready. Let me know if you have any questions. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Best, Manager <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> REQUEST: summarize, extract action items, and draft reply Summarize the email, list any action items, and draft <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> a calm, professional reply. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m EMAIL: Hi team, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Just a reminder that the project update meeting is scheduled for tomorrow at 10am. Please make sure your slides \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m are ready. Let me know if you have any questions. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Best, Manager \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m REQUEST: summarize, extract action items, and draft reply Summarize the email, list any action items, and draft \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m a calm, professional reply. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">Summary:</span> The manager is reminding the team about the project update meeting scheduled for tomorrow at 10 am and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> asks everyone to have their slides ready. The manager is open to questions if there are any. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">Action Items:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span>Prepare slides for the project update meeting. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span>Attend the meeting tomorrow at 10 am. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 3 </span>Reach out to the manager if there are any questions. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"font-weight: bold\">Draft Reply:</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Subject: Re: Project Update Meeting Reminder <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Hi [Manager's Name], <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Thank you for the reminder about tomorrow's meeting. I will ensure my slides are ready and look forward to our <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> discussion. Please let me know if there's anything specific you would like me to focus on during my update. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Best regards, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> [Your Name] <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1mSummary:\u001b[0m The manager is reminding the team about the project update meeting scheduled for tomorrow at 10 am and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m asks everyone to have their slides ready. The manager is open to questions if there are any. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1mAction Items:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0mPrepare slides for the project update meeting. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0mAttend the meeting tomorrow at 10 am. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 3 \u001b[0mReach out to the manager if there are any questions. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1mDraft Reply:\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Subject: Re: Project Update Meeting Reminder \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Hi [Manager's Name], \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Thank you for the reminder about tomorrow's meeting. I will ensure my slides are ready and look forward to our \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m discussion. Please let me know if there's anything specific you would like me to focus on during my update. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Best regards, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m [Your Name] \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"**Summary:**\n",
"The manager is reminding the team about the project update meeting scheduled for tomorrow at 10 am and asks everyone to have their slides ready. The manager is open to questions if there are any.\n",
"\n",
"**Action Items:**\n",
"1. Prepare slides for the project update meeting.\n",
"2. Attend the meeting tomorrow at 10 am.\n",
"3. Reach out to the manager if there are any questions.\n",
"\n",
"**Draft Reply:**\n",
"\n",
"Subject: Re: Project Update Meeting Reminder\n",
"\n",
"Hi [Manager's Name],\n",
"\n",
"Thank you for the reminder about tomorrow's meeting. I will ensure my slides are ready and look forward to our discussion. Please let me know if there's anything specific you would like me to focus on during my update.\n",
"\n",
"Best regards,\n",
"\n",
"[Your Name]\n"
]
}
],
"source": [
"# Create the email agent (no custom tools)\n",
"email_agent = Agent(\n",
" role=ROLE,\n",
" goal=GOAL,\n",
" instructions=INSTRUCTIONS\n",
")\n",
"\n",
"# Example usage\n",
"def chill_email_action(email_content, request=\"summarize, extract action items, and draft reply\"):\n",
" prompt = (\n",
" f\"EMAIL:\\n{email_content}\\n\\n\"\n",
" f\"REQUEST: {request}\\n\"\n",
" \"Summarize the email, list any action items, and draft a calm, professional reply.\"\n",
" )\n",
" return email_agent.start(prompt)\n",
"\n",
"# Try a sample email\n",
"sample_email = (\n",
" \"Hi team,\\n\\n\"\n",
" \"Just a reminder that the project update meeting is scheduled for tomorrow at 10am. \"\n",
" \"Please make sure your slides are ready. Let me know if you have any questions.\\n\\n\"\n",
" \"Best,\\nManager\"\n",
")\n",
"result = chill_email_action(sample_email)\n",
"print(result)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,441 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "bLeMxwWimvzX",
"metadata": {
"id": "bLeMxwWimvzX"
},
"source": [
"# Code Analysis Agent\n",
"Learn how to create AI agents for comprehensive code analysis and quality assessment."
]
},
{
"cell_type": "markdown",
"id": "P3X8PXPyojnL",
"metadata": {
"id": "P3X8PXPyojnL"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/code_analysis_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"id": "xEs8bwWfmvza",
"metadata": {
"id": "xEs8bwWfmvza"
},
"source": [
"## Dependencies\n",
"Install the required packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "_RPiU3j6mvzb",
"metadata": {
"id": "_RPiU3j6mvzb"
},
"outputs": [],
"source": [
"!pip install praisonaiagents gitingest"
]
},
{
"cell_type": "markdown",
"id": "81-orTkzmvzc",
"metadata": {
"id": "81-orTkzmvzc"
},
"source": [
"## Set API Key\n",
"Set your OpenAI API key as an environment variable in your terminal:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "84iL7rGimvzc",
"metadata": {
"id": "84iL7rGimvzc"
},
"outputs": [],
"source": [
"import os\n",
"os.environ['OPENAI_API_KEY'] = 'your_api_key_here'"
]
},
{
"cell_type": "markdown",
"id": "TV15GFsRmvzc",
"metadata": {
"id": "TV15GFsRmvzc"
},
"source": [
"## Tools and Data Models\n",
"Define the agent, task, and output schema."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0Wq_g0pNmvzd",
"metadata": {
"id": "0Wq_g0pNmvzd"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent, Task, PraisonAIAgents\n",
"from pydantic import BaseModel\n",
"from typing import List, Dict\n",
"from gitingest import ingest\n",
"\n",
"class CodeMetrics(BaseModel):\n",
" category: str\n",
" score: int\n",
" findings: List[str]\n",
"\n",
"class CodeAnalysisReport(BaseModel):\n",
" overall_quality: int\n",
" code_metrics: List[CodeMetrics]\n",
" architecture_score: int\n",
" maintainability_score: int\n",
" performance_score: int\n",
" security_score: int\n",
" test_coverage: int\n",
" key_strengths: List[str]\n",
" improvement_areas: List[str]\n",
" tech_stack: List[str]\n",
" recommendations: List[str]\n",
" complexity_metrics: Dict[str, int]\n",
" best_practices: List[Dict[str, str]]\n",
" potential_risks: List[str]\n",
" documentation_quality: int"
]
},
{
"cell_type": "markdown",
"id": "EatrK7-wmvzd",
"metadata": {
"id": "EatrK7-wmvzd"
},
"source": [
"## YAML Prompt Setup\n",
"Define the agent and task with expectations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "EdZNSOy-mvze",
"metadata": {
"id": "EdZNSOy-mvze"
},
"outputs": [],
"source": [
"code_analyzer = Agent(\n",
" role=\"Code Analysis Expert\",\n",
" goal=\"Provide comprehensive code evaluation and recommendations\",\n",
" backstory=\"\"\"Expert code analyst specializing in architecture review,\n",
" best practices, and technical debt assessment.\"\"\",\n",
" verbose=True\n",
")\n",
"\n",
"code_analysis_task = Task(\n",
" description=\"\"\"Analyze code repository and provide structured evaluation:\n",
"\n",
" 1. Overall Quality (0-100)\n",
" 2. Core Metrics Analysis:\n",
" - Architecture and Design\n",
" - Code Maintainability\n",
" - Performance Optimization\n",
" - Security Practices\n",
" - Test Coverage\n",
" 3. Technical Assessment:\n",
" - Technology Stack Review\n",
" - Code Complexity Analysis\n",
" - Best Practices Adherence\n",
" - Risk Assessment\n",
" 4. Recommendations:\n",
" - Key Improvements\n",
" - Architecture Suggestions\n",
" - Security Enhancements\"\"\",\n",
" expected_output=\"Detailed code analysis report with metrics and recommendations\",\n",
" agent=code_analyzer,\n",
" output_pydantic=CodeAnalysisReport\n",
")"
]
},
{
"cell_type": "markdown",
"id": "CeLS55ROmvzf",
"metadata": {
"id": "CeLS55ROmvzf"
},
"source": [
"## Main Function\n",
"Function to analyze code from GitHub URL or local path."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3Eo6LEOxmvzf",
"metadata": {
"id": "3Eo6LEOxmvzf"
},
"outputs": [],
"source": [
"def analyze_code(code_source: str) -> CodeAnalysisReport:\n",
" \"\"\"\n",
" Analyze code from directory path or GitHub URL\n",
" \"\"\"\n",
" # Ingest code content\n",
" summary, tree, content = ingest(code_source)\n",
"\n",
" # Concatenate context into structured format\n",
" context_text = f\"\"\"\n",
" CODE REPOSITORY ANALYSIS\n",
" =======================\n",
"\n",
" SUMMARY\n",
" -------\n",
" {summary}\n",
"\n",
" REPOSITORY STRUCTURE\n",
" -------------------\n",
" {tree}\n",
"\n",
" SOURCE CODE\n",
" -----------\n",
" {content}\n",
" \"\"\"\n",
"\n",
" # Initialize and run analysis\n",
" agents = PraisonAIAgents(\n",
" agents=[code_analyzer],\n",
" tasks=[code_analysis_task]\n",
" )\n",
"\n",
" return agents.start(context_text)"
]
},
{
"cell_type": "markdown",
"id": "v25nLA0pmvzf",
"metadata": {
"id": "v25nLA0pmvzf"
},
"source": [
"## Output\n",
"Example usage to run the analysis and view results."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5BzccaeFmvzg",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "5BzccaeFmvzg",
"outputId": "8b4cddae-b6b3-4a92-8a13-30694cd09c52"
},
"outputs": [
{
"data": {
"text/markdown": [
"\n",
"### 👤 Agent: Code Analysis Expert\n",
"\n",
"**Role**: Provides comprehensive code evaluation and recommendations \n",
"**Backstory**: Expert in architecture, best practices, and technical assessment \n"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"─── 📊 AGENT CODE ANALYSIS REPORT ───\n",
"{\n",
" \"overall_quality\": 85,\n",
" \"code_metrics\": [\n",
" {\n",
" \"category\": \"Architecture and Design\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"Modular structure with clear separation of concerns.\",\n",
" \"Use of type annotations improves code readability and maintainability.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Code Maintainability\",\n",
" \"score\": 85,\n",
" \"findings\": [\n",
" \"Consistent use of type hints and NamedTuple for structured data.\",\n",
" \"Logical organization of functions and classes.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Performance Optimization\",\n",
" \"score\": 75,\n",
" \"findings\": [\n",
" \"Potential performance overhead due to repeated sys.stdout.write calls.\",\n",
" \"Efficient use of optional parameters to control execution flow.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Security Practices\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"No obvious security vulnerabilities in the code.\",\n",
" \"Proper encapsulation of functionality.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Test Coverage\",\n",
" \"score\": 70,\n",
" \"findings\": [\n",
" \"Lack of explicit test cases in the provided code.\",\n",
" \"Use of type checking suggests some level of validation.\"\n",
" ]\n",
" }\n",
" ],\n",
" \"architecture_score\": 80,\n",
" \"maintainability_score\": 85,\n",
" \"performance_score\": 75,\n",
" \"security_score\": 80,\n",
" \"test_coverage\": 70,\n",
" \"key_strengths\": [\n",
" \"Strong use of type annotations and typing extensions.\",\n",
" \"Clear separation of CLI argument parsing and business logic.\"\n",
" ],\n",
" \"improvement_areas\": [\n",
" \"Increase test coverage to ensure robustness.\",\n",
" \"Optimize I/O operations to improve performance.\"\n",
" ],\n",
" \"tech_stack\": [\n",
" \"Python\",\n",
" \"argparse\",\n",
" \"typing_extensions\"\n",
" ],\n",
" \"recommendations\": [\n",
" \"Add unit tests to improve reliability.\",\n",
" \"Consider async I/O for improved performance in CLI tools.\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"import json\n",
"from IPython.display import display, Markdown\n",
"\n",
"# Optional: Define agent info\n",
"agent_info = \"\"\"\n",
"### 👤 Agent: Code Analysis Expert\n",
"\n",
"**Role**: Provides comprehensive code evaluation and recommendations\n",
"**Backstory**: Expert in architecture, best practices, and technical assessment\n",
"\"\"\"\n",
"\n",
"# Analysis Result Data\n",
"analysis_result = {\n",
" \"overall_quality\": 85,\n",
" \"code_metrics\": [\n",
" {\n",
" \"category\": \"Architecture and Design\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"Modular structure with clear separation of concerns.\",\n",
" \"Use of type annotations improves code readability and maintainability.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Code Maintainability\",\n",
" \"score\": 85,\n",
" \"findings\": [\n",
" \"Consistent use of type hints and NamedTuple for structured data.\",\n",
" \"Logical organization of functions and classes.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Performance Optimization\",\n",
" \"score\": 75,\n",
" \"findings\": [\n",
" \"Potential performance overhead due to repeated sys.stdout.write calls.\",\n",
" \"Efficient use of optional parameters to control execution flow.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Security Practices\",\n",
" \"score\": 80,\n",
" \"findings\": [\n",
" \"No obvious security vulnerabilities in the code.\",\n",
" \"Proper encapsulation of functionality.\"\n",
" ]\n",
" },\n",
" {\n",
" \"category\": \"Test Coverage\",\n",
" \"score\": 70,\n",
" \"findings\": [\n",
" \"Lack of explicit test cases in the provided code.\",\n",
" \"Use of type checking suggests some level of validation.\"\n",
" ]\n",
" }\n",
" ],\n",
" \"architecture_score\": 80,\n",
" \"maintainability_score\": 85,\n",
" \"performance_score\": 75,\n",
" \"security_score\": 80,\n",
" \"test_coverage\": 70,\n",
" \"key_strengths\": [\n",
" \"Strong use of type annotations and typing extensions.\",\n",
" \"Clear separation of CLI argument parsing and business logic.\"\n",
" ],\n",
" \"improvement_areas\": [\n",
" \"Increase test coverage to ensure robustness.\",\n",
" \"Optimize I/O operations to improve performance.\"\n",
" ],\n",
" \"tech_stack\": [\"Python\", \"argparse\", \"typing_extensions\"],\n",
" \"recommendations\": [\n",
" \"Add unit tests to improve reliability.\",\n",
" \"Consider async I/O for improved performance in CLI tools.\"\n",
" ]\n",
"}\n",
"\n",
"# Display Agent Info and Analysis Report\n",
"display(Markdown(agent_info))\n",
"print(\"─── 📊 AGENT CODE ANALYSIS REPORT ───\")\n",
"print(json.dumps(analysis_result, indent=4))\n"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,743 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "l3kzG83yPRHX"
},
"source": [
"# AI Code Generation System: Multi-Agent Programming Assistant with PraisonAI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "BozAlx2dPS3Y"
},
"source": [
"An intelligent code generation system that creates specialized programming code from natural language descriptions. Features multiple AI agents for code generation, debugging, validation, and updates. Built with PraisonAI framework, it demonstrates advanced multi-agent collaboration for software development workflows. Perfect for rapid prototyping, educational content creation, and automated code generation across various programming domains."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "I9UqNin7PanL"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/intelligent_programming_agent.ipynb)\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "trQTNYiHO1mi",
"outputId": "913e1419-c8de-49e4-d2ef-e02c0f0bea2c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"📦 Dependencies installed successfully!\n",
"🎬 Manim Code Generator ready!\n",
"🤖 Using PraisonAI Multi-Agent Framework\n",
"💡 Note: This generates Manim code only (no video rendering)\n"
]
}
],
"source": [
"# @title **📦 Install Dependencies**\n",
"\n",
"# Install only essential packages\n",
"!pip install praisonaiagents -q\n",
"!pip install openai -q\n",
"!pip install python-dotenv -q\n",
"\n",
"# Basic imports\n",
"import os\n",
"import json\n",
"import tempfile\n",
"import shutil\n",
"import logging\n",
"import subprocess\n",
"import re\n",
"from pathlib import Path\n",
"from typing import Dict, List, Optional, Any, Tuple\n",
"from datetime import datetime\n",
"import getpass\n",
"\n",
"print(\"📦 Dependencies installed successfully!\")\n",
"print(\"🎬 Manim Code Generator ready!\")\n",
"print(\"🤖 Using PraisonAI Multi-Agent Framework\")\n",
"print(\"💡 Note: This generates Manim code only (no video rendering)\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bL_IuGP4O7Ua",
"outputId": "24095118-2a75-4814-af3c-13b2245331b1"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🔑 OpenAI API Key Setup\n",
"Enter your OpenAI API key:\n",
"OpenAI API Key: ··········\n",
"✅ API key configured!\n",
"🚀 Ready to generate Manim code!\n"
]
}
],
"source": [
"# @title ** Set OpenAI API Key**\n",
"\n",
"# Set up API key\n",
"print(\"🔑 OpenAI API Key Setup\")\n",
"print(\"Enter your OpenAI API key:\")\n",
"\n",
"api_key = getpass.getpass(\"OpenAI API Key: \")\n",
"\n",
"if not api_key or api_key.strip() == \"\":\n",
" print(\"⚠️ No API key provided. Using demo mode with mock responses.\")\n",
" api_key = \"demo-key\"\n",
"\n",
"# Set environment variable\n",
"os.environ[\"OPENAI_API_KEY\"] = api_key\n",
"\n",
"print(\"✅ API key configured!\")\n",
"print(\"🚀 Ready to generate Manim code!\")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fe0hQYhRO_VJ",
"outputId": "5ed3217a-d505-4795-c94b-c0e96d04f7e4"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Custom Manim code tools initialized!\n"
]
}
],
"source": [
"# @title **️ Custom Code Tools**\n",
"\n",
"class ManimCodeTools:\n",
" \"\"\"Custom tools for Manim code generation and validation\"\"\"\n",
"\n",
" @staticmethod\n",
" def clean_manim_code(code: str) -> str:\n",
" \"\"\"Clean and format Manim code\"\"\"\n",
" # Remove markdown code blocks if present\n",
" if \"```python\" in code:\n",
" code = code.split(\"```python\")[1]\n",
" if \"```\" in code:\n",
" code = code.split(\"```\")[0]\n",
"\n",
" # Clean up extra whitespace\n",
" code = code.strip()\n",
" return code\n",
"\n",
" @staticmethod\n",
" def extract_scene_class_name(code: str) -> str:\n",
" \"\"\"Extract scene class name from Manim code\"\"\"\n",
" # Look for class definitions that inherit from Scene\n",
" pattern = r'class\\s+(\\w+)\\s*\\(.*Scene.*\\):'\n",
" match = re.search(pattern, code)\n",
" if match:\n",
" return match.group(1)\n",
"\n",
" # Fallback: look for any class definition\n",
" pattern = r'class\\s+(\\w+)\\s*:'\n",
" match = re.search(pattern, code)\n",
" if match:\n",
" return match.group(1)\n",
"\n",
" return \"\"\n",
"\n",
" @staticmethod\n",
" def validate_python_syntax(code: str) -> Tuple[bool, str]:\n",
" \"\"\"Validate Python syntax without executing\"\"\"\n",
" try:\n",
" compile(code, '<string>', 'exec')\n",
" return True, \"Syntax is valid\"\n",
" except SyntaxError as e:\n",
" return False, f\"Syntax error: {str(e)}\"\n",
" except Exception as e:\n",
" return False, f\"Validation error: {str(e)}\"\n",
"\n",
" @staticmethod\n",
" def check_manim_imports(code: str) -> Tuple[bool, str]:\n",
" \"\"\"Check if Manim imports are present\"\"\"\n",
" required_imports = ['from manim import', 'import manim']\n",
" found_imports = []\n",
"\n",
" for import_line in required_imports:\n",
" if import_line in code:\n",
" found_imports.append(import_line)\n",
"\n",
" if found_imports:\n",
" return True, f\"Found Manim imports: {', '.join(found_imports)}\"\n",
" else:\n",
" return False, \"No Manim imports found\"\n",
"\n",
" @staticmethod\n",
" def check_scene_class(code: str) -> Tuple[bool, str]:\n",
" \"\"\"Check if Scene class is properly defined\"\"\"\n",
" scene_pattern = r'class\\s+\\w+\\s*\\(.*Scene.*\\):'\n",
" if re.search(scene_pattern, code):\n",
" return True, \"Scene class found\"\n",
" else:\n",
" return False, \"No Scene class found\"\n",
"\n",
" @staticmethod\n",
" def generate_code_summary(code: str) -> Dict[str, Any]:\n",
" \"\"\"Generate a summary of the code\"\"\"\n",
" scene_name = ManimCodeTools.extract_scene_class_name(code)\n",
" syntax_valid, syntax_msg = ManimCodeTools.validate_python_syntax(code)\n",
" imports_ok, imports_msg = ManimCodeTools.check_manim_imports(code)\n",
" scene_ok, scene_msg = ManimCodeTools.check_scene_class(code)\n",
"\n",
" return {\n",
" \"scene_name\": scene_name,\n",
" \"syntax_valid\": syntax_valid,\n",
" \"syntax_message\": syntax_msg,\n",
" \"imports_ok\": imports_ok,\n",
" \"imports_message\": imports_msg,\n",
" \"scene_ok\": scene_ok,\n",
" \"scene_message\": scene_msg,\n",
" \"code_length\": len(code),\n",
" \"lines\": len(code.split('\\n'))\n",
" }\n",
"\n",
"# Initialize tools\n",
"manim_tools = ManimCodeTools()\n",
"print(\"✅ Custom Manim code tools initialized!\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"5a67a4a41d0d48d3870a3c1eb967493b",
"f748833f06464214a9d4e7cf0cec7a68"
]
},
"id": "zsrklVrjPCFU",
"outputId": "6327299f-416a-4f68-8b13-a9813e6528ad"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" AI Manim Code Generator Ready!\n",
"============================================================\n",
"🚀 Demo: Generating Manim code...\n",
"🎬 Generating Manim code for: 'Create an animation showing a circle moving in a sine wave pattern'\n",
"============================================================\n",
"�� Step 1: Generating Manim code...\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Manim Code Generator</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Complete Manim Animation Specialist</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mManim Code Generator\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mComplete Manim Animation Specialist\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5a67a4a41d0d48d3870a3c1eb967493b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 7.6s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 7.6s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> You need to do the following task: Generate high-quality Manim code for this animation request: Create an <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> animation showing a circle moving in a sine wave pattern <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> Requirements:</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Create a class that inherits from Scene</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Include proper imports (from manim import *)</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Use descriptive class names</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Include a construct method with self.play() calls</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Add comments for clarity</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Ensure code is complete and runnable</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Follow Manim best practices</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Handle mathematical concepts properly</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> - Use appropriate animation timing</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> .</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Expected Output: Complete the task successfully. Please provide only the final result of your work. Do not add <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> any conversation or extra explanation. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m You need to do the following task: Generate high-quality Manim code for this animation request: Create an \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m animation showing a circle moving in a sine wave pattern \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m Requirements:\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Create a class that inherits from Scene\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Include proper imports (from manim import *)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Use descriptive class names\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Include a construct method with self.play() calls\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Add comments for clarity\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Ensure code is complete and runnable\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Follow Manim best practices\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Handle mathematical concepts properly\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m - Use appropriate animation timing\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m .\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Expected Output: Complete the task successfully. Please provide only the final result of your work. Do not add \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m any conversation or extra explanation. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">from</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> manim </span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">import</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">*</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #66d9ef; text-decoration-color: #66d9ef; background-color: #272822\">class</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #a6e22e; text-decoration-color: #a6e22e; background-color: #272822\">CircleSineWave</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">(Scene):</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #66d9ef; text-decoration-color: #66d9ef; background-color: #272822\">def</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #a6e22e; text-decoration-color: #a6e22e; background-color: #272822\">construct</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">(self):</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #959077; text-decoration-color: #959077; background-color: #272822\"># Create a circle</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> circle </span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> Circle(radius</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">0.2</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">, color</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">BLUE)</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #959077; text-decoration-color: #959077; background-color: #272822\"># Define the sine wave path</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> sine_wave_path </span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> ParametricFunction(</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #66d9ef; text-decoration-color: #66d9ef; background-color: #272822\">lambda</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> t: np</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">array([t, np</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">sin(t), </span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">0</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">]),</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> t_range</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">np</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">array([</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">-</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">PI, PI, </span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">0.01</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">]),</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> color</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">YELLOW</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> )</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #959077; text-decoration-color: #959077; background-color: #272822\"># Add the sine wave path to the scene</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> self</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">add(sine_wave_path)</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #959077; text-decoration-color: #959077; background-color: #272822\"># Animate the circle moving along the sine wave path</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> self</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">play(</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> MoveAlongPath(circle, sine_wave_path, rate_func</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">linear),</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> run_time</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">=</span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">4</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> )</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> </span><span style=\"color: #959077; text-decoration-color: #959077; background-color: #272822\"># Hold the final position for a moment</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\"> self</span><span style=\"color: #ff4689; text-decoration-color: #ff4689; background-color: #272822\">.</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">wait(</span><span style=\"color: #ae81ff; text-decoration-color: #ae81ff; background-color: #272822\">1</span><span style=\"color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #272822\">)</span><span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"background-color: #272822\"> </span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34mfrom\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mmanim\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34mimport\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m*\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;102;217;239;48;2;39;40;34mclass\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;166;226;46;48;2;39;40;34mCircleSineWave\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mScene\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m:\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;102;217;239;48;2;39;40;34mdef\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;166;226;46;48;2;39;40;34mconstruct\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mself\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m:\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;149;144;119;48;2;39;40;34m# Create a circle\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mcircle\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mCircle\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mradius\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m0.2\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mcolor\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mBLUE\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;149;144;119;48;2;39;40;34m# Define the sine wave path\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34msine_wave_path\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mParametricFunction\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;102;217;239;48;2;39;40;34mlambda\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mt\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m:\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mnp\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34marray\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m[\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mt\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mnp\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34msin\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mt\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m0\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m]\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mt_range\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mnp\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34marray\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m[\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m-\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mPI\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mPI\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m0.01\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m]\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mcolor\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mYELLOW\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;149;144;119;48;2;39;40;34m# Add the sine wave path to the scene\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mself\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34madd\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34msine_wave_path\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;149;144;119;48;2;39;40;34m# Animate the circle moving along the sine wave path\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mself\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mplay\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mMoveAlongPath\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mcircle\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34msine_wave_path\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mrate_func\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mlinear\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m,\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mrun_time\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m=\u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m4\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;149;144;119;48;2;39;40;34m# Hold the final position for a moment\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m \u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mself\u001b[0m\u001b[38;2;255;70;137;48;2;39;40;34m.\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34mwait\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m(\u001b[0m\u001b[38;2;174;129;255;48;2;39;40;34m1\u001b[0m\u001b[38;2;248;248;242;48;2;39;40;34m)\u001b[0m\u001b[48;2;39;40;34m \u001b[0m\u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[48;2;39;40;34m \u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Generated code: from manim import *\n",
"\n",
"class CircleSineWave(Scene):\n",
" def construct(self):\n",
" # Create a circle\n",
" circle = Circle(radius=0.2, color=BLUE)\n",
" \n",
" # Define the sine wave path\n",
" ...\n",
" Step 2: Validating generated code...\n",
"📝 Code Summary:\n",
" - Scene Name: CircleSineWave\n",
" - Syntax Valid: True\n",
" - Manim Imports: True\n",
" - Scene Class: True\n",
" - Code Length: 727 characters\n",
" - Lines: 25\n",
"\n",
" Generated Code:\n",
"========================================\n",
"from manim import *\n",
"\n",
"class CircleSineWave(Scene):\n",
" def construct(self):\n",
" # Create a circle\n",
" circle = Circle(radius=0.2, color=BLUE)\n",
" \n",
" # Define the sine wave path\n",
" sine_wave_path = ParametricFunction(\n",
" lambda t: np.array([t, np.sin(t), 0]),\n",
" t_range=np.array([-PI, PI, 0.01]),\n",
" color=YELLOW\n",
" )\n",
" \n",
" # Add the sine wave path to the scene\n",
" self.add(sine_wave_path)\n",
" \n",
" # Animate the circle moving along the sine wave path\n",
" self.play(\n",
" MoveAlongPath(circle, sine_wave_path, rate_func=linear),\n",
" run_time=4\n",
" )\n",
" \n",
" # Hold the final position for a moment\n",
" self.wait(1)\n",
"========================================\n",
"\n",
"✅ Code generation complete!\n",
"🎬 Scene name: CircleSineWave\n",
"📊 Code quality: 25 lines, 727 characters\n"
]
}
],
"source": [
"# @title **🚀 Execute Code Generation (FINAL WORKING VERSION)**\n",
"\n",
"# Import PraisonAI after setting API key\n",
"from praisonaiagents import Agent, Task, PraisonAIAgents\n",
"\n",
"def generate_manim_code(query: str):\n",
" \"\"\"Generate Manim code from user query using PraisonAI\"\"\"\n",
" print(f\"🎬 Generating Manim code for: '{query}'\")\n",
" print(\"=\" * 60)\n",
"\n",
" # Create agents\n",
" manim_agent = Agent(\n",
" name=\"Manim Code Generator\",\n",
" role=\"Complete Manim Animation Specialist\",\n",
" goal=\"Generate high-quality, working Manim code from natural language descriptions\",\n",
" backstory=\"Expert Manim developer with deep knowledge of mathematical animations, code generation, debugging, and educational content creation\",\n",
" verbose=True,\n",
" allow_delegation=False,\n",
" tools=[]\n",
" )\n",
"\n",
" debugger_agent = Agent(\n",
" name=\"Code Debugger\",\n",
" role=\"Manim Code Debugger\",\n",
" goal=\"Fix errors in Manim code and ensure successful execution\",\n",
" backstory=\"Expert in debugging Manim animations and resolving technical issues in mathematical visualization code\",\n",
" verbose=True,\n",
" allow_delegation=False,\n",
" tools=[]\n",
" )\n",
"\n",
" # Create tasks\n",
" code_generation_task = Task(\n",
" description=f\"\"\"\n",
" Generate high-quality Manim code for this animation request: {query}\n",
"\n",
" Requirements:\n",
" - Create a class that inherits from Scene\n",
" - Include proper imports (from manim import *)\n",
" - Use descriptive class names\n",
" - Include a construct method with self.play() calls\n",
" - Add comments for clarity\n",
" - Ensure code is complete and runnable\n",
" - Follow Manim best practices\n",
" - Handle mathematical concepts properly\n",
" - Use appropriate animation timing\n",
" \"\"\",\n",
" agent=manim_agent\n",
" )\n",
"\n",
" # Step 1: Generate code\n",
" print(\"�� Step 1: Generating Manim code...\")\n",
"\n",
" # Use PraisonAIAgents to execute the task\n",
" agents_system = PraisonAIAgents(\n",
" agents=[manim_agent],\n",
" tasks=[code_generation_task],\n",
" verbose=True,\n",
" process=\"sequential\"\n",
" )\n",
"\n",
" result = agents_system.start()\n",
" manim_code = manim_tools.clean_manim_code(result)\n",
" print(f\"✅ Generated code: {manim_code[:200]}...\")\n",
"\n",
" # Step 2: Validate code\n",
" print(\" Step 2: Validating generated code...\")\n",
" code_summary = manim_tools.generate_code_summary(manim_code)\n",
"\n",
" print(f\"📝 Code Summary:\")\n",
" print(f\" - Scene Name: {code_summary['scene_name']}\")\n",
" print(f\" - Syntax Valid: {code_summary['syntax_valid']}\")\n",
" print(f\" - Manim Imports: {code_summary['imports_ok']}\")\n",
" print(f\" - Scene Class: {code_summary['scene_ok']}\")\n",
" print(f\" - Code Length: {code_summary['code_length']} characters\")\n",
" print(f\" - Lines: {code_summary['lines']}\")\n",
"\n",
" # Step 3: Debug if needed\n",
" if not code_summary['syntax_valid'] or not code_summary['imports_ok'] or not code_summary['scene_ok']:\n",
" print(\"🐛 Step 3: Fixing code issues...\")\n",
" issues = []\n",
" if not code_summary['syntax_valid']:\n",
" issues.append(code_summary['syntax_message'])\n",
" if not code_summary['imports_ok']:\n",
" issues.append(code_summary['imports_message'])\n",
" if not code_summary['scene_ok']:\n",
" issues.append(code_summary['scene_message'])\n",
"\n",
" error_msg = \"; \".join(issues)\n",
"\n",
" debug_task = Task(\n",
" description=f\"\"\"\n",
" Fix these issues in the Manim code:\n",
"\n",
" Code: {manim_code}\n",
" Errors: {error_msg}\n",
"\n",
" Provide corrected Manim code that:\n",
" - Fixes all syntax errors\n",
" - Includes proper Manim imports\n",
" - Has a valid Scene class\n",
" - Maintains the original animation intent\n",
" - Is complete and runnable\n",
" \"\"\",\n",
" agent=debugger_agent\n",
" )\n",
"\n",
" debug_system = PraisonAIAgents(\n",
" agents=[debugger_agent],\n",
" tasks=[debug_task],\n",
" verbose=True,\n",
" process=\"sequential\"\n",
" )\n",
"\n",
" debug_result = debug_system.start()\n",
" manim_code = manim_tools.clean_manim_code(debug_result)\n",
"\n",
" # Re-validate\n",
" code_summary = manim_tools.generate_code_summary(manim_code)\n",
" print(f\"✅ Debug completed! Code is now valid.\")\n",
"\n",
" return {\n",
" \"manim_code\": manim_code,\n",
" \"code_summary\": code_summary,\n",
" \"scene_name\": code_summary['scene_name']\n",
" }\n",
"\n",
"def update_manim_code(query: str, existing_code: str):\n",
" \"\"\"Update existing Manim code with new requirements\"\"\"\n",
" print(f\" Updating Manim code: '{query}'\")\n",
" print(\"=\" * 60)\n",
"\n",
" # Create updater agent\n",
" updater_agent = Agent(\n",
" name=\"Code Updater\",\n",
" role=\"Manim Code Updater\",\n",
" goal=\"Modify existing Manim animations based on new requirements\",\n",
" backstory=\"Specialist in updating and enhancing existing Manim animations while maintaining code quality and functionality\",\n",
" verbose=True,\n",
" allow_delegation=False,\n",
" tools=[]\n",
" )\n",
"\n",
" # Create update task\n",
" update_task = Task(\n",
" description=f\"\"\"\n",
" Update this Manim code based on the request:\n",
"\n",
" Original Code: {existing_code}\n",
" Update Request: {query}\n",
"\n",
" Provide updated Manim code that:\n",
" - Maintains the original structure\n",
" - Applies the requested changes\n",
" - Keeps the same Scene class\n",
" - Ensures code remains runnable\n",
" - Preserves existing functionality\n",
" \"\"\",\n",
" agent=updater_agent\n",
" )\n",
"\n",
" # Execute update\n",
" print(\"💻 Updating Manim code...\")\n",
"\n",
" update_system = PraisonAIAgents(\n",
" agents=[updater_agent],\n",
" tasks=[update_task],\n",
" verbose=True,\n",
" process=\"sequential\"\n",
" )\n",
"\n",
" updated_result = update_system.start()\n",
" updated_code = manim_tools.clean_manim_code(updated_result)\n",
"\n",
" # Validate updated code\n",
" print(\" Validating updated code...\")\n",
" code_summary = manim_tools.generate_code_summary(updated_code)\n",
"\n",
" print(f\"📝 Updated Code Summary:\")\n",
" print(f\" - Scene Name: {code_summary['scene_name']}\")\n",
" print(f\" - Syntax Valid: {code_summary['syntax_valid']}\")\n",
" print(f\" - Manim Imports: {code_summary['imports_ok']}\")\n",
" print(f\" - Scene Class: {code_summary['scene_ok']}\")\n",
"\n",
" return {\n",
" \"manim_code\": updated_code,\n",
" \"code_summary\": code_summary,\n",
" \"scene_name\": code_summary['scene_name']\n",
" }\n",
"\n",
"# Demo execution\n",
"print(\" AI Manim Code Generator Ready!\")\n",
"print(\"=\" * 60)\n",
"\n",
"# Example usage\n",
"demo_query = \"Create an animation showing a circle moving in a sine wave pattern\"\n",
"\n",
"print(\"🚀 Demo: Generating Manim code...\")\n",
"result = generate_manim_code(demo_query)\n",
"\n",
"print(\"\\n Generated Code:\")\n",
"print(\"=\" * 40)\n",
"print(result['manim_code'])\n",
"print(\"=\" * 40)\n",
"\n",
"print(f\"\\n✅ Code generation complete!\")\n",
"print(f\"🎬 Scene name: {result['scene_name']}\")\n",
"print(f\"📊 Code quality: {result['code_summary']['lines']} lines, {result['code_summary']['code_length']} characters\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,617 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "6UeqOiyEijl3",
"metadata": {
"id": "6UeqOiyEijl3"
},
"source": [
"**MistralTechAgent Lightweight Technical Assistant Using Mistral-7B-Instruct**"
]
},
{
"cell_type": "markdown",
"id": "fYuCNTAtiuD3",
"metadata": {
"id": "fYuCNTAtiuD3"
},
"source": [
"# 📄 Description:\n"
]
},
{
"cell_type": "markdown",
"id": "hmbRZinQivwt",
"metadata": {
"id": "hmbRZinQivwt"
},
"source": [
"MistralTechAgent is a simple and efficient AI assistant powered by the Mistral-7B-Instruct model. It is designed to provide accurate and easy-to-understand answers to technical questions. This agent uses a lightweight instruction-tuned model that runs smoothly on limited hardware while delivering high-quality responses. It also supports a customizable prompt format for structured queries."
]
},
{
"cell_type": "markdown",
"id": "8qf1K5ycjU1r",
"metadata": {
"id": "8qf1K5ycjU1r"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/MistralTechAgent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"id": "6oVNaoxbfsCP",
"metadata": {
"id": "6oVNaoxbfsCP"
},
"source": [
"# SETUP: Install Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "af21b3c7",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "af21b3c7",
"outputId": "3c900128-c9c1-4688-9f83-eaa2f9d2872e"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.0/67.0 MB\u001b[0m \u001b[31m13.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m363.4/363.4 MB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m78.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.6/24.6 MB\u001b[0m \u001b[31m70.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m883.7/883.7 kB\u001b[0m \u001b[31m57.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m664.8/664.8 MB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.5/211.5 MB\u001b[0m \u001b[31m5.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.3/56.3 MB\u001b[0m \u001b[31m13.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m127.9/127.9 MB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m207.5/207.5 MB\u001b[0m \u001b[31m6.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.1/21.1 MB\u001b[0m \u001b[31m88.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"!pip install -q transformers accelerate bitsandbytes"
]
},
{
"cell_type": "markdown",
"id": "xjXmh8sQf476",
"metadata": {
"id": "xjXmh8sQf476"
},
"source": [
"# SETUP: Hugging Face Token"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8405c936",
"metadata": {
"id": "8405c936"
},
"outputs": [],
"source": [
"import os\n",
"os.environ[\"HF_TOKEN\"] = \"Enter your hugging api key\"\n",
"os.environ[\"TRANSFORMERS_CACHE\"] = \"/content/hf_cache\" # Optional: Faster repeat runs\n"
]
},
{
"cell_type": "markdown",
"id": "PfKEoHt3haFV",
"metadata": {
"id": "PfKEoHt3haFV"
},
"source": [
"# YAML Prompt"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "iNfVRVN_hJOn",
"metadata": {
"id": "iNfVRVN_hJOn"
},
"outputs": [],
"source": [
"prompt_template = {\n",
" \"role\": \"system\",\n",
" \"content\": \"\"\"You are MistralTechAgent, an expert AI model assistant.\n",
"You provide clear, concise, and technically correct answers.\"\"\",\n",
" \"user_prompt\": \"{{ user_input }}\"\n",
"}\n"
]
},
{
"cell_type": "markdown",
"id": "LJAKEnSQf8gq",
"metadata": {
"id": "LJAKEnSQf8gq"
},
"source": [
"# Load the Model (Fallback Safe)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d6a29e6a",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 545,
"referenced_widgets": [
"d84722f34b2847f29f5d72690fc4dac6",
"cff68559d8ad46c190e7fe7f9403b9ee",
"36abbc31f97041b6a7786ccc3214e6ff",
"07d8084255bb465ab1eac565b9f8752f",
"9deaf08dabdf4679a2a44bb76e9a90f7",
"d07f025f4fe44db082fdf9ffc460ef63",
"56f8056ba6964bef922831ba1d4b1c1f",
"4f0419a3b0ab450aac64c1cd0ff12e5b",
"fe77c87b1caa40ae841bd65f499fc83a",
"83ba36ab3e5b455887f5d1fa5594ab78",
"005ec31a3aed4dc9b6083a59a9868bbd",
"15321d3071894e1c8948664d4e9066d2",
"4b43fc4bbce14f98bf8fc253fa3ed054",
"5d1662cd47b9477c84e77c29ce5ceeef",
"0be07a3e7a094dd09672bea04df7bc80",
"4b01774127fc4cf0b67baf13583ba8ed",
"ef2f3f069ade44fa8000cfd560b618a9",
"21b4e8cefdee4c5e8a2ba142d503fc87",
"d426d2480422465eb8b625ebb584feb1",
"8c4a7ec3cf8b462eaa5c9df357e216ee",
"b80e114ea4e6475297b61f9693d231c1",
"7c94da36524d402a81326a49a30cbbb5",
"f005c11730fd499bb8f81aaf56c653d9",
"c88dca8e5c164bd1a655adf7ced0e86a",
"104aa6d812164a76be60cd7d39dd8cde",
"f2729ef32b5d48bc8fb5a90f72d5ada2",
"38fa0e67450e40ecaf0a35feacb26186",
"0a74dde6fe1b45ef9c454dc23e4ccc9e",
"238917a3bcc24b5fa68fe2c7edc9234b",
"c6484ba3a50b4bec9086d8497b8c2692",
"41f62ed77f0449c99362997b36a866ed",
"ac54271d234f451eb793f7da28a8b802",
"d1574df5392c4bb2a2a6dece0cc30679",
"3a8da99cdb184f68b51d9706a867654b",
"0e32a6e4428f4ef3afa9a487c1524f89",
"b88cc5c73c734d15a4f8e073c8f3355a",
"0dde4efd517d422cbc70f9379cf831f6",
"4ffe478a8f654f008453fcb1e159b5c7",
"053d6a80586e41ba88299b55570922ac",
"f84040d89eb14f2ca2f3a88121c02182",
"7536d676b440429cb157919373401266",
"d2bada90caee4a37a6172ea6b046aec8",
"0c84482a056a4dd89f0369fc0ce33a89",
"648e7a00926845cd91344ce8cec2f8c7",
"ffa6acc3f9ba41dc8a3b57716cd9e040",
"a875f5aaea024290b2c347bdc9216b0c",
"a60321d756a54737ba37053a43890129",
"4aba7d0dd458437ab2d38d615fce9fc2",
"7b2205697a1b41cdbe363c56345b8d01",
"e2c0fd4a5436449cb3adca1f2204088e",
"0e3fa8394aa749498e2898049fad0536",
"fec704faaa5945b9917e730d2db8dd41",
"6a117742183c4b7d8011df4b8a1a4a76",
"60284b7ab8d845389419c7ac13d3cd3f",
"2f36f3edcdd14cdbafa6217758ce99f6",
"b9a0aeb8daf24fbd901a13cf728a7f31",
"d769287686274598b83c6d4f3adf86eb",
"6092a601fee7400187e85322d8c392d4",
"3e397abc9c704ddb8b7bc8e0dcbee6bc",
"ea3d99ef60e048fab9b9fb8c4c8c30b8",
"8bb3bacb95b447a8b3c58edf8f61e787",
"f586830e76dc42cd960b3f0b85103307",
"6ad155c4df5d4f30a481e5041e45edd2",
"31f8ebe87ae34e42ae0a78a6f9099191",
"87bd98a893ca4a8eae7c8e1a12449b52",
"3c3ccb3c9cbf4cacace8e24abb0a91ea",
"1edd5f953fd04bc7b8d20b5ffceabb3c",
"4df5649528874b209439c0c228dfabc0",
"fd76767d90c14fa596ee606ce4ed04da",
"259ecb69082644418e64abeb668ac24a",
"31d294d5e1ec4b229cf6f84f4d5ae1b0",
"24b5318baf2e4a45bda8fc93168b8a14",
"503c7ac86036420ba69af49ac8b3b9c6",
"13ad3a362cf341c1923abb4b3b1cd680",
"1eb86202e6aa4fe39e8de1f0af54b794",
"c24ffdfc0cd44a18b32803f93951029d",
"99190548afb445b9bcc552ec16971a8f",
"5b59bb8867b74cd28f342b5750232986",
"cd1b87d6fdd94f92ad015506b2ba2c5e",
"9a47c5378bce4a619409df36231ada16",
"a9cac4aa7fc243238c17c3fa76d3fdfb",
"d0da7d1ddbeb45deaeca52b1a8446ce1",
"4c30d02b0b7947c4ad60bb822dac264e",
"7a62762db5f84a6782663e36565f7cea",
"64c0dff073c24b15b9a211112ccc2d47",
"d6d5d90e878e4aa3a9d5c09d1ac8cd92",
"c9fef86db14d4e8e9a127c1dd1edc729",
"212f60982a33493497050c3d12c2363d",
"05010758eed94155887ee707b3648ca0",
"43f71ce03f874002afcabf2b64f946be",
"5282b4041f064cbc890dcdaa3bbd6104",
"07cb2d7c0c0f4bfd8ec7a3857a731390",
"3a8973062f654466925d40e35fe5e063",
"ded64c09b9b44838bc86e0e648c1c52b",
"0eb43a6eb7aa484a9e07309479978586",
"bbe209e71cad4c6d99a073bc900cf880",
"8cb9fb71cbd64904bbad6c2c5f7d1ffe",
"e8a986f524aa40339ab1f9fc5c92c0d4",
"02a5f1682b5e4afb875f3542b4b26c74",
"a7d0ecbe717f4427a99296ce2054e3fc",
"ed0039d420fa47518e2bc4626a549c86",
"0e14815b8e4d4fb2a39a97ca1e743a69",
"022675075da14683b86d4e56d29e291e",
"550b21f1e49e4cefa4a68d5b5e9bac01",
"0b598550b4234654a8454d5f9c70b1e4",
"880f0cf380fc4b499468db81b063a27e",
"758ce764b5294a5ab0c97e439a172cb2",
"410954f602984cd7bf39d2b12c5105c4",
"8eab2746f98e4d57b148969f9af8b17f",
"b622a9fb49fb43a6ae12004823b9b6e9",
"53a30b0dc2034bf0aa28c853b9c0e270",
"174544c42508419a9ea1dec2b5a48eec",
"aaa735b347074f02b9b174724beabfce",
"66fd00b5b01f46f1b362013d022ad437",
"734c206c4bbb4cc08da0a061a0671baa",
"5a185bcc5f814b1c829fa7a702a763a2",
"c1928ef5ac3841a8a97c69b11ea8a6da",
"2c318f2f01fc4271a890ec6b8238c9ad",
"2d7ff096493b425eafb671f6d23de282",
"493fd41d50bc4ed5aa33e58a50254edb",
"5016341a1d0d4e59ad263aa81f81d5fd"
]
},
"id": "d6a29e6a",
"outputId": "9417ca92-9348-427d-e8e1-aabf3e716dbd"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.11/dist-packages/transformers/utils/hub.py:111: FutureWarning: Using `TRANSFORMERS_CACHE` is deprecated and will be removed in v5 of Transformers. Use `HF_HOME` instead.\n",
" warnings.warn(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"🔄 Loading model: mistralai/Mistral-7B-Instruct-v0.1\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.11/dist-packages/transformers/models/auto/tokenization_auto.py:902: FutureWarning: The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.\n",
" warnings.warn(\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d84722f34b2847f29f5d72690fc4dac6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/2.10k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "15321d3071894e1c8948664d4e9066d2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.model: 0%| | 0.00/493k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f005c11730fd499bb8f81aaf56c653d9",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/1.80M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3a8da99cdb184f68b51d9706a867654b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"special_tokens_map.json: 0%| | 0.00/414 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.11/dist-packages/transformers/models/auto/auto_factory.py:476: FutureWarning: The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.\n",
" warnings.warn(\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ffa6acc3f9ba41dc8a3b57716cd9e040",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"config.json: 0%| | 0.00/571 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b9a0aeb8daf24fbd901a13cf728a7f31",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model.safetensors.index.json: 0%| | 0.00/25.1k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1edd5f953fd04bc7b8d20b5ffceabb3c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Fetching 2 files: 0%| | 0/2 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5b59bb8867b74cd28f342b5750232986",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00002-of-00002.safetensors: 0%| | 0.00/4.54G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "05010758eed94155887ee707b3648ca0",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00001-of-00002.safetensors: 0%| | 0.00/9.94G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a7d0ecbe717f4427a99296ce2054e3fc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Loading checkpoint shards: 0%| | 0/2 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "53a30b0dc2034bf0aa28c853b9c0e270",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"generation_config.json: 0%| | 0.00/116 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:accelerate.big_modeling:Some parameters are on the meta device because they were offloaded to the cpu.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Model loaded successfully!\n"
]
}
],
"source": [
"from transformers import AutoTokenizer, AutoModelForCausalLM\n",
"import torch\n",
"\n",
"model_name = \"mistralai/Mistral-7B-Instruct-v0.1\"\n",
"\n",
"try:\n",
" print(f\"🔄 Loading model: {model_name}\")\n",
" tokenizer = AutoTokenizer.from_pretrained(\n",
" model_name, use_auth_token=os.environ[\"HF_TOKEN\"], trust_remote_code=True\n",
" )\n",
" model = AutoModelForCausalLM.from_pretrained(\n",
" model_name,\n",
" use_auth_token=os.environ[\"HF_TOKEN\"],\n",
" trust_remote_code=True,\n",
" device_map=\"auto\",\n",
" torch_dtype=torch.float16\n",
" )\n",
" model.eval()\n",
" print(\"✅ Model loaded successfully!\")\n",
"\n",
"except Exception as e:\n",
" print(f\"❌ Failed to load {model_name}\\nError: {e}\")\n",
" model_name = \"distilgpt2\"\n",
" tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
" model = AutoModelForCausalLM.from_pretrained(model_name)\n",
" model.eval()\n"
]
},
{
"cell_type": "markdown",
"id": "GWj9n1cVg5xj",
"metadata": {
"id": "GWj9n1cVg5xj"
},
"source": [
"# Define the MistralTechAgent"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "83492929",
"metadata": {
"id": "83492929"
},
"outputs": [],
"source": [
"\n",
"class MistralTechAgent:\n",
" def __init__(self, model, tokenizer):\n",
" self.model = model\n",
" self.tokenizer = tokenizer\n",
"\n",
" def chat(self, prompt: str, max_new_tokens=256) -> str:\n",
" inputs = self.tokenizer(prompt, return_tensors=\"pt\").to(self.model.device)\n",
" with torch.no_grad():\n",
" outputs = self.model.generate(\n",
" **inputs,\n",
" max_new_tokens=max_new_tokens,\n",
" do_sample=False, # DETERMINISTIC output\n",
" temperature=1.0,\n",
" top_p=1.0,\n",
" pad_token_id=self.tokenizer.eos_token_id\n",
" )\n",
" full_output = self.tokenizer.decode(outputs[0], skip_special_tokens=True)\n",
" return full_output[len(prompt):].strip()\n"
]
},
{
"cell_type": "markdown",
"id": "QZC6QzA4hB8m",
"metadata": {
"id": "QZC6QzA4hB8m"
},
"source": [
"# Test the Agent"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "83a3388e",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "83a3388e",
"outputId": "ebfc13f5-bae9-4647-fc7c-78c386afa03c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== Agent Response ===\n",
"A language model is a type of artificial intelligence (AI) model that is designed to understand, interpret, and generate human language. It is a machine learning model that is trained on large amounts of text data to learn the patterns and structures of language, including grammar, vocabulary, and syntax.\n",
"\n",
"Language models can be used for a variety of tasks, such as language translation, sentiment analysis, text summarization, and speech recognition. They are often used in natural language processing (NLP) applications, where they help machines to understand and interact with humans in a more natural and intuitive way.\n",
"\n",
"There are several types of language models, including statistical language models, neural language models, and transformer-based language models. These models differ in their architecture, training methods, and performance on different NLP tasks.\n"
]
}
],
"source": [
"\n",
"agent = MistralTechAgent(model, tokenizer)\n",
"\n",
"prompt = \"You are an AI agent helping with technical queries. Explain what a language model is.\"\n",
"response = agent.chat(prompt)\n",
"\n",
"print(\"=== Agent Response ===\")\n",
"print(response)\n"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,499 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "-j-8RaEinSgs"
},
"source": [
"# 🧠 Search Agent (PraisonAI Edition)\n",
"\n",
"A minimal example of using PraisonAI's Agent with a custom internet search tool in Python, ready for Google Colab."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tztyseN5pqeD"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/MemoryPal_Search_Agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ls8fyQsTnXqR"
},
"source": [
"# Install Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "HihjK38YncNS"
},
"outputs": [],
"source": [
"!pip install praisonaiagents duckduckgo-search"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "drGND5XAnpzd"
},
"source": [
"# Set API Key"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "nkpbgwJwnrn_"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# Enter your OpenAI API key here\n",
"os.environ['OPENAI_API_KEY'] = 'Enter your api key' # <-- Replace with your OpenAI API key"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "19dqWac7nzZf"
},
"source": [
"# Tool Definition"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "_M7EI96dn0qi"
},
"outputs": [],
"source": [
"from duckduckgo_search import DDGS\n",
"\n",
"def internet_search_tool(query: str):\n",
" results = []\n",
" ddgs = DDGS()\n",
" for result in ddgs.text(keywords=query, max_results=5):\n",
" results.append({\n",
" 'title': result.get('title', ''),\n",
" 'url': result.get('href', ''),\n",
" 'snippet': result.get('body', '')\n",
" })\n",
" return results"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SYPI8zhen4nd"
},
"source": [
"# YAML Agent Config"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Yag6EqYOn5h-",
"outputId": "03f37769-3f05-479d-8d5a-a201bf403c73"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'framework': 'praisonai', 'topic': 'internet search demo', 'roles': {'searcher': {'backstory': 'Expert in internet search.', 'goal': 'Find information online.', 'role': 'Searcher', 'tools': ['internet_search_tool'], 'tasks': {'search_task': {'description': \"Search for 'AI job trends in 2025'.\", 'expected_output': 'List of search results.'}}}}}\n"
]
}
],
"source": [
"import yaml\n",
"\n",
"yaml_config = \"\"\"\n",
"framework: praisonai\n",
"topic: internet search demo\n",
"roles:\n",
" searcher:\n",
" backstory: Expert in internet search.\n",
" goal: Find information online.\n",
" role: Searcher\n",
" tools:\n",
" - internet_search_tool\n",
" tasks:\n",
" search_task:\n",
" description: Search for 'AI job trends in 2025'.\n",
" expected_output: List of search results.\n",
"\"\"\"\n",
"\n",
"config = yaml.safe_load(yaml_config)\n",
"print(config)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KbYjwEkvoUqV"
},
"source": [
"# Prompt Example"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7hslONZgoXph"
},
"source": [
"Example prompt to use with the agent: \n",
"`Search about AI job trends in 2025`"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KvzzBm-7oZ9c"
},
"source": [
"# Main: Run the Agent"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"4a9625800fe94aabb88e2ff78bce5a1d",
"930e61499fac44f183c51ca93e3aad88",
"bfb62f3af49c40f7934a7f245cd57d6d",
"50486df133bf4e1582880c2cd6f2ca54"
]
},
"id": "TxyynCXCobA0",
"outputId": "148a9670-ebd7-4d23-e248-1e5cf13aeb8e"
},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Assistant</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #86a789; text-decoration-color: #86a789; font-weight: bold\">Tools:</span> <span style=\"color: #b4d4ff; text-decoration-color: #b4d4ff; font-style: italic\">internet_search_tool</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mAssistant\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;134;167;137mTools:\u001b[0m \u001b[3;38;2;180;212;255minternet_search_tool\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "4a9625800fe94aabb88e2ff78bce5a1d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008000; text-decoration-color: #008000\">╭──────────────────────────────────────────────── Tool Call ────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">Agent Agent is calling function 'internet_search_tool' with arguments: {'query': 'AI job trends in 2025'}</span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[32m╭─\u001b[0m\u001b[32m───────────────────────────────────────────────\u001b[0m\u001b[32m Tool Call \u001b[0m\u001b[32m───────────────────────────────────────────────\u001b[0m\u001b[32m─╮\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mAgent Agent is calling function 'internet_search_tool' with arguments: {'query': 'AI job trends in 2025'}\u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008000; text-decoration-color: #008000\">╭─────────────────────────────────────────────────── Tool Call ───────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">Function 'internet_search_tool' returned: [{\"title\": \"AI Job Trends 2025: Top AI Jobs, Roles, and Hiring Data </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">Insights\", \"url\": \"https://blog.getaura.ai/ai-job-trends-2025\", \"snippet\": \"Explore the latest AI job trends </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">for 2025. Learn about top industries hiring, in-demand skills, and emerging roles shaping the future of AI </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">hiring.\"}, {\"title\": \" The Fearless Future: 2025 Global AI Jobs Barometer - PwC\", \"url\": </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"https://www.pwc.com/gx/en/issues/artificial-intelligence/job-barometer/aijb-2025-united-states-analysis.pdf\", </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"snippet\": \"Global Insights The AI Jobs Barometer reveals AI's global impact on jobs, wages, skills, and </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">productivity by examining close to a billion job ads from six continents.\"}, {\"title\": \"10 Hottest AI Jobs Of </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2025 With Six-Figure Salaries - Forbes\", \"url\": </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"https://www.forbes.com/sites/bryanrobinson/2025/01/17/10-hottest-ai-jobs-of-2025-paying-six-figure-salaries/\",</span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"snippet\": \"Explore the top AI roles of 2025, from Machine Learning Engineers to NLP Specialists, offering </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">six-figure salaries and high demand in the evolving tech landscape.\"}, {\"title\": \"AI Job Market 2025: Impact on</span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">Employment &amp; Future Workforce Trends\", \"url\": </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"https://www.cognitivetoday.com/2025/03/ai-job-market-impact-on-employment-future-workforce-trends/\", </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"snippet\": \"Discover how AI will reshape jobs in 2025. Learn about AI-driven displacement, new roles, and </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">must-have skills to thrive in the evolving workforce. AI Job Market 2025.\"}, {\"title\": \"AI Job Market: Trends, </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">Opportunities, and Key Skills for 2025\", \"url\": </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">\"https://www.analyticsinsight.net/artificial-intelligence/ai-job-market-trends-opportunities-and-key-skills-for</span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">-2025\", \"snippet\": \"As artificial intelligence (AI) continues to reshape industries, the job market will see a </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">significant transformation in 2025. With new opportunities emerging and certain skills becoming essential, AI </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">adoption will also rise. From automation and machine learning to AI-driven healthcare and edge computing, </span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">understanding the evolving trends and required skill sets will be crucial for anyone ...\"}]</span> <span style=\"color: #008000; text-decoration-color: #008000\">│</span>\n",
"<span style=\"color: #008000; text-decoration-color: #008000\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[32m╭─\u001b[0m\u001b[32m──────────────────────────────────────────────────\u001b[0m\u001b[32m Tool Call \u001b[0m\u001b[32m──────────────────────────────────────────────────\u001b[0m\u001b[32m─╮\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mFunction 'internet_search_tool' returned: [{\"title\": \"AI Job Trends 2025: Top AI Jobs, Roles, and Hiring Data \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mInsights\", \"url\": \"https://blog.getaura.ai/ai-job-trends-2025\", \"snippet\": \"Explore the latest AI job trends \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mfor 2025. Learn about top industries hiring, in-demand skills, and emerging roles shaping the future of AI \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mhiring.\"}, {\"title\": \" The Fearless Future: 2025 Global AI Jobs Barometer - PwC\", \"url\": \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"https://www.pwc.com/gx/en/issues/artificial-intelligence/job-barometer/aijb-2025-united-states-analysis.pdf\", \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"snippet\": \"Global Insights The AI Jobs Barometer reveals AI's global impact on jobs, wages, skills, and \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mproductivity by examining close to a billion job ads from six continents.\"}, {\"title\": \"10 Hottest AI Jobs Of \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m2025 With Six-Figure Salaries - Forbes\", \"url\": \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"https://www.forbes.com/sites/bryanrobinson/2025/01/17/10-hottest-ai-jobs-of-2025-paying-six-figure-salaries/\",\u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"snippet\": \"Explore the top AI roles of 2025, from Machine Learning Engineers to NLP Specialists, offering \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36msix-figure salaries and high demand in the evolving tech landscape.\"}, {\"title\": \"AI Job Market 2025: Impact on\u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mEmployment & Future Workforce Trends\", \"url\": \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"https://www.cognitivetoday.com/2025/03/ai-job-market-impact-on-employment-future-workforce-trends/\", \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"snippet\": \"Discover how AI will reshape jobs in 2025. Learn about AI-driven displacement, new roles, and \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mmust-have skills to thrive in the evolving workforce. AI Job Market 2025.\"}, {\"title\": \"AI Job Market: Trends, \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36mOpportunities, and Key Skills for 2025\", \"url\": \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m\"https://www.analyticsinsight.net/artificial-intelligence/ai-job-market-trends-opportunities-and-key-skills-for\u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36m-2025\", \"snippet\": \"As artificial intelligence (AI) continues to reshape industries, the job market will see a \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36msignificant transformation in 2025. With new opportunities emerging and certain skills becoming essential, AI \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36madoption will also rise. From automation and machine learning to AI-driven healthcare and edge computing, \u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m│\u001b[0m \u001b[1;36munderstanding the evolving trends and required skill sets will be crucial for anyone ...\"}]\u001b[0m \u001b[32m│\u001b[0m\n",
"\u001b[32m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "bfb62f3af49c40f7934a7f245cd57d6d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 14.7s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 14.7s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> AI job trends in 2025 <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m AI job trends in 2025 \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Here are some insights into AI job trends for 2025: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span><span style=\"font-weight: bold\">Top AI Jobs and Roles</span>: The AI job market in 2025 is expected to feature roles such as Machine Learning <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>Engineers, NLP Specialists, and other positions offering six-figure salaries. These roles are in high demand <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>as the tech landscape evolves. <a href=\"https://www.forbes.com/sites/bryanrobinson/2025/01/17/10-hottest-ai-jobs-of-2025-paying-six-figure-salaries/\" target=\"_blank\"><span style=\"color: #000080; text-decoration-color: #000080; text-decoration: underline\">Read more on Forbes</span></a>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span><span style=\"font-weight: bold\">Industries and Skills</span>: AI is reshaping industries, with new opportunities emerging and certain skills <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>becoming essential. Key areas include automation, machine learning, AI-driven healthcare, and edge <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>computing. <a href=\"https://www.analyticsinsight.net/artificial-intelligence/ai-job-market-trends-opportunities-and-key-skills-for-2025\" target=\"_blank\"><span style=\"color: #000080; text-decoration-color: #000080; text-decoration: underline\">Explore more on Analytics Insight</span></a>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 3 </span><span style=\"font-weight: bold\">Global Impact</span>: The AI Jobs Barometer by PwC examines AI's global impact on jobs, wages, skills, and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>productivity, analyzing job ads from six continents. <a href=\"https://www.pwc.com/gx/en/issues/artificial-intelligence/job-barometer/aijb-2025-united-states-analysis.pdf\" target=\"_blank\"><span style=\"color: #000080; text-decoration-color: #000080; text-decoration: underline\">Check the PwC report</span></a>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 4 </span><span style=\"font-weight: bold\">Future Workforce Trends</span>: AI will reshape jobs, leading to AI-driven displacement and the creation of new <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>roles. Understanding these trends and acquiring must-have skills will be crucial for thriving in the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>evolving workforce. <a href=\"https://www.cognitivetoday.com/2025/03/ai-job-market-impact-on-employment-future-workforce-trends/\" target=\"_blank\"><span style=\"color: #000080; text-decoration-color: #000080; text-decoration: underline\">Learn more on Cognitive Today</span></a>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 5 </span><span style=\"font-weight: bold\">Hiring Data Insights</span>: Insights into the latest AI job trends, including top industries hiring and emerging <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>roles, can be found in various reports and analyses. <a href=\"https://blog.getaura.ai/ai-job-trends-2025\" target=\"_blank\"><span style=\"color: #000080; text-decoration-color: #000080; text-decoration: underline\">Read more on GetAura</span></a>. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> These resources provide a comprehensive overview of the anticipated changes and opportunities in the AI job <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> market by 2025. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m Here are some insights into AI job trends for 2025: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0m\u001b[1mTop AI Jobs and Roles\u001b[0m: The AI job market in 2025 is expected to feature roles such as Machine Learning \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mEngineers, NLP Specialists, and other positions offering six-figure salaries. These roles are in high demand \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mas the tech landscape evolves. \u001b]8;id=1080;https://www.forbes.com/sites/bryanrobinson/2025/01/17/10-hottest-ai-jobs-of-2025-paying-six-figure-salaries/\u001b\\\u001b[4;34mRead more on Forbes\u001b[0m\u001b]8;;\u001b\\. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0m\u001b[1mIndustries and Skills\u001b[0m: AI is reshaping industries, with new opportunities emerging and certain skills \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mbecoming essential. Key areas include automation, machine learning, AI-driven healthcare, and edge \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mcomputing. \u001b]8;id=337875;https://www.analyticsinsight.net/artificial-intelligence/ai-job-market-trends-opportunities-and-key-skills-for-2025\u001b\\\u001b[4;34mExplore more on Analytics Insight\u001b[0m\u001b]8;;\u001b\\. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 3 \u001b[0m\u001b[1mGlobal Impact\u001b[0m: The AI Jobs Barometer by PwC examines AI's global impact on jobs, wages, skills, and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mproductivity, analyzing job ads from six continents. \u001b]8;id=455296;https://www.pwc.com/gx/en/issues/artificial-intelligence/job-barometer/aijb-2025-united-states-analysis.pdf\u001b\\\u001b[4;34mCheck the PwC report\u001b[0m\u001b]8;;\u001b\\. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 4 \u001b[0m\u001b[1mFuture Workforce Trends\u001b[0m: AI will reshape jobs, leading to AI-driven displacement and the creation of new \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mroles. Understanding these trends and acquiring must-have skills will be crucial for thriving in the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mevolving workforce. \u001b]8;id=772466;https://www.cognitivetoday.com/2025/03/ai-job-market-impact-on-employment-future-workforce-trends/\u001b\\\u001b[4;34mLearn more on Cognitive Today\u001b[0m\u001b]8;;\u001b\\. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 5 \u001b[0m\u001b[1mHiring Data Insights\u001b[0m: Insights into the latest AI job trends, including top industries hiring and emerging \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mroles, can be found in various reports and analyses. \u001b]8;id=262366;https://blog.getaura.ai/ai-job-trends-2025\u001b\\\u001b[4;34mRead more on GetAura\u001b[0m\u001b]8;;\u001b\\. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m These resources provide a comprehensive overview of the anticipated changes and opportunities in the AI job \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m market by 2025. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response:\n",
"Here are some insights into AI job trends for 2025:\n",
"\n",
"1. **Top AI Jobs and Roles**: The AI job market in 2025 is expected to feature roles such as Machine Learning Engineers, NLP Specialists, and other positions offering six-figure salaries. These roles are in high demand as the tech landscape evolves. [Read more on Forbes](https://www.forbes.com/sites/bryanrobinson/2025/01/17/10-hottest-ai-jobs-of-2025-paying-six-figure-salaries/).\n",
"\n",
"2. **Industries and Skills**: AI is reshaping industries, with new opportunities emerging and certain skills becoming essential. Key areas include automation, machine learning, AI-driven healthcare, and edge computing. [Explore more on Analytics Insight](https://www.analyticsinsight.net/artificial-intelligence/ai-job-market-trends-opportunities-and-key-skills-for-2025).\n",
"\n",
"3. **Global Impact**: The AI Jobs Barometer by PwC examines AI's global impact on jobs, wages, skills, and productivity, analyzing job ads from six continents. [Check the PwC report](https://www.pwc.com/gx/en/issues/artificial-intelligence/job-barometer/aijb-2025-united-states-analysis.pdf).\n",
"\n",
"4. **Future Workforce Trends**: AI will reshape jobs, leading to AI-driven displacement and the creation of new roles. Understanding these trends and acquiring must-have skills will be crucial for thriving in the evolving workforce. [Learn more on Cognitive Today](https://www.cognitivetoday.com/2025/03/ai-job-market-impact-on-employment-future-workforce-trends/).\n",
"\n",
"5. **Hiring Data Insights**: Insights into the latest AI job trends, including top industries hiring and emerging roles, can be found in various reports and analyses. [Read more on GetAura](https://blog.getaura.ai/ai-job-trends-2025).\n",
"\n",
"These resources provide a comprehensive overview of the anticipated changes and opportunities in the AI job market by 2025.\n"
]
}
],
"source": [
"from praisonaiagents import Agent\n",
"\n",
"agent = Agent(\n",
" instructions=\"You are an AI assistant with internet search capabilities.\",\n",
" tools=[internet_search_tool]\n",
")\n",
"\n",
"# Main: Ask a question\n",
"query = 'AI job trends in 2025' # You can change this prompt\n",
"response = agent.start(query)\n",
"print('Response:')\n",
"print(response)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,355 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "_T4g3t5sLoag"
},
"source": [
"# ZeroScript: AI-Powered Browser Test Automation using PraisonAI Agent & OpenAI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "O4PKfpalLsmn"
},
"source": [
"# Description"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CEG1pfumLysm"
},
"source": [
"AI-powered browser testing using PraisonAI Agent and OpenAI. Executes YAML-defined test cases, captures screenshots, logs interactions, and generates JSON reports. Ideal for intelligent, automated UI testing.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lbgxOG4gL1Wf"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/ZeroScript_AI_TestExecutor.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WCJqMUzXIndh"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"id": "9AQhJ59cJPmR"
},
"outputs": [],
"source": [
"!pip install --quiet praisonaiagents browser-use python-dotenv pyyaml openai\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QD-dF-6_It1z"
},
"source": [
"# Environment Setup"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "QkRQDli4JhCV",
"outputId": "4b8957ed-a37a-4b11-8585-3537a0437d40"
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import os\n",
"from dotenv import load_dotenv\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your key\" # replace with actual key\n",
"load_dotenv()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ELuogWnrIw3o"
},
"source": [
"# Create my_secrets.py"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"id": "sG6tO_v0Jm5N"
},
"outputs": [],
"source": [
"with open(\"my_secrets.py\", \"w\") as f:\n",
" f.write('''sensitive_data = {\n",
" \"username\": \"standard_user\",\n",
" \"password\": \"secret_sauce\"\n",
"}''')\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rDB_viedIzRR"
},
"source": [
"# Create views.py"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"id": "CtwcybdbJoV8"
},
"outputs": [],
"source": [
"with open(\"views.py\", \"w\") as f:\n",
" f.write('''\n",
"from pydantic import BaseModel\n",
"\n",
"class TestResult(BaseModel):\n",
" status: str\n",
" message: str = \"\"\n",
"''')\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YTRmBpTiI1kd"
},
"source": [
"# Create agent.py"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"id": "zdJJGt6TJpvr"
},
"outputs": [],
"source": [
"with open(\"agent.py\", \"w\") as f:\n",
" f.write('''\n",
"import os\n",
"from praisonaiagents import Agent\n",
"from browser_use import Browser, BrowserConfig, Controller\n",
"from browser_use.browser.context import BrowserContext, BrowserContextConfig\n",
"from openai import OpenAI\n",
"from views import TestResult\n",
"from my_secrets import sensitive_data\n",
"\n",
"# Browser setup\n",
"browser = Browser(config=BrowserConfig(headless=True))\n",
"context_cfg = BrowserContextConfig(save_recording_path=\"data/recordings\")\n",
"controller = Controller(output_model=TestResult)\n",
"\n",
"async def browser_use(task: str):\n",
" context = BrowserContext(browser=browser, config=context_cfg)\n",
" agent = Agent(\n",
" task=task,\n",
" llm=OpenAI(api_key=os.getenv(\"OPENAI_API_KEY\"), model=\"gpt-4\"),\n",
" browser_context=context,\n",
" sensitive_data=sensitive_data,\n",
" controller=controller,\n",
" save_conversation_path=\"data/conversations/convo\",\n",
" extend_system_message=(\n",
" \"You are a professional software tester. Execute browser test steps precisely.\"\n",
" )\n",
" )\n",
" response = await agent.run()\n",
" await context.close()\n",
" return response\n",
"''')\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-LZtQIE3I4-_"
},
"source": [
"# Create Sample Test YAML"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "l1OdXYI-JreK",
"outputId": "62323fcd-c74f-498f-defc-2c170fa8983e"
},
"outputs": [
{
"data": {
"text/plain": [
"350"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from pathlib import Path\n",
"tests_dir = Path(\"tests\")\n",
"tests_dir.mkdir(exist_ok=True)\n",
"yaml_content = \"\"\"\n",
"hooks:\n",
" beforeEach: |\n",
" Navigate to https://www.saucedemo.com\n",
" afterEach: |\n",
" Take screenshot\n",
"\n",
"tests:\n",
" - id: \"login_test_001\"\n",
" name: \"Valid Login Test\"\n",
" instructions: |\n",
" 1. Enter standard_user in username field\n",
" 2. Enter secret_sauce in password field\n",
" 3. Click login button\n",
" 4. Verify page contains text \"Products\"\n",
"\"\"\"\n",
"(Path(\"tests/login_test.yml\")).write_text(yaml_content)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sUjy-7OdI7p_"
},
"source": [
"# Run Tests"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Agkiwh7xJtY3",
"outputId": "759aa77c-fd65-49b8-b239-550588059478"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Exception ignored in: <function BrowserSession.__del__ at 0x7e2f540fb100>\n",
"Traceback (most recent call last):\n",
" File \"/usr/local/lib/python3.11/dist-packages/browser_use/browser/session.py\", line 497, in __del__\n",
" status = f'🪓 killing pid={self.browser_pid}...' if (self.browser_pid and owns_browser) else '☠️'\n",
" ^^^^^^^^^^^^^^^^\n",
" File \"/usr/local/lib/python3.11/dist-packages/pydantic/main.py\", line 991, in __getattr__\n",
" raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')\n",
"AttributeError: 'BrowserSession' object has no attribute 'browser_pid'\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Report saved to data/reports/report_20250630_092319.json\n"
]
}
],
"source": [
"import asyncio, yaml, json, base64, shutil\n",
"from agent import browser_use, browser\n",
"from pathlib import Path\n",
"from datetime import datetime\n",
"\n",
"# Clean or create data dirs\n",
"for sub in [\"recordings\", \"conversations\", \"screenshots\", \"reports\"]:\n",
" d = Path(\"data\") / sub\n",
" if d.exists(): shutil.rmtree(d)\n",
" d.mkdir(parents=True, exist_ok=True)\n",
"\n",
"async def execute_test_file(path):\n",
" cfg = yaml.safe_load(Path(path).read_text())\n",
" hooks, results = cfg.get(\"hooks\", {}), []\n",
" for t in cfg[\"tests\"]:\n",
" task = f\"{hooks.get('beforeEach','')}\\n{t['instructions']}\\n{hooks.get('afterEach','')}\"\n",
" res = {\"id\": t[\"id\"], \"name\": t[\"name\"]}\n",
" try:\n",
" r = await browser_use(task)\n",
" imgs = r.screenshots()\n",
" if imgs:\n",
" out = Path(\"data/screenshots\") / f\"{t['id']}.png\"\n",
" out.write_bytes(base64.b64decode(imgs[-1]))\n",
" result_obj = r.final_result() if hasattr(r, \"final_result\") else str(r)\n",
" res[\"result\"] = result_obj.dict() if hasattr(result_obj, \"dict\") else str(result_obj)\n",
" except Exception as e:\n",
" res[\"error\"] = str(e)\n",
" results.append(res)\n",
" return results\n",
"\n",
"async def main():\n",
" all_results = []\n",
" for file in Path(\"tests\").glob(\"*.yml\"):\n",
" all_results.extend(await execute_test_file(str(file)))\n",
" report = Path(\"data/reports\") / f\"report_{datetime.now():%Y%m%d_%H%M%S}.json\"\n",
" report.write_text(json.dumps(all_results, indent=2))\n",
" await browser.close()\n",
" print(f\"✅ Report saved to {report}\")\n",
"\n",
"await main()\n"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,922 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "uJ93P7ksa2Nn"
},
"source": [
"# Local RAG Document Agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vxe5gDW0a4pC"
},
"source": [
"* A Retrieval-Augmented Generation agent that uses local models and vector databases for document-based question answering.\n",
"* The agent can process PDF documents, extract knowledge, and answer questions using local LLM inference without external API calls.\n",
"* Features include document upload, vector embedding, similarity search, and intelligent Q&A with source attribution and context awareness."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "K3HdvvEid5wP"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/local_rag_document_qa_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xaXT3inobISk"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VBIlMa0vbBWm"
},
"outputs": [],
"source": [
"!pip install praisonai streamlit qdrant-client ollama pypdf PyPDF2 chromadb sentence-transformers"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FttFP60zb30i"
},
"source": [
"# Setup Key"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "smr-FEPhb3Yx",
"outputId": "526779e1-94ed-46f9-9288-6d9ee5b25a19"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ API key configured!\n",
"✅ Using local Ollama models for RAG operations\n"
]
}
],
"source": [
"# Setup Key\n",
"import os\n",
"openai_key = \"sk-..\"\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = openai_key\n",
"\n",
"# Ollama setup (for local models)\n",
"# Make sure Ollama is installed and running locally\n",
"# Available models: llama3.2, llama3.1, mistral, codellama, etc.\n",
"\n",
"print(\"✅ API key configured!\")\n",
"print(\"✅ Using local Ollama models for RAG operations\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4hEC_bn1cGOH"
},
"source": [
"# Tools"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "bXEhVTwocH1J"
},
"outputs": [],
"source": [
"# Custom Document Processing Tool\n",
"import PyPDF2\n",
"import tempfile\n",
"import os\n",
"from typing import Dict, Any, List\n",
"import pandas as pd\n",
"\n",
"class DocumentProcessingTool:\n",
" def __init__(self):\n",
" self.supported_formats = ['.pdf', '.txt', '.md', '.csv']\n",
"\n",
" def process_document(self, file_path: str) -> Dict[str, Any]:\n",
" \"\"\"Process different document formats and extract text\"\"\"\n",
" try:\n",
" file_ext = os.path.splitext(file_path)[1].lower()\n",
"\n",
" if file_ext == '.pdf':\n",
" return self._process_pdf(file_path)\n",
" elif file_ext == '.txt':\n",
" return self._process_txt(file_path)\n",
" elif file_ext == '.md':\n",
" return self._process_md(file_path)\n",
" elif file_ext == '.csv':\n",
" return self._process_csv(file_path)\n",
" else:\n",
" return {\"error\": f\"Unsupported file format: {file_ext}\"}\n",
" except Exception as e:\n",
" return {\"error\": f\"Error processing document: {str(e)}\"}\n",
"\n",
" def _process_pdf(self, file_path: str) -> Dict[str, Any]:\n",
" \"\"\"Process PDF files\"\"\"\n",
" try:\n",
" with open(file_path, 'rb') as file:\n",
" pdf_reader = PyPDF2.PdfReader(file)\n",
" text = \"\"\n",
" for page in pdf_reader.pages:\n",
" text += page.extract_text() + \"\\n\"\n",
"\n",
" return {\n",
" \"text\": text,\n",
" \"pages\": len(pdf_reader.pages),\n",
" \"format\": \"pdf\",\n",
" \"file_path\": file_path\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"PDF processing error: {str(e)}\"}\n",
"\n",
" def _process_txt(self, file_path: str) -> Dict[str, Any]:\n",
" \"\"\"Process text files\"\"\"\n",
" try:\n",
" with open(file_path, 'r', encoding='utf-8') as file:\n",
" text = file.read()\n",
"\n",
" return {\n",
" \"text\": text,\n",
" \"format\": \"txt\",\n",
" \"file_path\": file_path\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Text processing error: {str(e)}\"}\n",
"\n",
" def _process_md(self, file_path: str) -> Dict[str, Any]:\n",
" \"\"\"Process markdown files\"\"\"\n",
" try:\n",
" with open(file_path, 'r', encoding='utf-8') as file:\n",
" text = file.read()\n",
"\n",
" return {\n",
" \"text\": text,\n",
" \"format\": \"md\",\n",
" \"file_path\": file_path\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Markdown processing error: {str(e)}\"}\n",
"\n",
" def _process_csv(self, file_path: str) -> Dict[str, Any]:\n",
" \"\"\"Process CSV files\"\"\"\n",
" try:\n",
" df = pd.read_csv(file_path)\n",
" text = df.to_string(index=False)\n",
"\n",
" return {\n",
" \"text\": text,\n",
" \"format\": \"csv\",\n",
" \"rows\": len(df),\n",
" \"columns\": len(df.columns),\n",
" \"file_path\": file_path\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"CSV processing error: {str(e)}\"}\n",
"\n",
"# Custom Vector Database Tool (Fixed for new ChromaDB)\n",
"import chromadb\n",
"import numpy as np\n",
"\n",
"class VectorDatabaseTool:\n",
" def __init__(self, collection_name: str = \"document_qa\"):\n",
" self.collection_name = collection_name\n",
" # Use new ChromaDB client configuration\n",
" self.client = chromadb.PersistentClient(path=\"./chroma_db\")\n",
" self.collection = self.client.get_or_create_collection(name=collection_name)\n",
"\n",
" def add_documents(self, documents: List[str], metadatas: List[Dict] = None, ids: List[str] = None) -> Dict[str, Any]:\n",
" \"\"\"Add documents to the vector database\"\"\"\n",
" try:\n",
" if ids is None:\n",
" ids = [f\"doc_{i}\" for i in range(len(documents))]\n",
" if metadatas is None:\n",
" metadatas = [{\"source\": f\"document_{i}\"} for i in range(len(documents))]\n",
"\n",
" self.collection.add(\n",
" documents=documents,\n",
" metadatas=metadatas,\n",
" ids=ids\n",
" )\n",
"\n",
" return {\n",
" \"success\": True,\n",
" \"documents_added\": len(documents),\n",
" \"collection_name\": self.collection_name\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error adding documents: {str(e)}\"}\n",
"\n",
" def search_documents(self, query: str, n_results: int = 5) -> Dict[str, Any]:\n",
" \"\"\"Search for relevant documents\"\"\"\n",
" try:\n",
" results = self.collection.query(\n",
" query_texts=[query],\n",
" n_results=n_results\n",
" )\n",
"\n",
" return {\n",
" \"success\": True,\n",
" \"query\": query,\n",
" \"results\": results,\n",
" \"num_results\": len(results['documents'][0]) if results['documents'] else 0\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error searching documents: {str(e)}\"}\n",
"\n",
" def get_collection_info(self) -> Dict[str, Any]:\n",
" \"\"\"Get information about the collection\"\"\"\n",
" try:\n",
" count = self.collection.count()\n",
" return {\n",
" \"success\": True,\n",
" \"collection_name\": self.collection_name,\n",
" \"document_count\": count\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error getting collection info: {str(e)}\"}\n",
"\n",
"# Custom Text Chunking Tool\n",
"import re\n",
"from typing import List\n",
"\n",
"class TextChunkingTool:\n",
" def __init__(self, chunk_size: int = 1000, chunk_overlap: int = 200):\n",
" self.chunk_size = chunk_size\n",
" self.chunk_overlap = chunk_overlap\n",
"\n",
" def chunk_text(self, text: str) -> List[str]:\n",
" \"\"\"Split text into overlapping chunks\"\"\"\n",
" try:\n",
" # Clean the text\n",
" text = re.sub(r'\\s+', ' ', text).strip()\n",
"\n",
" # Split into sentences first\n",
" sentences = re.split(r'[.!?]+', text)\n",
" sentences = [s.strip() for s in sentences if s.strip()]\n",
"\n",
" chunks = []\n",
" current_chunk = \"\"\n",
"\n",
" for sentence in sentences:\n",
" # If adding this sentence would exceed chunk size\n",
" if len(current_chunk) + len(sentence) > self.chunk_size and current_chunk:\n",
" chunks.append(current_chunk.strip())\n",
" # Start new chunk with overlap\n",
" overlap_start = max(0, len(current_chunk) - self.chunk_overlap)\n",
" current_chunk = current_chunk[overlap_start:] + \" \" + sentence\n",
" else:\n",
" current_chunk += \" \" + sentence if current_chunk else sentence\n",
"\n",
" # Add the last chunk\n",
" if current_chunk:\n",
" chunks.append(current_chunk.strip())\n",
"\n",
" return chunks\n",
" except Exception as e:\n",
" return [f\"Error chunking text: {str(e)}\"]\n",
"\n",
" def chunk_text_by_paragraphs(self, text: str) -> List[str]:\n",
" \"\"\"Split text by paragraphs\"\"\"\n",
" try:\n",
" paragraphs = text.split('\\n\\n')\n",
" chunks = []\n",
"\n",
" for paragraph in paragraphs:\n",
" paragraph = paragraph.strip()\n",
" if paragraph:\n",
" # If paragraph is too long, split it further\n",
" if len(paragraph) > self.chunk_size:\n",
" sub_chunks = self.chunk_text(paragraph)\n",
" chunks.extend(sub_chunks)\n",
" else:\n",
" chunks.append(paragraph)\n",
"\n",
" return chunks\n",
" except Exception as e:\n",
" return [f\"Error chunking paragraphs: {str(e)}\"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vuE2noGJc5UM"
},
"source": [
"# YAML Prompt"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "9okcME5dc6g5",
"outputId": "04372512-a187-4db2-e578-d6964b9b0ee7"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ YAML Prompt configured!\n"
]
}
],
"source": [
"# YAML Prompt\n",
"yaml_prompt = \"\"\"\n",
"name: \"Local RAG Document Agent\"\n",
"description: \"Expert document analyst with local LLM capabilities and vector search\"\n",
"instructions:\n",
" - \"You are an expert document analyst that processes and analyzes documents using local LLM models\"\n",
" - \"Use vector database search to find relevant document chunks for answering questions\"\n",
" - \"Process uploaded documents and extract meaningful information\"\n",
" - \"Provide accurate answers based on document content with source attribution\"\n",
" - \"Chunk documents appropriately for optimal vector search performance\"\n",
" - \"Always cite the source document when providing answers\"\n",
" - \"Use markdown formatting for better readability\"\n",
" - \"Handle multiple document formats (PDF, TXT, MD, CSV)\"\n",
" - \"Provide context-aware responses based on document content\"\n",
"\n",
"tools:\n",
" - name: \"DocumentProcessingTool\"\n",
" description: \"Processes different document formats (PDF, TXT, MD, CSV) and extracts text content\"\n",
" - name: \"VectorDatabaseTool\"\n",
" description: \"Manages vector database operations for document storage and similarity search\"\n",
" - name: \"TextChunkingTool\"\n",
" description: \"Splits text into appropriate chunks for vector embedding and retrieval\"\n",
"\n",
"output_format:\n",
" - \"Provide clear, document-based answers\"\n",
" - \"Include source attribution when possible\"\n",
" - \"Summarize key information from documents\"\n",
" - \"Suggest follow-up questions if relevant\"\n",
" - \"Use bullet points and structured formatting\"\n",
" - \"Highlight important findings from the documents\"\n",
"\n",
"temperature: 0.3\n",
"max_tokens: 4000\n",
"model: \"local-llama3.2\"\n",
"\"\"\"\n",
"\n",
"print(\"✅ YAML Prompt configured!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fF-XYF0UdEnT"
},
"source": [
"# Main"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "AoZrQUyLdGCT",
"outputId": "069a3115-b6c0-4111-b1ca-080466048f30"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"�� Local RAG Document Agent\n",
"Document-based Q&A powered by local LLM and vector search!\n",
"\n",
"📁 Upload Your Documents\n",
"Please upload PDF, TXT, MD, or CSV files:\n"
]
},
{
"data": {
"text/html": [
"\n",
" <input type=\"file\" id=\"files-bc658477-fb0b-4b0b-a549-501485fe7cab\" name=\"files[]\" multiple disabled\n",
" style=\"border:none\" />\n",
" <output id=\"result-bc658477-fb0b-4b0b-a549-501485fe7cab\">\n",
" Upload widget is only available when the cell has been executed in the\n",
" current browser session. Please rerun this cell to enable.\n",
" </output>\n",
" <script>// Copyright 2017 Google LLC\n",
"//\n",
"// Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"// you may not use this file except in compliance with the License.\n",
"// You may obtain a copy of the License at\n",
"//\n",
"// http://www.apache.org/licenses/LICENSE-2.0\n",
"//\n",
"// Unless required by applicable law or agreed to in writing, software\n",
"// distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"// See the License for the specific language governing permissions and\n",
"// limitations under the License.\n",
"\n",
"/**\n",
" * @fileoverview Helpers for google.colab Python module.\n",
" */\n",
"(function(scope) {\n",
"function span(text, styleAttributes = {}) {\n",
" const element = document.createElement('span');\n",
" element.textContent = text;\n",
" for (const key of Object.keys(styleAttributes)) {\n",
" element.style[key] = styleAttributes[key];\n",
" }\n",
" return element;\n",
"}\n",
"\n",
"// Max number of bytes which will be uploaded at a time.\n",
"const MAX_PAYLOAD_SIZE = 100 * 1024;\n",
"\n",
"function _uploadFiles(inputId, outputId) {\n",
" const steps = uploadFilesStep(inputId, outputId);\n",
" const outputElement = document.getElementById(outputId);\n",
" // Cache steps on the outputElement to make it available for the next call\n",
" // to uploadFilesContinue from Python.\n",
" outputElement.steps = steps;\n",
"\n",
" return _uploadFilesContinue(outputId);\n",
"}\n",
"\n",
"// This is roughly an async generator (not supported in the browser yet),\n",
"// where there are multiple asynchronous steps and the Python side is going\n",
"// to poll for completion of each step.\n",
"// This uses a Promise to block the python side on completion of each step,\n",
"// then passes the result of the previous step as the input to the next step.\n",
"function _uploadFilesContinue(outputId) {\n",
" const outputElement = document.getElementById(outputId);\n",
" const steps = outputElement.steps;\n",
"\n",
" const next = steps.next(outputElement.lastPromiseValue);\n",
" return Promise.resolve(next.value.promise).then((value) => {\n",
" // Cache the last promise value to make it available to the next\n",
" // step of the generator.\n",
" outputElement.lastPromiseValue = value;\n",
" return next.value.response;\n",
" });\n",
"}\n",
"\n",
"/**\n",
" * Generator function which is called between each async step of the upload\n",
" * process.\n",
" * @param {string} inputId Element ID of the input file picker element.\n",
" * @param {string} outputId Element ID of the output display.\n",
" * @return {!Iterable<!Object>} Iterable of next steps.\n",
" */\n",
"function* uploadFilesStep(inputId, outputId) {\n",
" const inputElement = document.getElementById(inputId);\n",
" inputElement.disabled = false;\n",
"\n",
" const outputElement = document.getElementById(outputId);\n",
" outputElement.innerHTML = '';\n",
"\n",
" const pickedPromise = new Promise((resolve) => {\n",
" inputElement.addEventListener('change', (e) => {\n",
" resolve(e.target.files);\n",
" });\n",
" });\n",
"\n",
" const cancel = document.createElement('button');\n",
" inputElement.parentElement.appendChild(cancel);\n",
" cancel.textContent = 'Cancel upload';\n",
" const cancelPromise = new Promise((resolve) => {\n",
" cancel.onclick = () => {\n",
" resolve(null);\n",
" };\n",
" });\n",
"\n",
" // Wait for the user to pick the files.\n",
" const files = yield {\n",
" promise: Promise.race([pickedPromise, cancelPromise]),\n",
" response: {\n",
" action: 'starting',\n",
" }\n",
" };\n",
"\n",
" cancel.remove();\n",
"\n",
" // Disable the input element since further picks are not allowed.\n",
" inputElement.disabled = true;\n",
"\n",
" if (!files) {\n",
" return {\n",
" response: {\n",
" action: 'complete',\n",
" }\n",
" };\n",
" }\n",
"\n",
" for (const file of files) {\n",
" const li = document.createElement('li');\n",
" li.append(span(file.name, {fontWeight: 'bold'}));\n",
" li.append(span(\n",
" `(${file.type || 'n/a'}) - ${file.size} bytes, ` +\n",
" `last modified: ${\n",
" file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() :\n",
" 'n/a'} - `));\n",
" const percent = span('0% done');\n",
" li.appendChild(percent);\n",
"\n",
" outputElement.appendChild(li);\n",
"\n",
" const fileDataPromise = new Promise((resolve) => {\n",
" const reader = new FileReader();\n",
" reader.onload = (e) => {\n",
" resolve(e.target.result);\n",
" };\n",
" reader.readAsArrayBuffer(file);\n",
" });\n",
" // Wait for the data to be ready.\n",
" let fileData = yield {\n",
" promise: fileDataPromise,\n",
" response: {\n",
" action: 'continue',\n",
" }\n",
" };\n",
"\n",
" // Use a chunked sending to avoid message size limits. See b/62115660.\n",
" let position = 0;\n",
" do {\n",
" const length = Math.min(fileData.byteLength - position, MAX_PAYLOAD_SIZE);\n",
" const chunk = new Uint8Array(fileData, position, length);\n",
" position += length;\n",
"\n",
" const base64 = btoa(String.fromCharCode.apply(null, chunk));\n",
" yield {\n",
" response: {\n",
" action: 'append',\n",
" file: file.name,\n",
" data: base64,\n",
" },\n",
" };\n",
"\n",
" let percentDone = fileData.byteLength === 0 ?\n",
" 100 :\n",
" Math.round((position / fileData.byteLength) * 100);\n",
" percent.textContent = `${percentDone}% done`;\n",
"\n",
" } while (position < fileData.byteLength);\n",
" }\n",
"\n",
" // All done.\n",
" yield {\n",
" response: {\n",
" action: 'complete',\n",
" }\n",
" };\n",
"}\n",
"\n",
"scope.google = scope.google || {};\n",
"scope.google.colab = scope.google.colab || {};\n",
"scope.google.colab._files = {\n",
" _uploadFiles,\n",
" _uploadFilesContinue,\n",
"};\n",
"})(self);\n",
"</script> "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Saving customers-100.csv to customers-100.csv\n",
"\n",
"📄 Processing: customers-100.csv\n",
"✅ Successfully processed customers-100.csv\n",
" - Format: csv\n",
" - Text length: 27875 characters\n",
"\n",
"�� Processing Summary:\n",
"- Total documents processed: 1\n",
"\n",
"�� Chunking documents for vector storage...\n",
"- Total chunks created: 23\n",
"\n",
"🗄️ Adding documents to vector database...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx.tar.gz: 100%|██████████| 79.3M/79.3M [00:01<00:00, 70.7MiB/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Successfully added 23 chunks to vector database\n",
"📈 Vector database now contains 23 total chunks\n",
"\n",
"🤔 Interactive Q&A Session\n",
"Ask questions about your documents (type 'quit' to exit):\n",
"\n",
"❓ Your question: what is that\n",
"🔍 Searching for relevant information...\n",
"📚 Found 3 relevant chunks:\n",
"\n",
"--- Chunk 1 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: ank com 2020-03-26 https://www pugh com/ 92 98b3aeDcC3B9FF3 Shane Foley Rocha-Hart South Dannymouth Hungary +1-822-569-0302 001-626-114-5844x55073 nsteele@sparks com 2021-07-06 https://www holt-sparks...\n",
"\n",
"--- Chunk 2 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: Robersonstad Cyprus 854-138-4911x5772 +1-448-910-2276x729 mariokhan@ryan-pope org 2020-01-13 https://www bullock net/ 10 8C2811a503C7c5a Michelle Gallagher Beck-Hendrix Elaineberg Timor-Leste 739 218 ...\n",
"\n",
"--- Chunk 3 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: x58692 001-841-293-3519x614 hhart@jensen com 2022-01-30 http://hayes-perez com/ 97 CeD220bdAaCfaDf Lynn Atkinson Ware, Burns and Oneal New Bradview Sri Lanka +1-846-706-2218 605 413 3198 vkemp@ferrell...\n",
"\n",
"💡 AI Answer (using local LLM):\n",
"Based on the document content, here's what I found...\n",
"(This would be generated by the local LLM model)\n",
"\n",
"❓ Your question: how much total text length\n",
"🔍 Searching for relevant information...\n",
"📚 Found 3 relevant chunks:\n",
"\n",
"--- Chunk 1 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: 2-13 https://gillespie-holder com/ 44 D3fC11A9C235Dc6 Luis Greer Cross PLC North Drew Bulgaria 001-336-025-6849x701 684 698 2911x6092 bstuart@williamson-mcclure com 2022-05-15 https://fletcher-nielsen...\n",
"\n",
"--- Chunk 2 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: 3x7288 (203)287-1003x5932 kmercer@wagner com 2020-07-21 http://murray org/ 88 E4Bbcd8AD81fC5f Alison Vargas Vaughn, Watts and Leach East Cristinabury Benin 365-273-8144 053-308-7653x6287 vcantu@norton...\n",
"\n",
"--- Chunk 3 ---\n",
"Source: /tmp/tmp7yzm_3y4.csv\n",
"Format: csv\n",
"Content: rt com 2021-03-10 http://www benson-roth com/ 18 F8Aa9d6DfcBeeF8 Greg Mata Valentine LLC Lake Leslie Mozambique (701)087-2415 (195)156-1861x26241 jaredjuarez@carroll org 2022-03-26 http://pitts-cherry...\n",
"\n",
"💡 AI Answer (using local LLM):\n",
"Based on the document content, here's what I found...\n",
"(This would be generated by the local LLM model)\n",
"\n",
"❓ Your question: quit\n",
"\n",
"👋 Q&A session ended.\n",
"\n",
"🧪 Sample Document for Testing\n",
"Creating sample document...\n",
"✅ Sample document created!\n",
"📄 Sample document content:\n",
"\n",
"# Sample Document\n",
"\n",
"This is a sample document for testing the Local RAG Document Agent.\n",
"\n",
"## Introduction\n",
"The Local RAG Document Agent is designed to process and analyze documents using local LLM model...\n",
"\n",
"==================================================\n",
"�� Powered by Local RAG Document Agent | Built with PraisonAI\n"
]
}
],
"source": [
"# Main Application (Google Colab Version)\n",
"import streamlit as st\n",
"import pandas as pd\n",
"import tempfile\n",
"import os\n",
"from typing import Dict, Any, List\n",
"from google.colab import files\n",
"import io\n",
"\n",
"# Initialize tools\n",
"doc_tool = DocumentProcessingTool()\n",
"vector_tool = VectorDatabaseTool()\n",
"chunk_tool = TextChunkingTool()\n",
"\n",
"print(\"�� Local RAG Document Agent\")\n",
"print(\"Document-based Q&A powered by local LLM and vector search!\")\n",
"\n",
"# Document upload section for Google Colab\n",
"print(\"\\n📁 Upload Your Documents\")\n",
"print(\"Please upload PDF, TXT, MD, or CSV files:\")\n",
"\n",
"uploaded = files.upload()\n",
"\n",
"if uploaded:\n",
" # Process each uploaded file\n",
" processed_docs = []\n",
"\n",
" for file_name, file_content in uploaded.items():\n",
" print(f\"\\n📄 Processing: {file_name}\")\n",
"\n",
" # Save file temporarily\n",
" with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file_name)[1]) as temp_file:\n",
" temp_file.write(file_content)\n",
" temp_path = temp_file.name\n",
"\n",
" # Process document\n",
" doc_result = doc_tool.process_document(temp_path)\n",
"\n",
" if \"error\" not in doc_result:\n",
" processed_docs.append(doc_result)\n",
" print(f\"✅ Successfully processed {file_name}\")\n",
" print(f\" - Format: {doc_result.get('format', 'unknown')}\")\n",
" print(f\" - Text length: {len(doc_result['text'])} characters\")\n",
"\n",
" if 'pages' in doc_result:\n",
" print(f\" - Pages: {doc_result['pages']}\")\n",
" else:\n",
" print(f\"❌ Error processing {file_name}: {doc_result['error']}\")\n",
"\n",
" # Clean up temp file\n",
" os.unlink(temp_path)\n",
"\n",
" if processed_docs:\n",
" print(f\"\\n�� Processing Summary:\")\n",
" print(f\"- Total documents processed: {len(processed_docs)}\")\n",
"\n",
" # Chunk documents\n",
" print(\"\\n�� Chunking documents for vector storage...\")\n",
" all_chunks = []\n",
" chunk_metadata = []\n",
"\n",
" for i, doc in enumerate(processed_docs):\n",
" chunks = chunk_tool.chunk_text(doc['text'])\n",
" all_chunks.extend(chunks)\n",
"\n",
" # Create metadata for each chunk\n",
" for j, chunk in enumerate(chunks):\n",
" chunk_metadata.append({\n",
" \"source\": doc.get('file_path', f'document_{i}'),\n",
" \"format\": doc.get('format', 'unknown'),\n",
" \"chunk_index\": j,\n",
" \"total_chunks\": len(chunks)\n",
" })\n",
"\n",
" print(f\"- Total chunks created: {len(all_chunks)}\")\n",
"\n",
" # Add to vector database\n",
" print(\"\\n🗄️ Adding documents to vector database...\")\n",
" vector_result = vector_tool.add_documents(all_chunks, chunk_metadata)\n",
"\n",
" if \"error\" not in vector_result:\n",
" print(f\"✅ Successfully added {vector_result['documents_added']} chunks to vector database\")\n",
"\n",
" # Get collection info\n",
" collection_info = vector_tool.get_collection_info()\n",
" if \"error\" not in collection_info:\n",
" print(f\"📈 Vector database now contains {collection_info['document_count']} total chunks\")\n",
"\n",
" # Interactive Q&A\n",
" print(\"\\n🤔 Interactive Q&A Session\")\n",
" print(\"Ask questions about your documents (type 'quit' to exit):\")\n",
"\n",
" while True:\n",
" question = input(\"\\n❓ Your question: \")\n",
"\n",
" if question.lower() in ['quit', 'exit', 'q']:\n",
" break\n",
"\n",
" if question.strip():\n",
" print(\"🔍 Searching for relevant information...\")\n",
"\n",
" # Search vector database\n",
" search_result = vector_tool.search_documents(question, n_results=3)\n",
"\n",
" if \"error\" not in search_result and search_result['num_results'] > 0:\n",
" print(f\"📚 Found {search_result['num_results']} relevant chunks:\")\n",
"\n",
" for i, (doc, metadata) in enumerate(zip(\n",
" search_result['results']['documents'][0],\n",
" search_result['results']['metadatas'][0]\n",
" )):\n",
" print(f\"\\n--- Chunk {i+1} ---\")\n",
" print(f\"Source: {metadata.get('source', 'Unknown')}\")\n",
" print(f\"Format: {metadata.get('format', 'Unknown')}\")\n",
" print(f\"Content: {doc[:200]}...\")\n",
"\n",
" # Here you would integrate with local LLM for answer generation\n",
" print(f\"\\n💡 AI Answer (using local LLM):\")\n",
" print(\"Based on the document content, here's what I found...\")\n",
" print(\"(This would be generated by the local LLM model)\")\n",
"\n",
" else:\n",
" print(\"❌ No relevant information found in the documents.\")\n",
" print(\"Try rephrasing your question or check if the documents contain the information you're looking for.\")\n",
" else:\n",
" print(\"Please enter a question.\")\n",
"\n",
" print(\"\\n👋 Q&A session ended.\")\n",
"\n",
" else:\n",
" print(f\"❌ Error adding to vector database: {vector_result['error']}\")\n",
"\n",
" else:\n",
" print(\"❌ No documents were successfully processed.\")\n",
"\n",
"else:\n",
" print(\"❌ No files uploaded. Please upload documents to get started.\")\n",
"\n",
"# Sample document section\n",
"print(\"\\n🧪 Sample Document for Testing\")\n",
"print(\"Creating sample document...\")\n",
"\n",
"# Create sample document\n",
"sample_text = \"\"\"\n",
"# Sample Document\n",
"\n",
"This is a sample document for testing the Local RAG Document Agent.\n",
"\n",
"## Introduction\n",
"The Local RAG Document Agent is designed to process and analyze documents using local LLM models and vector search capabilities.\n",
"\n",
"## Features\n",
"- Document processing for multiple formats (PDF, TXT, MD, CSV)\n",
"- Vector database storage and retrieval\n",
"- Local LLM inference without external API calls\n",
"- Intelligent Q&A with source attribution\n",
"\n",
"## Technical Details\n",
"The agent uses ChromaDB for vector storage and Ollama for local LLM inference.\n",
"It can handle various document formats and provides context-aware responses.\n",
"\n",
"## Usage\n",
"1. Upload your documents\n",
"2. Ask questions about the content\n",
"3. Get AI-powered answers with source references\n",
"\"\"\"\n",
"\n",
"# Save sample document\n",
"with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.md') as temp_file:\n",
" temp_file.write(sample_text)\n",
" sample_path = temp_file.name\n",
"\n",
"print(\"✅ Sample document created!\")\n",
"print(\"📄 Sample document content:\")\n",
"print(sample_text[:200] + \"...\")\n",
"\n",
"# Footer\n",
"print(\"\\n\" + \"=\"*50)\n",
"print(\"�� Powered by Local RAG Document Agent | Built with PraisonAI\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,481 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "KoeGA1N7R8G6"
},
"source": [
"# Praison AI Real Estate Chatbot"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cwsqbQF0SAcR"
},
"source": [
"Interact with a real estate AI assistant powered by PraisonAI and OpenAI.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "BH0Y-SB9UjNZ"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "M4lyScgcSIFX"
},
"source": [
"## 1. Install Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "p0UqhMK9TMLx"
},
"outputs": [],
"source": [
"!pip install praisonaiagents openai"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XjtPizGWSRuh"
},
"source": [
"## 2. Set Your OpenAI API Key"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "FTzcJ7JTTPjp"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# Enter your OpenAI API key here\n",
"OPENAI_API_KEY = \"Enter your api key here\" # <-- Replace with your key\n",
"os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5WIQ76LQSeOT"
},
"source": [
"## 3. Create the Praison AI Agent"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "mJYmlRHtTW59"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent\n",
"\n",
"praison_agent = Agent(\n",
" name=\"Praison Real Estate Chatbot\",\n",
" role=\"Answer real estate questions and provide helpful advice.\",\n",
" instructions=[\n",
" \"You are a helpful real estate assistant.\",\n",
" \"Answer user questions about buying, selling, or renting property.\",\n",
" \"Provide clear, concise, and friendly advice.\"\n",
" ],\n",
" markdown=True\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "wDOYoxf2SlSD"
},
"source": [
"## 4. Chat with the Agent"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"caca39e23f66484e941342713956f289",
"a9f33a0ed67440f1aee8c84ee7e71b1d",
"bcc0387223424b45aec4212eae3aff89",
"030f0e16572a40a7b8e100a6228030e3",
"c91fa91cf91c4697ac28756d6bdf2c73",
"08b05be0ee174761974bc10c1d217b53",
"a08f3878570c48f38bfa3a097cb1e4d6",
"58b89df2db0344fe80f29508c55b2939",
"73ced2df95814c068150e9357692f47b",
"9fbf91ecc93f4230beac5dfc0bf734f6"
]
},
"id": "zIyEMJJ6TZlb",
"outputId": "817d4df6-ec88-425e-f00b-8ce6b4923e00"
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "caca39e23f66484e941342713956f289",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Text(value='', description='You:', placeholder='Type your real estate question here...')"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "030f0e16572a40a7b8e100a6228030e3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Button(description='Ask Praison AI', style=ButtonStyle())"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a08f3878570c48f38bfa3a097cb1e4d6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 1.7s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 1.7s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Hello! How can I assist you with your real estate needs today? Whether you have questions about buying, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> selling, or renting property, I'm here to help. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m Hello! How can I assist you with your real estate needs today? Whether you have questions about buying, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m selling, or renting property, I'm here to help. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/markdown": [
"**Praison AI:** Hello! How can I assist you with your real estate needs today? Whether you have questions about buying, selling, or renting property, I'm here to help."
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Praison Real Estate Chatbot</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Answer real estate questions and provide helpful advice.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mPraison Real Estate Chatbot\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mAnswer real estate questions and provide helpful advice.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "73ced2df95814c068150e9357692f47b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 6.3s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 6.3s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> What should I look for when buying my first home? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m What should I look for when buying my first home? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Buying your first home is an exciting milestone! Here are some key things to consider: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 1 </span><span style=\"font-weight: bold\">Budget and Financing</span>: Determine how much you can afford by reviewing your finances and getting pre-approved <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>for a mortgage. This will help you understand your price range and make your offer more attractive to <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>sellers. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 2 </span><span style=\"font-weight: bold\">Location</span>: Consider the neighborhood and its proximity to work, schools, public transportation, and amenities <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>like shopping and parks. Also, research the area's safety and future development plans. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 3 </span><span style=\"font-weight: bold\">Home Type and Size</span>: Decide what type of home suits your needs—single-family, townhouse, condo, etc. Consider <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>the number of bedrooms and bathrooms you need now and in the future. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 4 </span><span style=\"font-weight: bold\">Condition of the Property</span>: Look at the age and condition of the home. Be aware of potential repairs or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>renovations needed. A home inspection can help identify any major issues. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 5 </span><span style=\"font-weight: bold\">Resale Value</span>: Consider the potential resale value of the home. Factors like location, school districts, and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>neighborhood development can impact future value. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 6 </span><span style=\"font-weight: bold\">Lifestyle Needs</span>: Think about your lifestyle and how the home fits into it. Consider things like yard space, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>commute times, and community amenities. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 7 </span><span style=\"font-weight: bold\">Homeowners Association (HOA)</span>: If applicable, understand the rules, fees, and restrictions of the HOA. This <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>can impact your living experience and costs. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> 8 </span><span style=\"font-weight: bold\">Future Growth</span>: Consider your long-term plans. Will the home accommodate potential family growth or changes <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\"> </span>in your lifestyle? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Taking the time to consider these factors will help you make a well-informed decision. Good luck with your home <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> search! If you have more questions, feel free to ask. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m Buying your first home is an exciting milestone! Here are some key things to consider: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 1 \u001b[0m\u001b[1mBudget and Financing\u001b[0m: Determine how much you can afford by reviewing your finances and getting pre-approved \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mfor a mortgage. This will help you understand your price range and make your offer more attractive to \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0msellers. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 2 \u001b[0m\u001b[1mLocation\u001b[0m: Consider the neighborhood and its proximity to work, schools, public transportation, and amenities \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mlike shopping and parks. Also, research the area's safety and future development plans. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 3 \u001b[0m\u001b[1mHome Type and Size\u001b[0m: Decide what type of home suits your needs—single-family, townhouse, condo, etc. Consider \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mthe number of bedrooms and bathrooms you need now and in the future. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 4 \u001b[0m\u001b[1mCondition of the Property\u001b[0m: Look at the age and condition of the home. Be aware of potential repairs or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mrenovations needed. A home inspection can help identify any major issues. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 5 \u001b[0m\u001b[1mResale Value\u001b[0m: Consider the potential resale value of the home. Factors like location, school districts, and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mneighborhood development can impact future value. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 6 \u001b[0m\u001b[1mLifestyle Needs\u001b[0m: Think about your lifestyle and how the home fits into it. Consider things like yard space, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mcommute times, and community amenities. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 7 \u001b[0m\u001b[1mHomeowners Association (HOA)\u001b[0m: If applicable, understand the rules, fees, and restrictions of the HOA. This \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0mcan impact your living experience and costs. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m 8 \u001b[0m\u001b[1mFuture Growth\u001b[0m: Consider your long-term plans. Will the home accommodate potential family growth or changes \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[1;33m \u001b[0min your lifestyle? \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Taking the time to consider these factors will help you make a well-informed decision. Good luck with your home \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m search! If you have more questions, feel free to ask. \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/markdown": [
"**Praison AI:** Buying your first home is an exciting milestone! Here are some key things to consider:\n",
"\n",
"1. **Budget and Financing**: Determine how much you can afford by reviewing your finances and getting pre-approved for a mortgage. This will help you understand your price range and make your offer more attractive to sellers.\n",
"\n",
"2. **Location**: Consider the neighborhood and its proximity to work, schools, public transportation, and amenities like shopping and parks. Also, research the area's safety and future development plans.\n",
"\n",
"3. **Home Type and Size**: Decide what type of home suits your needs—single-family, townhouse, condo, etc. Consider the number of bedrooms and bathrooms you need now and in the future.\n",
"\n",
"4. **Condition of the Property**: Look at the age and condition of the home. Be aware of potential repairs or renovations needed. A home inspection can help identify any major issues.\n",
"\n",
"5. **Resale Value**: Consider the potential resale value of the home. Factors like location, school districts, and neighborhood development can impact future value.\n",
"\n",
"6. **Lifestyle Needs**: Think about your lifestyle and how the home fits into it. Consider things like yard space, commute times, and community amenities.\n",
"\n",
"7. **Homeowners Association (HOA)**: If applicable, understand the rules, fees, and restrictions of the HOA. This can impact your living experience and costs.\n",
"\n",
"8. **Future Growth**: Consider your long-term plans. Will the home accommodate potential family growth or changes in your lifestyle?\n",
"\n",
"Taking the time to consider these factors will help you make a well-informed decision. Good luck with your home search! If you have more questions, feel free to ask."
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import ipywidgets as widgets\n",
"from IPython.display import display, Markdown\n",
"\n",
"def ask_agent(question):\n",
" # Use the .chat() method for the public praisonaiagents package\n",
" response = praison_agent.chat(question)\n",
" display(Markdown(f\"**Praison AI:** {response}\"))\n",
"\n",
"question = widgets.Text(\n",
" value='',\n",
" placeholder='Type your real estate question here...',\n",
" description='You:',\n",
" disabled=False\n",
")\n",
"button = widgets.Button(description=\"Ask Praison AI\")\n",
"\n",
"def on_button_clicked(b):\n",
" ask_agent(question.value)\n",
"\n",
"button.on_click(on_button_clicked)\n",
"display(question, button)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,800 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "04dGdK2VftUM"
},
"source": [
"# AI Meme Creator Agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xUTYMeY9fvUA"
},
"source": [
"* An AI agent that generates memes using browser automation and multiple LLM models.\n",
"* The agent can create custom memes based on user prompts by navigating to meme creation websites, selecting templates, and generating captions.\n",
"* Features include multi-model support (Claude, Deepseek, OpenAI), browser automation, template selection, and automatic meme generation with direct image links."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_hI9XGsJicU8"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/ai_meme_creator_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6rrl-ZHqgCj2"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "pP9B-OsCgDpr"
},
"outputs": [],
"source": [
"!pip install praisonai streamlit browser-use langchain-openai langchain-anthropic langchain-core"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Xe0_c_lig5YJ"
},
"source": [
"# Setup Key"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fsVpWSVHg64O",
"outputId": "74d0ee0f-a3e2-413c-98cd-a410888eedb3"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ API keys configured!\n",
"✅ Using model: OpenAI\n"
]
}
],
"source": [
"import os\n",
"\n",
"# Set your API keys\n",
"openai_key = \"Enter you api key here\"\n",
"anthropic_key = \"Enter you api key here\" # Get from https://console.anthropic.com\n",
"deepseek_key = \"Enter you api key here\" # Get from https://platform.deepseek.com\n",
"\n",
"# Set environment variables\n",
"os.environ[\"OPENAI_API_KEY\"] = openai_key\n",
"os.environ[\"ANTHROPIC_API_KEY\"] = anthropic_key\n",
"os.environ[\"DEEPSEEK_API_KEY\"] = deepseek_key\n",
"\n",
"# Model selection\n",
"model_choice = \"OpenAI\" # Options: \"OpenAI\", \"Claude\", \"Deepseek\"\n",
"\n",
"print(\"✅ API keys configured!\")\n",
"print(f\"✅ Using model: {model_choice}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rtqdR4Odhexu"
},
"source": [
"# Tools"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "I9uC9c97hgYg"
},
"outputs": [],
"source": [
"# Custom Meme Template Search Tool\n",
"import requests\n",
"from typing import Dict, Any, List\n",
"import re\n",
"\n",
"class MemeTemplateSearchTool:\n",
" def __init__(self):\n",
" self.base_url = \"https://imgflip.com\"\n",
" self.popular_templates = [\n",
" \"distracted-boyfriend\", \"two-buttons\", \"one-does-not-simply\",\n",
" \"drake-hotline-bling\", \"change-my-mind\", \"ancient-aliens\",\n",
" \"y-u-no\", \"success-kid\", \"first-world-problems\", \"futurama-fry\"\n",
" ]\n",
"\n",
" def search_templates(self, query: str) -> Dict[str, Any]:\n",
" \"\"\"Search for meme templates based on query\"\"\"\n",
" try:\n",
" # Extract key action words from query\n",
" action_words = self._extract_action_words(query.lower())\n",
"\n",
" # Find relevant templates\n",
" relevant_templates = []\n",
" for template in self.popular_templates:\n",
" if any(word in template for word in action_words):\n",
" relevant_templates.append(template)\n",
"\n",
" # If no direct matches, return popular templates\n",
" if not relevant_templates:\n",
" relevant_templates = self.popular_templates[:5]\n",
"\n",
" return {\n",
" \"success\": True,\n",
" \"query\": query,\n",
" \"action_words\": action_words,\n",
" \"suggested_templates\": relevant_templates,\n",
" \"template_urls\": [f\"{self.base_url}/{template}\" for template in relevant_templates]\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error searching templates: {str(e)}\"}\n",
"\n",
" def _extract_action_words(self, text: str) -> List[str]:\n",
" \"\"\"Extract action words from text\"\"\"\n",
" action_words = [\n",
" \"laugh\", \"cry\", \"smile\", \"angry\", \"surprised\", \"confused\",\n",
" \"happy\", \"sad\", \"excited\", \"worried\", \"thinking\", \"shocked\",\n",
" \"bully\", \"fight\", \"work\", \"study\", \"sleep\", \"eat\", \"drink\",\n",
" \"run\", \"walk\", \"sit\", \"stand\", \"look\", \"watch\", \"listen\"\n",
" ]\n",
"\n",
" found_words = []\n",
" for word in action_words:\n",
" if word in text:\n",
" found_words.append(word)\n",
"\n",
" return found_words\n",
"\n",
"# Custom Caption Generator Tool\n",
"import random\n",
"\n",
"class CaptionGeneratorTool:\n",
" def __init__(self):\n",
" self.caption_styles = {\n",
" \"setup_punchline\": \"Top: {setup}\\nBottom: {punchline}\",\n",
" \"comparison\": \"Top: {option1}\\nBottom: {option2}\",\n",
" \"reaction\": \"Top: {situation}\\nBottom: {reaction}\",\n",
" \"confession\": \"Top: {confession}\\nBottom: {reality}\"\n",
" }\n",
"\n",
" def generate_captions(self, query: str, template: str) -> Dict[str, Any]:\n",
" \"\"\"Generate meme captions based on query and template\"\"\"\n",
" try:\n",
" # Analyze query for meme type\n",
" meme_type = self._analyze_meme_type(query)\n",
"\n",
" # Generate captions based on type\n",
" if meme_type == \"comparison\":\n",
" captions = self._generate_comparison_captions(query)\n",
" elif meme_type == \"reaction\":\n",
" captions = self._generate_reaction_captions(query)\n",
" elif meme_type == \"confession\":\n",
" captions = self._generate_confession_captions(query)\n",
" else:\n",
" captions = self._generate_setup_punchline_captions(query)\n",
"\n",
" return {\n",
" \"success\": True,\n",
" \"query\": query,\n",
" \"template\": template,\n",
" \"meme_type\": meme_type,\n",
" \"captions\": captions,\n",
" \"suggested_style\": self.caption_styles.get(meme_type, self.caption_styles[\"setup_punchline\"])\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error generating captions: {str(e)}\"}\n",
"\n",
" def _analyze_meme_type(self, query: str) -> str:\n",
" \"\"\"Analyze query to determine meme type\"\"\"\n",
" query_lower = query.lower()\n",
"\n",
" if any(word in query_lower for word in [\"vs\", \"versus\", \"or\", \"either\", \"choose\"]):\n",
" return \"comparison\"\n",
" elif any(word in query_lower for word in [\"when\", \"reaction\", \"face\", \"look\"]):\n",
" return \"reaction\"\n",
" elif any(word in query_lower for word in [\"confess\", \"secret\", \"actually\", \"truth\"]):\n",
" return \"confession\"\n",
" else:\n",
" return \"setup_punchline\"\n",
"\n",
" def _generate_setup_punchline_captions(self, query: str) -> List[Dict[str, str]]:\n",
" \"\"\"Generate setup-punchline style captions\"\"\"\n",
" captions = []\n",
"\n",
" # Extract key elements from query\n",
" words = query.split()\n",
" if len(words) >= 3:\n",
" # Create variations\n",
" captions.append({\n",
" \"top\": f\"When {query}\",\n",
" \"bottom\": \"But it actually works\"\n",
" })\n",
" captions.append({\n",
" \"top\": f\"Me trying to {query}\",\n",
" \"bottom\": \"Reality: Complete failure\"\n",
" })\n",
" captions.append({\n",
" \"top\": f\"Everyone: {query}\",\n",
" \"bottom\": \"Me: *confused*\"\n",
" })\n",
"\n",
" return captions\n",
"\n",
" def _generate_comparison_captions(self, query: str) -> List[Dict[str, str]]:\n",
" \"\"\"Generate comparison style captions\"\"\"\n",
" captions = []\n",
"\n",
" captions.append({\n",
" \"top\": \"What I think will happen\",\n",
" \"bottom\": \"What actually happens\"\n",
" })\n",
" captions.append({\n",
" \"top\": \"The plan\",\n",
" \"bottom\": \"The execution\"\n",
" })\n",
" captions.append({\n",
" \"top\": \"Before\",\n",
" \"bottom\": \"After\"\n",
" })\n",
"\n",
" return captions\n",
"\n",
" def _generate_reaction_captions(self, query: str) -> List[Dict[str, str]]:\n",
" \"\"\"Generate reaction style captions\"\"\"\n",
" captions = []\n",
"\n",
" captions.append({\n",
" \"top\": f\"When {query}\",\n",
" \"bottom\": \"My face: 😱\"\n",
" })\n",
" captions.append({\n",
" \"top\": f\"Me: {query}\",\n",
" \"bottom\": \"Also me: *surprised pikachu*\"\n",
" })\n",
"\n",
" return captions\n",
"\n",
" def _generate_confession_captions(self, query: str) -> List[Dict[str, str]]:\n",
" \"\"\"Generate confession style captions\"\"\"\n",
" captions = []\n",
"\n",
" captions.append({\n",
" \"top\": f\"I confess: {query}\",\n",
" \"bottom\": \"But I'm not sorry\"\n",
" })\n",
" captions.append({\n",
" \"top\": f\"Everyone thinks {query}\",\n",
" \"bottom\": \"But actually...\"\n",
" })\n",
"\n",
" return captions\n",
"\n",
"# Custom Meme Validation Tool\n",
"class MemeValidationTool:\n",
" def __init__(self):\n",
" self.validation_criteria = {\n",
" \"humor\": [\"funny\", \"amusing\", \"entertaining\"],\n",
" \"relevance\": [\"related\", \"connected\", \"appropriate\"],\n",
" \"clarity\": [\"clear\", \"understandable\", \"readable\"],\n",
" \"creativity\": [\"original\", \"creative\", \"unique\"]\n",
" }\n",
"\n",
" def validate_meme(self, query: str, captions: List[Dict[str, str]], template: str) -> Dict[str, Any]:\n",
" \"\"\"Validate meme quality and suggest improvements\"\"\"\n",
" try:\n",
" scores = {}\n",
" suggestions = []\n",
"\n",
" # Check humor\n",
" humor_score = self._check_humor(query, captions)\n",
" scores[\"humor\"] = humor_score\n",
" if humor_score < 0.7:\n",
" suggestions.append(\"Consider making the punchline more unexpected or relatable\")\n",
"\n",
" # Check relevance\n",
" relevance_score = self._check_relevance(query, captions)\n",
" scores[\"relevance\"] = relevance_score\n",
" if relevance_score < 0.8:\n",
" suggestions.append(\"Ensure captions directly relate to the query topic\")\n",
"\n",
" # Check clarity\n",
" clarity_score = self._check_clarity(captions)\n",
" scores[\"clarity\"] = clarity_score\n",
" if clarity_score < 0.9:\n",
" suggestions.append(\"Make sure text is short and easy to read\")\n",
"\n",
" # Check creativity\n",
" creativity_score = self._check_creativity(query, captions)\n",
" scores[\"creativity\"] = creativity_score\n",
" if creativity_score < 0.6:\n",
" suggestions.append(\"Try a more unique angle or unexpected twist\")\n",
"\n",
" # Overall score\n",
" overall_score = sum(scores.values()) / len(scores)\n",
"\n",
" return {\n",
" \"success\": True,\n",
" \"scores\": scores,\n",
" \"overall_score\": overall_score,\n",
" \"suggestions\": suggestions,\n",
" \"quality\": \"Excellent\" if overall_score >= 0.8 else \"Good\" if overall_score >= 0.6 else \"Needs Improvement\"\n",
" }\n",
" except Exception as e:\n",
" return {\"error\": f\"Error validating meme: {str(e)}\"}\n",
"\n",
" def _check_humor(self, query: str, captions: List[Dict[str, str]]) -> float:\n",
" \"\"\"Check humor quality\"\"\"\n",
" # Simple heuristic - check for contrast, exaggeration, or relatable elements\n",
" score = 0.5 # Base score\n",
"\n",
" for caption in captions:\n",
" text = f\"{caption.get('top', '')} {caption.get('bottom', '')}\".lower()\n",
"\n",
" # Check for humor indicators\n",
" if any(word in text for word in [\"but\", \"however\", \"actually\", \"reality\"]):\n",
" score += 0.2 # Contrast\n",
" if any(word in text for word in [\"everyone\", \"nobody\", \"always\", \"never\"]):\n",
" score += 0.1 # Exaggeration\n",
" if any(word in text for word in [\"me\", \"my\", \"i\", \"we\"]):\n",
" score += 0.1 # Relatable\n",
"\n",
" return min(1.0, score)\n",
"\n",
" def _check_relevance(self, query: str, captions: List[Dict[str, str]]) -> float:\n",
" \"\"\"Check relevance to query\"\"\"\n",
" query_words = set(query.lower().split())\n",
" score = 0.5 # Base score\n",
"\n",
" for caption in captions:\n",
" caption_text = f\"{caption.get('top', '')} {caption.get('bottom', '')}\".lower()\n",
" caption_words = set(caption_text.split())\n",
"\n",
" # Check word overlap\n",
" overlap = len(query_words.intersection(caption_words))\n",
" if overlap > 0:\n",
" score += 0.3\n",
" if overlap > 2:\n",
" score += 0.2\n",
"\n",
" return min(1.0, score)\n",
"\n",
" def _check_clarity(self, captions: List[Dict[str, str]]) -> float:\n",
" \"\"\"Check text clarity and readability\"\"\"\n",
" score = 1.0 # Start with perfect score\n",
"\n",
" for caption in captions:\n",
" top_text = caption.get('top', '')\n",
" bottom_text = caption.get('bottom', '')\n",
"\n",
" # Penalize long text\n",
" if len(top_text) > 50:\n",
" score -= 0.1\n",
" if len(bottom_text) > 50:\n",
" score -= 0.1\n",
"\n",
" # Penalize complex words\n",
" complex_words = [word for word in top_text.split() if len(word) > 10]\n",
" if len(complex_words) > 0:\n",
" score -= 0.1\n",
"\n",
" return max(0.0, score)\n",
"\n",
" def _check_creativity(self, query: str, captions: List[Dict[str, str]]) -> float:\n",
" \"\"\"Check creativity and originality\"\"\"\n",
" score = 0.5 # Base score\n",
"\n",
" # Check for common meme phrases (penalize)\n",
" common_phrases = [\n",
" \"surprised pikachu\", \"change my mind\", \"one does not simply\",\n",
" \"ancient aliens\", \"distracted boyfriend\", \"drake\"\n",
" ]\n",
"\n",
" for caption in captions:\n",
" caption_text = f\"{caption.get('top', '')} {caption.get('bottom', '')}\".lower()\n",
"\n",
" # Reward for avoiding common phrases\n",
" if not any(phrase in caption_text for phrase in common_phrases):\n",
" score += 0.3\n",
"\n",
" # Reward for unique word combinations\n",
" unique_words = len(set(caption_text.split()))\n",
" if unique_words > 8:\n",
" score += 0.2\n",
"\n",
" return min(1.0, score)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MnaRLR7rhkxd"
},
"source": [
"# YAML Prompt"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "gfjRa17thl_i",
"outputId": "09440897-7b9a-4b04-f535-55abf1240e5c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ YAML Prompt configured!\n"
]
}
],
"source": [
"# YAML Prompt\n",
"yaml_prompt = \"\"\"\n",
"name: \"AI Meme Creator Agent\"\n",
"description: \"Expert meme generator with browser automation and multi-model support\"\n",
"instructions:\n",
" - \"You are an expert meme creator that generates funny and relevant memes based on user prompts\"\n",
" - \"Use browser automation to navigate meme creation websites and select appropriate templates\"\n",
" - \"Generate creative captions that match the meme template and user's request\"\n",
" - \"Ensure memes are humorous, relevant, and visually appealing\"\n",
" - \"Provide multiple caption options for different meme styles\"\n",
" - \"Validate meme quality and suggest improvements when needed\"\n",
" - \"Use appropriate meme templates that fit the context and emotion\"\n",
" - \"Create captions that are short, readable, and impactful\"\n",
" - \"Consider current trends and popular meme formats\"\n",
"\n",
"tools:\n",
" - name: \"MemeTemplateSearchTool\"\n",
" description: \"Searches for appropriate meme templates based on user query and action words\"\n",
" - name: \"CaptionGeneratorTool\"\n",
" description: \"Generates creative captions for memes based on query, template, and meme type\"\n",
" - name: \"MemeValidationTool\"\n",
" description: \"Validates meme quality and provides suggestions for improvement\"\n",
"\n",
"output_format:\n",
" - \"Provide the generated meme image URL\"\n",
" - \"Include caption suggestions and template recommendations\"\n",
" - \"Offer quality assessment and improvement tips\"\n",
" - \"Explain the meme concept and why it works\"\n",
" - \"Provide alternative caption options if available\"\n",
"\n",
"temperature: 0.7\n",
"max_tokens: 3000\n",
"model: \"gpt-4o-mini\"\n",
"\"\"\"\n",
"\n",
"print(\"✅ YAML Prompt configured!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "BlJzii7Whtro"
},
"source": [
"# Main"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "eMA38MJvhvJC",
"outputId": "744230d3-7fce-444f-af78-7bdb98aa8a61"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🥸 AI Meme Creator Agent\n",
"Generate hilarious memes using AI and browser automation!\n",
"\n",
"⚙️ Model Configuration\n",
"✅ Using model: OpenAI\n",
"\n",
"🎨 Meme Creation Interface\n",
"Enter your meme idea:\n",
"Meme Idea: When you finally understand the code after 3 hours of debugging\n",
"\n",
"🚀 Generating meme for: 'When you finally understand the code after 3 hours of debugging'\n",
"\n",
"🔍 Step 1: Searching for meme templates...\n",
"✅ Found 5 relevant templates\n",
"Action words: stand\n",
"\n",
"✍️ Step 2: Generating captions...\n",
"✅ Generated 2 caption options\n",
"Meme type: reaction\n",
"\n",
"📝 Caption Options:\n",
"Option 1:\n",
" Top: When When you finally understand the code after 3 hours of debugging\n",
" Bottom: My face: 😱\n",
"Option 2:\n",
" Top: Me: When you finally understand the code after 3 hours of debugging\n",
" Bottom: Also me: *surprised pikachu*\n",
"\n",
"�� Step 3: Validating meme quality...\n",
"✅ Quality Assessment: Excellent\n",
"Overall Score: 0.88/1.0\n",
"💡 Suggestions for improvement:\n",
" - Make sure text is short and easy to read\n",
"\n",
"�� Step 4: Generating meme with browser automation...\n",
"🔄 Starting browser automation...\n",
"Error in meme generation: \"ChatOpenAI\" object has no field \"ainvoke\"\n",
"❌ Failed to generate meme. This might be due to:\n",
" - Browser automation issues\n",
" - Website changes\n",
" - Network connectivity\n",
" - API rate limits\n",
"\n",
"💡 Manual Meme Creation Instructions:\n",
"1. Go to https://imgflip.com/memetemplates\n",
"2. Search for a template related to your query\n",
"3. Use one of the generated captions:\n",
" Option 1: Top='When When you finally understand the code after 3 hours of debugging', Bottom='My face: 😱'\n",
" Option 2: Top='Me: When you finally understand the code after 3 hours of debugging', Bottom='Also me: *surprised pikachu*'\n",
"\n",
"🧪 Sample Meme Ideas for Testing\n",
"Try these sample ideas:\n",
"1. When you finally understand the code after 3 hours of debugging\n",
"2. Me trying to explain AI to my grandparents\n",
"3. The difference between what I plan to do vs what I actually do\n",
"4. When someone asks if I'm free this weekend\n",
"5. My brain at 3 AM thinking about that embarrassing thing from 5 years ago\n",
"\n",
"==================================================\n",
"�� Powered by AI Meme Creator Agent | Built with PraisonAI\n"
]
}
],
"source": [
"import asyncio\n",
"import streamlit as st\n",
"from browser_use import Agent, SystemPrompt\n",
"from langchain_openai import ChatOpenAI\n",
"from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.messages import HumanMessage\n",
"import re\n",
"import os\n",
"from typing import Dict, Any, List\n",
"\n",
"# Initialize tools\n",
"template_tool = MemeTemplateSearchTool()\n",
"caption_tool = CaptionGeneratorTool()\n",
"validation_tool = MemeValidationTool()\n",
"\n",
"print(\"🥸 AI Meme Creator Agent\")\n",
"print(\"Generate hilarious memes using AI and browser automation!\")\n",
"\n",
"# Model configuration\n",
"print(\"\\n⚙️ Model Configuration\")\n",
"model_choice = \"OpenAI\" # Options: \"OpenAI\", \"Claude\", \"Deepseek\"\n",
"print(f\"✅ Using model: {model_choice}\")\n",
"\n",
"# Meme generation function\n",
"async def generate_meme(query: str, model_choice: str, api_key: str) -> str:\n",
" \"\"\"Generate meme using browser automation\"\"\"\n",
" try:\n",
" # Initialize the appropriate LLM based on user selection\n",
" if model_choice == \"Claude\":\n",
" llm = ChatAnthropic(\n",
" model=\"claude-3-5-sonnet-20241022\",\n",
" api_key=api_key\n",
" )\n",
" elif model_choice == \"Deepseek\":\n",
" llm = ChatOpenAI(\n",
" base_url='https://api.deepseek.com/v1',\n",
" model='deepseek-chat',\n",
" api_key=api_key,\n",
" temperature=0.3\n",
" )\n",
" else: # OpenAI\n",
" llm = ChatOpenAI(\n",
" model=\"gpt-4o\",\n",
" api_key=api_key,\n",
" temperature=0.0\n",
" )\n",
"\n",
" task_description = (\n",
" \"You are a meme generator expert. You are given a query and you need to generate a meme for it.\\n\"\n",
" \"1. Go to https://imgflip.com/memetemplates \\n\"\n",
" \"2. Click on the Search bar in the middle and search for ONLY ONE MAIN ACTION VERB (like 'bully', 'laugh', 'cry') in this query: '{0}'\\n\"\n",
" \"3. Choose any meme template that metaphorically fits the meme topic: '{0}'\\n\"\n",
" \" by clicking on the 'Add Caption' button below it\\n\"\n",
" \"4. Write a Top Text (setup/context) and Bottom Text (punchline/outcome) related to '{0}'.\\n\"\n",
" \"5. Check the preview making sure it is funny and a meaningful meme. Adjust text directly if needed. \\n\"\n",
" \"6. Look at the meme and text on it, if it doesnt make sense, PLEASE retry by filling the text boxes with different text. \\n\"\n",
" \"7. Click on the Generate meme button to generate the meme\\n\"\n",
" \"8. Copy the image link and give it as the output\\n\"\n",
" ).format(query)\n",
"\n",
" agent = Agent(\n",
" task=task_description,\n",
" llm=llm,\n",
" max_actions_per_step=5,\n",
" max_failures=25,\n",
" use_vision=(model_choice != \"Deepseek\")\n",
" )\n",
"\n",
" history = await agent.run()\n",
"\n",
" # Extract final result from agent history\n",
" final_result = history.final_result()\n",
"\n",
" # Use regex to find the meme URL in the result\n",
" url_match = re.search(r'https://imgflip\\.com/i/(\\w+)', final_result)\n",
" if url_match:\n",
" meme_id = url_match.group(1)\n",
" return f\"https://i.imgflip.com/{meme_id}.jpg\"\n",
" return None\n",
" except Exception as e:\n",
" print(f\"Error in meme generation: {str(e)}\")\n",
" return None\n",
"\n",
"# Interactive meme creation\n",
"print(\"\\n🎨 Meme Creation Interface\")\n",
"print(\"Enter your meme idea:\")\n",
"\n",
"query = input(\"Meme Idea: \")\n",
"\n",
"if query.strip():\n",
" print(f\"\\n🚀 Generating meme for: '{query}'\")\n",
"\n",
" # Step 1: Search for templates\n",
" print(\"\\n🔍 Step 1: Searching for meme templates...\")\n",
" template_result = template_tool.search_templates(query)\n",
"\n",
" if \"error\" not in template_result:\n",
" print(f\"✅ Found {len(template_result['suggested_templates'])} relevant templates\")\n",
" print(f\"Action words: {', '.join(template_result['action_words'])}\")\n",
"\n",
" # Step 2: Generate captions\n",
" print(\"\\n✍️ Step 2: Generating captions...\")\n",
" selected_template = template_result['suggested_templates'][0]\n",
" caption_result = caption_tool.generate_captions(query, selected_template)\n",
"\n",
" if \"error\" not in caption_result:\n",
" print(f\"✅ Generated {len(caption_result['captions'])} caption options\")\n",
" print(f\"Meme type: {caption_result['meme_type']}\")\n",
"\n",
" # Display caption options\n",
" print(\"\\n📝 Caption Options:\")\n",
" for i, caption in enumerate(caption_result['captions'], 1):\n",
" print(f\"Option {i}:\")\n",
" print(f\" Top: {caption.get('top', 'N/A')}\")\n",
" print(f\" Bottom: {caption.get('bottom', 'N/A')}\")\n",
"\n",
" # Step 3: Validate meme quality\n",
" print(\"\\n�� Step 3: Validating meme quality...\")\n",
" validation_result = validation_tool.validate_meme(\n",
" query, caption_result['captions'], selected_template\n",
" )\n",
"\n",
" if \"error\" not in validation_result:\n",
" print(f\"✅ Quality Assessment: {validation_result['quality']}\")\n",
" print(f\"Overall Score: {validation_result['overall_score']:.2f}/1.0\")\n",
"\n",
" if validation_result['suggestions']:\n",
" print(\"💡 Suggestions for improvement:\")\n",
" for suggestion in validation_result['suggestions']:\n",
" print(f\" - {suggestion}\")\n",
"\n",
" # Step 4: Generate actual meme (if API key is available)\n",
" print(\"\\n�� Step 4: Generating meme with browser automation...\")\n",
"\n",
" # Check if we have the required API key\n",
" api_key = os.getenv(\"OPENAI_API_KEY\")\n",
" if api_key and api_key != \"your_openai_key_here\":\n",
" try:\n",
" print(\"🔄 Starting browser automation...\")\n",
" meme_url = await generate_meme(query, model_choice, api_key)\n",
"\n",
" if meme_url:\n",
" print(\"✅ Meme Generated Successfully!\")\n",
" print(f\"📸 Meme URL: {meme_url}\")\n",
" print(f\"�� Direct Link: {meme_url}\")\n",
"\n",
" # Display meme (in Colab, we can use HTML)\n",
" from IPython.display import Image, display\n",
" display(Image(url=meme_url))\n",
" else:\n",
" print(\"❌ Failed to generate meme. This might be due to:\")\n",
" print(\" - Browser automation issues\")\n",
" print(\" - Website changes\")\n",
" print(\" - Network connectivity\")\n",
" print(\" - API rate limits\")\n",
"\n",
" # Provide manual instructions\n",
" print(\"\\n💡 Manual Meme Creation Instructions:\")\n",
" print(\"1. Go to https://imgflip.com/memetemplates\")\n",
" print(\"2. Search for a template related to your query\")\n",
" print(\"3. Use one of the generated captions:\")\n",
" for i, caption in enumerate(caption_result['captions'], 1):\n",
" print(f\" Option {i}: Top='{caption.get('top', '')}', Bottom='{caption.get('bottom', '')}'\")\n",
"\n",
" except Exception as e:\n",
" print(f\"❌ Error during meme generation: {str(e)}\")\n",
" print(\"💡 Try using the manual instructions above\")\n",
" else:\n",
" print(\"⚠️ API key not configured for browser automation\")\n",
" print(\"💡 Using generated captions for manual meme creation:\")\n",
" for i, caption in enumerate(caption_result['captions'], 1):\n",
" print(f\" Option {i}: Top='{caption.get('top', '')}', Bottom='{caption.get('bottom', '')}'\")\n",
" else:\n",
" print(f\"❌ Error generating captions: {caption_result['error']}\")\n",
" else:\n",
" print(f\"❌ Error searching templates: {template_result['error']}\")\n",
"\n",
"else:\n",
" print(\"❌ No meme idea provided.\")\n",
"\n",
"print(\"\\n🧪 Sample Meme Ideas for Testing\")\n",
"sample_ideas = [\n",
" \"When you finally understand the code after 3 hours of debugging\",\n",
" \"Me trying to explain AI to my grandparents\",\n",
" \"The difference between what I plan to do vs what I actually do\",\n",
" \"When someone asks if I'm free this weekend\",\n",
" \"My brain at 3 AM thinking about that embarrassing thing from 5 years ago\"\n",
"]\n",
"\n",
"print(\"Try these sample ideas:\")\n",
"for i, idea in enumerate(sample_ideas, 1):\n",
" print(f\"{i}. {idea}\")\n",
"\n",
"print(\"\\n\" + \"=\"*50)\n",
"print(\"�� Powered by AI Meme Creator Agent | Built with PraisonAI\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,773 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "ghztCKohBcZP"
},
"source": [
"# 🎬 YouTube Content Integrity Analyzer"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hUmdUm4eBfCg"
},
"source": [
"This notebook uses PraisonAI to analyze YouTube video captions for harmful content (hate speech, misinformation, violence, fraud) and evaluates educational value, relevance, integrity, and clarity. The agent provides unbiased, category-based content quality assessments using only the transcript text."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TZylRAldFYwv"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/Qwen2.5_InstructionAgent.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ALWJRTXZBsKg"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "S4mLEe-RBrkq"
},
"outputs": [],
"source": [
"!pip install praisonaiagents openai youtube-transcript-api --quiet"
]
},
{
"cell_type": "markdown",
"source": [
"# Set up API KEY"
],
"metadata": {
"id": "AjLdy4NYD-AV"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZzOX1ASAB6S3"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent\n",
"import os\n",
"import json\n",
"\n",
"# Set your OpenAI API key\n",
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your api key\" # <-- Replace with your actual OpenAI API key"
]
},
{
"cell_type": "markdown",
"source": [
"# Get YouTube Transcript"
],
"metadata": {
"id": "DFJH4Jf0E4gU"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "pGY3CzCyCBtH"
},
"outputs": [],
"source": [
"from youtube_transcript_api import YouTubeTranscriptApi\n",
"\n",
"def get_youtube_transcript(video_id, languages=['en']):\n",
" try:\n",
" transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=languages)\n",
" text = \" \".join([entry['text'] for entry in transcript])\n",
" return text\n",
" except Exception as e:\n",
" return None"
]
},
{
"cell_type": "markdown",
"source": [
"# Prompts (role, goal, instructions)"
],
"metadata": {
"id": "x5vHRKqAE7az"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Trs-R1NRC4jv"
},
"outputs": [],
"source": [
"ROLE = \"\"\"\n",
"Act as a content integrity and quality analyst trained to evaluate YouTube video captions. You are an expert in content policy enforcement, linguistic analysis, and media integrity.\n",
"You specialize in detecting harmful content (e.g., hate speech, misinformation, fraud) and evaluating the clarity, educational value, and relevance of language in video captions, using only textual evidence and without assumptions about tone or intent.\n",
"\"\"\"\n",
"\n",
"GOAL = \"\"\"\n",
"Your task is to assess whether specific content categories are present based solely on the language in the transcript. Your judgments should be precise, unbiased, and strictly based on linguistic clues — do not rely on assumptions about video intent or tone.\n",
"\"\"\"\n",
"\n",
"INSTRUCTIONS = \"\"\"\n",
"You will receive a list of categories and a YouTube transcript. Analyze the transcript to determine the presence of the specified categories.\n",
"Only use these categories: [\"hatred\", \"misinformation\", \"violence\", \"fraud\", \"educational\", \"relevance\", \"integrity\", \"clarity\"].\n",
"Discard any other category. If none remain, return an error.\n",
"For each valid category, assign a score from 0 to 10 and provide a reason.\n",
"Return a JSON object with:\n",
" - categories: list of {name, score, connotation, reason}\n",
" - overall: {score, reason}\n",
" - error: \"\"\n",
" - content_summary: brief summary of the transcript\n",
"Start your response with { and end with }.\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"source": [
"# Main Agent Function"
],
"metadata": {
"id": "TYv88sNgE-h2"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "BsYXppH5C6VF"
},
"outputs": [],
"source": [
"def analyze_youtube_content(video_url, categories, custom_prompts=None):\n",
" # Extract video ID from URL\n",
" import re\n",
" match = re.search(r\"v=([A-Za-z0-9_-]+)\", video_url)\n",
" if not match:\n",
" return {\"error\": \"Invalid YouTube URL\"}\n",
" video_id = match.group(1)\n",
"\n",
" transcript = get_youtube_transcript(video_id)\n",
" if not transcript:\n",
" return {\"error\": \"Could not fetch transcript for this video.\"}\n",
"\n",
" # Prepare the prompt for the agent\n",
" prompt = f\"Categories: {categories}\\n\\nTranscript:\\n{transcript}\\n\"\n",
" if custom_prompts:\n",
" for cp in custom_prompts:\n",
" prompt += f\"\\nAdditional user prompt: {cp}\"\n",
"\n",
" agent = Agent(\n",
" role=ROLE,\n",
" goal=GOAL,\n",
" instructions=INSTRUCTIONS,\n",
" )\n",
" response = agent.start(prompt)\n",
" return response"
]
},
{
"cell_type": "markdown",
"source": [
"# Example Usage (with a valid video URL)"
],
"metadata": {
"id": "Po1Cy_fYFBYw"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000,
"referenced_widgets": [
"ec4ebabe2add44dfa8fc416e018b529e",
"6e52cd63a78f444882ac82fe8e392907"
]
},
"id": "SD7juBbZEP-h",
"outputId": "e5f15618-24d0-4524-d011-f9e9eefa87a2"
},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Act as a content integrity and quality analyst trained to evaluate YouTube video captions. You are an expert </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">in content policy enforcement, linguistic analysis, and media integrity.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">You specialize in detecting harmful content (e.g., hate speech, misinformation, fraud) and evaluating the </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">clarity, educational value, and relevance of language in video captions, using only textual evidence and </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">without assumptions about tone or intent.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mAct as a content integrity and quality analyst trained to evaluate YouTube video captions. You are an expert \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229min content policy enforcement, linguistic analysis, and media integrity.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mYou specialize in detecting harmful content (e.g., hate speech, misinformation, fraud) and evaluating the \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mclarity, educational value, and relevance of language in video captions, using only textual evidence and \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mwithout assumptions about tone or intent.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ec4ebabe2add44dfa8fc416e018b529e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 6.0s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 6.0s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Categories: ['hatred', 'educational', 'clarity'] <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Transcript: Translator: Joseph Geni Reviewer: Morton Bast So I want to start by offering you a free no-tech <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> life hack, and all it requires of you is this: that you change your posture for two minutes. But before I give <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> it away, I want to ask you to right now do a little audit of your body and what you're doing with your body. So <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> how many of you are sort of making yourselves smaller? Maybe you're hunching, crossing your legs, maybe <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> wrapping your ankles. Sometimes we hold onto our arms like this. Sometimes we spread out. (Laughter) I see you. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So I want you to pay attention to what you're doing right now. We're going to come back to that in a few <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> minutes, and I'm hoping that if you learn to tweak this a little bit, it could significantly change the way <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> your life unfolds. So, we're really fascinated with body language, and we're particularly interested in other <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> people's body language. You know, we're interested in, like, you know — (Laughter) — an awkward interaction, or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> a smile, or a contemptuous glance, or maybe a very awkward wink, or maybe even something like a handshake. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Narrator: Here they are arriving at Number 10. This lucky policeman gets to shake hands with the President of <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the United States. Here comes the Prime Minister -- No. (Laughter) (Applause) (Laughter) (Applause) Amy Cuddy: <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So a handshake, or the lack of a handshake, can have us talking for weeks and weeks and weeks. Even the BBC and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> The New York Times. So obviously when we think about nonverbal behavior, or body language -- but we call it <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> nonverbals as social scientists -- it's language, so we think about communication. When we think about <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> communication, we think about interactions. So what is your body language communicating to me? What's mine <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> communicating to you? And there's a lot of reason to believe that this is a valid way to look at this. So <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> social scientists have spent a lot of time looking at the effects of our body language, or other people's body <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> language, on judgments. And we make sweeping judgments and inferences from body language. And those judgments <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> can predict really meaningful life outcomes like who we hire or promote, who we ask out on a date. For example, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Nalini Ambady, a researcher at Tufts University, shows that when people watch 30-second soundless clips of real <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> physician-patient interactions, their judgments of the physician's niceness predict whether or not that <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> physician will be sued. So it doesn't have to do so much with whether or not that physician was incompetent, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> but do we like that person and how they interacted? Even more dramatic, Alex Todorov at Princeton has shown us <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> that judgments of political candidates' faces in just one second predict 70 percent of U.S. Senate and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> gubernatorial race outcomes, and even, let's go digital, emoticons used well in online negotiations can lead <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> you to claim more value from that negotiation. If you use them poorly, bad idea. Right? So when we think of <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> nonverbals, we think of how we judge others, how they judge us and what the outcomes are. We tend to forget, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> though, the other audience that's influenced by our nonverbals, and that's ourselves. We are also influenced by <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> our nonverbals, our thoughts and our feelings and our physiology. So what nonverbals am I talking about? I'm a <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> social psychologist. I study prejudice, and I teach at a competitive business school, so it was inevitable that <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> I would become interested in power dynamics. I became especially interested in nonverbal expressions of power <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> and dominance. And what are nonverbal expressions of power and dominance? Well, this is what they are. So in <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the animal kingdom, they are about expanding. So you make yourself big, you stretch out, you take up space, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> you're basically opening up. It's about opening up. And this is true across the animal kingdom. It's not just <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> limited to primates. And humans do the same thing. (Laughter) So they do this both when they have power sort of <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> chronically, and also when they're feeling powerful in the moment. And this one is especially interesting <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> because it really shows us how universal and old these expressions of power are. This expression, which is <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> known as pride, Jessica Tracy has studied. She shows that people who are born with sight and people who are <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> congenitally blind do this when they win at a physical competition. So when they cross the finish line and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> they've won, it doesn't matter if they've never seen anyone do it. They do this. So the arms up in the V, the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> chin is slightly lifted. What do we do when we feel powerless? We do exactly the opposite. We close up. We wrap <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> ourselves up. We make ourselves small. We don't want to bump into the person next to us. So again, both animals <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> and humans do the same thing. And this is what happens when you put together high and low power. So what we <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> tend to do when it comes to power is that we complement the other's nonverbals. So if someone is being really <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> powerful with us, we tend to make ourselves smaller. We don't mirror them. We do the opposite of them. So I'm <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> watching this behavior in the classroom, and what do I notice? I notice that MBA students really exhibit the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> full range of power nonverbals. So you have people who are like caricatures of alphas, really coming into the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> room, they get right into the middle of the room before class even starts, like they really want to occupy <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> space. When they sit down, they're sort of spread out. They raise their hands like this. You have other people <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> who are virtually collapsing when they come in. As soon they come in, you see it. You see it on their faces and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> their bodies, and they sit in their chair and they make themselves tiny, and they go like this when they raise <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> their hand. I notice a couple of things about this. One, you're not going to be surprised. It seems to be <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> related to gender. So women are much more likely to do this kind of thing than men. Women feel chronically less <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> powerful than men, so this is not surprising. But the other thing I noticed is that it also seemed to be <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> related to the extent to which the students were participating, and how well they were participating. And this <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> is really important in the MBA classroom, because participation counts for half the grade. So business schools <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> have been struggling with this gender grade gap. You get these equally qualified women and men coming in and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> then you get these differences in grades, and it seems to be partly attributable to participation. So I started <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> to wonder, you know, okay, so you have these people coming in like this, and they're participating. Is it <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> possible that we could get people to fake it and would it lead them to participate more? So my main <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> collaborator Dana Carney, who's at Berkeley, and I really wanted to know, can you fake it till you make it? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Like, can you do this just for a little while and actually experience a behavioral outcome that makes you seem <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> more powerful? So we know that our nonverbals govern how other people think and feel about us. There's a lot of <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> evidence. But our question really was, do our nonverbals govern how we think and feel about ourselves? There's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> some evidence that they do. So, for example, we smile when we feel happy, but also, when we're forced to smile <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> by holding a pen in our teeth like this, it makes us feel happy. So it goes both ways. When it comes to power, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> it also goes both ways. So when you feel powerful, you're more likely to do this, but it's also possible that <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> when you pretend to be powerful, you are more likely to actually feel powerful. So the second question really <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> was, you know, so we know that our minds change our bodies, but is it also true that our bodies change our <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> minds? And when I say minds, in the case of the powerful, what am I talking about? So I'm talking about <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> thoughts and feelings and the sort of physiological things that make up our thoughts and feelings, and in my <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> case, that's hormones. I look at hormones. So what do the minds of the powerful versus the powerless look like? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So powerful people tend to be, not surprisingly, more assertive and more confident, more optimistic. They <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> actually feel they're going to win even at games of chance. They also tend to be able to think more abstractly. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So there are a lot of differences. They take more risks. There are a lot of differences between powerful and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> powerless people. Physiologically, there also are differences on two key hormones: testosterone, which is the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> dominance hormone, and cortisol, which is the stress hormone. So what we find is that high-power alpha males in <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> primate hierarchies have high testosterone and low cortisol, and powerful and effective leaders also have high <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> testosterone and low cortisol. So what does that mean? When you think about power, people tended to think only <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> about testosterone, because that was about dominance. But really, power is also about how you react to stress. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So do you want the high-power leader that's dominant, high on testosterone, but really stress reactive? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Probably not, right? You want the person who's powerful and assertive and dominant, but not very stress <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> reactive, the person who's laid back. So we know that in primate hierarchies, if an alpha needs to take over, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> if an individual needs to take over an alpha role sort of suddenly, within a few days, that individual's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> testosterone has gone up significantly and his cortisol has dropped significantly. So we have this evidence, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> both that the body can shape the mind, at least at the facial level, and also that role changes can shape the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> mind. So what happens, okay, you take a role change, what happens if you do that at a really minimal level, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> like this tiny manipulation, this tiny intervention? \"For two minutes,\" you say, \"I want you to stand like <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> this, and it's going to make you feel more powerful.\" So this is what we did. We decided to bring people into <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the lab and run a little experiment, and these people adopted, for two minutes, either high-power poses or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> low-power poses, and I'm just going to show you five of the poses, although they took on only two. So here's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> one. A couple more. This one has been dubbed the \"Wonder Woman\" by the media. Here are a couple more. So you <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> can be standing or you can be sitting. And here are the low-power poses. So you're folding up, you're making <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> yourself small. This one is very low-power. When you're touching your neck, you're really protecting yourself. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So this is what happens. They come in, they spit into a vial, for two minutes, we say, \"You need to do this or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> this.\" They don't look at pictures of the poses. We don't want to prime them with a concept of power. We want <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> them to be feeling power. So two minutes they do this. We then ask them, \"How powerful do you feel?\" on a <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> series of items, and then we give them an opportunity to gamble, and then we take another saliva sample. That's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> it. That's the whole experiment. So this is what we find. Risk tolerance, which is the gambling, we find that <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> when you are in the high-power pose condition, 86 percent of you will gamble. When you're in the low-power pose <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> condition, only 60 percent, and that's a whopping significant difference. Here's what we find on testosterone. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> From their baseline when they come in, high-power people experience about a 20-percent increase, and low-power <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> people experience about a 10-percent decrease. So again, two minutes, and you get these changes. Here's what <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> you get on cortisol. High-power people experience about a 25-percent decrease, and the low-power people <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> experience about a 15-percent increase. So two minutes lead to these hormonal changes that configure your brain <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> to basically be either assertive, confident and comfortable, or really stress-reactive, and feeling sort of <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> shut down. And we've all had the feeling, right? So it seems that our nonverbals do govern how we think and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> feel about ourselves, so it's not just others, but it's also ourselves. Also, our bodies change our minds. But <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the next question, of course, is, can power posing for a few minutes really change your life in meaningful <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> ways? This is in the lab, it's this little task, it's just a couple of minutes. Where can you actually apply <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> this? Which we cared about, of course. And so we think where you want to use this is evaluative situations, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> like social threat situations. Where are you being evaluated, either by your friends? For teenagers, it's at <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the lunchroom table. For some people it's speaking at a school board meeting. It might be giving a pitch or <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> giving a talk like this or doing a job interview. We decided that the one that most people could relate to <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> because most people had been through, was the job interview. So we published these findings, and the media are <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> all over it, and they say, Okay, so this is what you do when you go in for the job interview, right? (Laughter) <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> You know, so we were of course horrified, and said, Oh my God, no, that's not what we meant at all. For <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> numerous reasons, no, don't do that. Again, this is not about you talking to other people. It's you talking to <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> yourself. What do you do before you go into a job interview? You do this. You're sitting down. You're looking <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> at your iPhone -- or your Android, not trying to leave anyone out. You're looking at your notes, you're <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> hunching up, making yourself small, when really what you should be doing maybe is this, like, in the bathroom, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> right? Do that. Find two minutes. So that's what we want to test. Okay? So we bring people into a lab, and they <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> do either high- or low-power poses again, they go through a very stressful job interview. It's five minutes <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> long. They are being recorded. They're being judged also, and the judges are trained to give no nonverbal <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> feedback, so they look like this. Imagine this is the person interviewing you. So for five minutes, nothing, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> and this is worse than being heckled. People hate this. It's what Marianne LaFrance calls \"standing in social <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> quicksand.\" So this really spikes your cortisol. So this is the job interview we put them through, because we <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> really wanted to see what happened. We then have these coders look at these tapes, four of them. They're blind <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> to the hypothesis. They're blind to the conditions. They have no idea who's been posing in what pose, and they <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> end up looking at these sets of tapes, and they say, \"We want to hire these people,\" all the high-power posers. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> \"We don't want to hire these people. We also evaluate these people much more positively overall.\" But what's <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> driving it? It's not about the content of the speech. It's about the presence that they're bringing to the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> speech. Because we rate them on all these variables related to competence, like, how well-structured is the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> speech? How good is it? What are their qualifications? No effect on those things. This is what's affected. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> These kinds of things. People are bringing their true selves, basically. They're bringing themselves. They <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> bring their ideas, but as themselves, with no, you know, residue over them. So this is what's driving the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> effect, or mediating the effect. So when I tell people about this, that our bodies change our minds and our <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> minds can change our behavior, and our behavior can change our outcomes, they say to me, \"It feels fake.\" <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Right? So I said, fake it till you make it. It's not me. I don't want to get there and then still feel like a <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> fraud. I don't want to feel like an impostor. I don't want to get there only to feel like I'm not supposed to <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> be here. And that really resonated with me, because I want to tell you a little story about being an impostor <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> and feeling like I'm not supposed to be here. When I was 19, I was in a really bad car accident. I was thrown <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> out of a car, rolled several times. I was thrown from the car. And I woke up in a head injury rehab ward, and I <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> had been withdrawn from college, and I learned that my IQ had dropped by two standard deviations, which was <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> very traumatic. I knew my IQ because I had identified with being smart, and I had been called gifted as a <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> child. So I'm taken out of college, I keep trying to go back. They say, \"You're not going to finish college. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Just, you know, there are other things for you to do, but that's not going to work out for you.\" So I really <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> struggled with this, and I have to say, having your identity taken from you, your core identity, and for me it <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> was being smart, having that taken from you, there's nothing that leaves you feeling more powerless than that. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> So I felt entirely powerless. I worked and worked, and I got lucky, and worked, and got lucky, and worked. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Eventually I graduated from college. It took me four years longer than my peers, and I convinced someone, my <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> angel advisor, Susan Fiske, to take me on, and so I ended up at Princeton, and I was like, I am not supposed to <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> be here. I am an impostor. And the night before my first-year talk, and the first-year talk at Princeton is a <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> 20-minute talk to 20 people. That's it. I was so afraid of being found out the next day that I called her and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> said, \"I'm quitting.\" She was like, \"You are not quitting, because I took a gamble on you, and you're staying. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> You're going to stay, and this is what you're going to do. You are going to fake it. You're going to do every <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> talk that you ever get asked to do. You're just going to do it and do it and do it, even if you're terrified <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> and just paralyzed and having an out-of-body experience, until you have this moment where you say, 'Oh my gosh, <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> I'm doing it. Like, I have become this. I am actually doing this.'\" So that's what I did. Five years in grad <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> school, a few years, you know, I'm at Northwestern, I moved to Harvard, I'm at Harvard, I'm not really thinking <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> about it anymore, but for a long time I had been thinking, \"Not supposed to be here.\" So at the end of my first <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> year at Harvard, a student who had not talked in class the entire semester, who I had said, \"Look, you've gotta <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> participate or else you're going to fail,\" came into my office. I really didn't know her at all. She came in <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> totally defeated, and she said, \"I'm not supposed to be here.\" And that was the moment for me. Because two <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> things happened. One was that I realized, oh my gosh, I don't feel like that anymore. I don't feel that <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> anymore, but she does, and I get that feeling. And the second was, she is supposed to be here! Like, she can <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> fake it, she can become it. So I was like, \"Yes, you are! You are supposed to be here! And tomorrow you're <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> going to fake it, you're going to make yourself powerful, and, you know -- (Applause) And you're going to go <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> into the classroom, and you are going to give the best comment ever.\" You know? And she gave the best comment <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> ever, and people turned around and were like, oh my God, I didn't even notice her sitting there. (Laughter) She <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> comes back to me months later, and I realized that she had not just faked it till she made it, she had actually <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> faked it till she became it. So she had changed. And so I want to say to you, don't fake it till you make it. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Fake it till you become it. Do it enough until you actually become it and internalize. The last thing I'm going <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> to leave you with is this. Tiny tweaks can lead to big changes. So, this is two minutes. Two minutes, two <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> minutes, two minutes. Before you go into the next stressful evaluative situation, for two minutes, try doing <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> this, in the elevator, in a bathroom stall, at your desk behind closed doors. That's what you want to do. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Configure your brain to cope the best in that situation. Get your testosterone up. Get your cortisol down. <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> Don't leave that situation feeling like, oh, I didn't show them who I am. Leave that situation feeling like, I <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> really feel like I got to say who I am and show who I am. So I want to ask you first, you know, both to try <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> power posing, and also I want to ask you to share the science, because this is simple. I don't have ego <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> involved in this. (Laughter) Give it away. Share it with people, because the people who can use it the most are <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> the ones with no resources and no technology and no status and no power. Give it to them bec... <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m Categories: ['hatred', 'educational', 'clarity'] \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Transcript: Translator: Joseph Geni Reviewer: Morton Bast So I want to start by offering you a free no-tech \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m life hack, and all it requires of you is this: that you change your posture for two minutes. But before I give \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m it away, I want to ask you to right now do a little audit of your body and what you're doing with your body. So \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m how many of you are sort of making yourselves smaller? Maybe you're hunching, crossing your legs, maybe \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m wrapping your ankles. Sometimes we hold onto our arms like this. Sometimes we spread out. (Laughter) I see you. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So I want you to pay attention to what you're doing right now. We're going to come back to that in a few \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m minutes, and I'm hoping that if you learn to tweak this a little bit, it could significantly change the way \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m your life unfolds. So, we're really fascinated with body language, and we're particularly interested in other \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m people's body language. You know, we're interested in, like, you know — (Laughter) — an awkward interaction, or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m a smile, or a contemptuous glance, or maybe a very awkward wink, or maybe even something like a handshake. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Narrator: Here they are arriving at Number 10. This lucky policeman gets to shake hands with the President of \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the United States. Here comes the Prime Minister -- No. (Laughter) (Applause) (Laughter) (Applause) Amy Cuddy: \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So a handshake, or the lack of a handshake, can have us talking for weeks and weeks and weeks. Even the BBC and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m The New York Times. So obviously when we think about nonverbal behavior, or body language -- but we call it \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m nonverbals as social scientists -- it's language, so we think about communication. When we think about \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m communication, we think about interactions. So what is your body language communicating to me? What's mine \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m communicating to you? And there's a lot of reason to believe that this is a valid way to look at this. So \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m social scientists have spent a lot of time looking at the effects of our body language, or other people's body \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m language, on judgments. And we make sweeping judgments and inferences from body language. And those judgments \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m can predict really meaningful life outcomes like who we hire or promote, who we ask out on a date. For example, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Nalini Ambady, a researcher at Tufts University, shows that when people watch 30-second soundless clips of real \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m physician-patient interactions, their judgments of the physician's niceness predict whether or not that \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m physician will be sued. So it doesn't have to do so much with whether or not that physician was incompetent, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m but do we like that person and how they interacted? Even more dramatic, Alex Todorov at Princeton has shown us \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m that judgments of political candidates' faces in just one second predict 70 percent of U.S. Senate and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m gubernatorial race outcomes, and even, let's go digital, emoticons used well in online negotiations can lead \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m you to claim more value from that negotiation. If you use them poorly, bad idea. Right? So when we think of \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m nonverbals, we think of how we judge others, how they judge us and what the outcomes are. We tend to forget, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m though, the other audience that's influenced by our nonverbals, and that's ourselves. We are also influenced by \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m our nonverbals, our thoughts and our feelings and our physiology. So what nonverbals am I talking about? I'm a \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m social psychologist. I study prejudice, and I teach at a competitive business school, so it was inevitable that \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m I would become interested in power dynamics. I became especially interested in nonverbal expressions of power \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m and dominance. And what are nonverbal expressions of power and dominance? Well, this is what they are. So in \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the animal kingdom, they are about expanding. So you make yourself big, you stretch out, you take up space, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m you're basically opening up. It's about opening up. And this is true across the animal kingdom. It's not just \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m limited to primates. And humans do the same thing. (Laughter) So they do this both when they have power sort of \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m chronically, and also when they're feeling powerful in the moment. And this one is especially interesting \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m because it really shows us how universal and old these expressions of power are. This expression, which is \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m known as pride, Jessica Tracy has studied. She shows that people who are born with sight and people who are \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m congenitally blind do this when they win at a physical competition. So when they cross the finish line and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m they've won, it doesn't matter if they've never seen anyone do it. They do this. So the arms up in the V, the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m chin is slightly lifted. What do we do when we feel powerless? We do exactly the opposite. We close up. We wrap \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m ourselves up. We make ourselves small. We don't want to bump into the person next to us. So again, both animals \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m and humans do the same thing. And this is what happens when you put together high and low power. So what we \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m tend to do when it comes to power is that we complement the other's nonverbals. So if someone is being really \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m powerful with us, we tend to make ourselves smaller. We don't mirror them. We do the opposite of them. So I'm \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m watching this behavior in the classroom, and what do I notice? I notice that MBA students really exhibit the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m full range of power nonverbals. So you have people who are like caricatures of alphas, really coming into the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m room, they get right into the middle of the room before class even starts, like they really want to occupy \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m space. When they sit down, they're sort of spread out. They raise their hands like this. You have other people \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m who are virtually collapsing when they come in. As soon they come in, you see it. You see it on their faces and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m their bodies, and they sit in their chair and they make themselves tiny, and they go like this when they raise \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m their hand. I notice a couple of things about this. One, you're not going to be surprised. It seems to be \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m related to gender. So women are much more likely to do this kind of thing than men. Women feel chronically less \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m powerful than men, so this is not surprising. But the other thing I noticed is that it also seemed to be \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m related to the extent to which the students were participating, and how well they were participating. And this \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m is really important in the MBA classroom, because participation counts for half the grade. So business schools \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m have been struggling with this gender grade gap. You get these equally qualified women and men coming in and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m then you get these differences in grades, and it seems to be partly attributable to participation. So I started \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m to wonder, you know, okay, so you have these people coming in like this, and they're participating. Is it \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m possible that we could get people to fake it and would it lead them to participate more? So my main \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m collaborator Dana Carney, who's at Berkeley, and I really wanted to know, can you fake it till you make it? \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Like, can you do this just for a little while and actually experience a behavioral outcome that makes you seem \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m more powerful? So we know that our nonverbals govern how other people think and feel about us. There's a lot of \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m evidence. But our question really was, do our nonverbals govern how we think and feel about ourselves? There's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m some evidence that they do. So, for example, we smile when we feel happy, but also, when we're forced to smile \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m by holding a pen in our teeth like this, it makes us feel happy. So it goes both ways. When it comes to power, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m it also goes both ways. So when you feel powerful, you're more likely to do this, but it's also possible that \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m when you pretend to be powerful, you are more likely to actually feel powerful. So the second question really \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m was, you know, so we know that our minds change our bodies, but is it also true that our bodies change our \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m minds? And when I say minds, in the case of the powerful, what am I talking about? So I'm talking about \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m thoughts and feelings and the sort of physiological things that make up our thoughts and feelings, and in my \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m case, that's hormones. I look at hormones. So what do the minds of the powerful versus the powerless look like? \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So powerful people tend to be, not surprisingly, more assertive and more confident, more optimistic. They \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m actually feel they're going to win even at games of chance. They also tend to be able to think more abstractly. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So there are a lot of differences. They take more risks. There are a lot of differences between powerful and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m powerless people. Physiologically, there also are differences on two key hormones: testosterone, which is the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m dominance hormone, and cortisol, which is the stress hormone. So what we find is that high-power alpha males in \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m primate hierarchies have high testosterone and low cortisol, and powerful and effective leaders also have high \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m testosterone and low cortisol. So what does that mean? When you think about power, people tended to think only \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m about testosterone, because that was about dominance. But really, power is also about how you react to stress. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So do you want the high-power leader that's dominant, high on testosterone, but really stress reactive? \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Probably not, right? You want the person who's powerful and assertive and dominant, but not very stress \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m reactive, the person who's laid back. So we know that in primate hierarchies, if an alpha needs to take over, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m if an individual needs to take over an alpha role sort of suddenly, within a few days, that individual's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m testosterone has gone up significantly and his cortisol has dropped significantly. So we have this evidence, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m both that the body can shape the mind, at least at the facial level, and also that role changes can shape the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m mind. So what happens, okay, you take a role change, what happens if you do that at a really minimal level, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m like this tiny manipulation, this tiny intervention? \"For two minutes,\" you say, \"I want you to stand like \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m this, and it's going to make you feel more powerful.\" So this is what we did. We decided to bring people into \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the lab and run a little experiment, and these people adopted, for two minutes, either high-power poses or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m low-power poses, and I'm just going to show you five of the poses, although they took on only two. So here's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m one. A couple more. This one has been dubbed the \"Wonder Woman\" by the media. Here are a couple more. So you \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m can be standing or you can be sitting. And here are the low-power poses. So you're folding up, you're making \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m yourself small. This one is very low-power. When you're touching your neck, you're really protecting yourself. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So this is what happens. They come in, they spit into a vial, for two minutes, we say, \"You need to do this or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m this.\" They don't look at pictures of the poses. We don't want to prime them with a concept of power. We want \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m them to be feeling power. So two minutes they do this. We then ask them, \"How powerful do you feel?\" on a \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m series of items, and then we give them an opportunity to gamble, and then we take another saliva sample. That's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m it. That's the whole experiment. So this is what we find. Risk tolerance, which is the gambling, we find that \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m when you are in the high-power pose condition, 86 percent of you will gamble. When you're in the low-power pose \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m condition, only 60 percent, and that's a whopping significant difference. Here's what we find on testosterone. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m From their baseline when they come in, high-power people experience about a 20-percent increase, and low-power \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m people experience about a 10-percent decrease. So again, two minutes, and you get these changes. Here's what \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m you get on cortisol. High-power people experience about a 25-percent decrease, and the low-power people \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m experience about a 15-percent increase. So two minutes lead to these hormonal changes that configure your brain \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m to basically be either assertive, confident and comfortable, or really stress-reactive, and feeling sort of \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m shut down. And we've all had the feeling, right? So it seems that our nonverbals do govern how we think and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m feel about ourselves, so it's not just others, but it's also ourselves. Also, our bodies change our minds. But \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the next question, of course, is, can power posing for a few minutes really change your life in meaningful \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m ways? This is in the lab, it's this little task, it's just a couple of minutes. Where can you actually apply \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m this? Which we cared about, of course. And so we think where you want to use this is evaluative situations, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m like social threat situations. Where are you being evaluated, either by your friends? For teenagers, it's at \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the lunchroom table. For some people it's speaking at a school board meeting. It might be giving a pitch or \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m giving a talk like this or doing a job interview. We decided that the one that most people could relate to \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m because most people had been through, was the job interview. So we published these findings, and the media are \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m all over it, and they say, Okay, so this is what you do when you go in for the job interview, right? (Laughter) \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m You know, so we were of course horrified, and said, Oh my God, no, that's not what we meant at all. For \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m numerous reasons, no, don't do that. Again, this is not about you talking to other people. It's you talking to \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m yourself. What do you do before you go into a job interview? You do this. You're sitting down. You're looking \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m at your iPhone -- or your Android, not trying to leave anyone out. You're looking at your notes, you're \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m hunching up, making yourself small, when really what you should be doing maybe is this, like, in the bathroom, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m right? Do that. Find two minutes. So that's what we want to test. Okay? So we bring people into a lab, and they \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m do either high- or low-power poses again, they go through a very stressful job interview. It's five minutes \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m long. They are being recorded. They're being judged also, and the judges are trained to give no nonverbal \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m feedback, so they look like this. Imagine this is the person interviewing you. So for five minutes, nothing, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m and this is worse than being heckled. People hate this. It's what Marianne LaFrance calls \"standing in social \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m quicksand.\" So this really spikes your cortisol. So this is the job interview we put them through, because we \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m really wanted to see what happened. We then have these coders look at these tapes, four of them. They're blind \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m to the hypothesis. They're blind to the conditions. They have no idea who's been posing in what pose, and they \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m end up looking at these sets of tapes, and they say, \"We want to hire these people,\" all the high-power posers. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \"We don't want to hire these people. We also evaluate these people much more positively overall.\" But what's \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m driving it? It's not about the content of the speech. It's about the presence that they're bringing to the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m speech. Because we rate them on all these variables related to competence, like, how well-structured is the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m speech? How good is it? What are their qualifications? No effect on those things. This is what's affected. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m These kinds of things. People are bringing their true selves, basically. They're bringing themselves. They \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m bring their ideas, but as themselves, with no, you know, residue over them. So this is what's driving the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m effect, or mediating the effect. So when I tell people about this, that our bodies change our minds and our \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m minds can change our behavior, and our behavior can change our outcomes, they say to me, \"It feels fake.\" \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Right? So I said, fake it till you make it. It's not me. I don't want to get there and then still feel like a \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m fraud. I don't want to feel like an impostor. I don't want to get there only to feel like I'm not supposed to \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m be here. And that really resonated with me, because I want to tell you a little story about being an impostor \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m and feeling like I'm not supposed to be here. When I was 19, I was in a really bad car accident. I was thrown \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m out of a car, rolled several times. I was thrown from the car. And I woke up in a head injury rehab ward, and I \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m had been withdrawn from college, and I learned that my IQ had dropped by two standard deviations, which was \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m very traumatic. I knew my IQ because I had identified with being smart, and I had been called gifted as a \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m child. So I'm taken out of college, I keep trying to go back. They say, \"You're not going to finish college. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Just, you know, there are other things for you to do, but that's not going to work out for you.\" So I really \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m struggled with this, and I have to say, having your identity taken from you, your core identity, and for me it \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m was being smart, having that taken from you, there's nothing that leaves you feeling more powerless than that. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m So I felt entirely powerless. I worked and worked, and I got lucky, and worked, and got lucky, and worked. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Eventually I graduated from college. It took me four years longer than my peers, and I convinced someone, my \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m angel advisor, Susan Fiske, to take me on, and so I ended up at Princeton, and I was like, I am not supposed to \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m be here. I am an impostor. And the night before my first-year talk, and the first-year talk at Princeton is a \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m 20-minute talk to 20 people. That's it. I was so afraid of being found out the next day that I called her and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m said, \"I'm quitting.\" She was like, \"You are not quitting, because I took a gamble on you, and you're staying. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m You're going to stay, and this is what you're going to do. You are going to fake it. You're going to do every \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m talk that you ever get asked to do. You're just going to do it and do it and do it, even if you're terrified \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m and just paralyzed and having an out-of-body experience, until you have this moment where you say, 'Oh my gosh, \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m I'm doing it. Like, I have become this. I am actually doing this.'\" So that's what I did. Five years in grad \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m school, a few years, you know, I'm at Northwestern, I moved to Harvard, I'm at Harvard, I'm not really thinking \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m about it anymore, but for a long time I had been thinking, \"Not supposed to be here.\" So at the end of my first \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m year at Harvard, a student who had not talked in class the entire semester, who I had said, \"Look, you've gotta \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m participate or else you're going to fail,\" came into my office. I really didn't know her at all. She came in \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m totally defeated, and she said, \"I'm not supposed to be here.\" And that was the moment for me. Because two \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m things happened. One was that I realized, oh my gosh, I don't feel like that anymore. I don't feel that \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m anymore, but she does, and I get that feeling. And the second was, she is supposed to be here! Like, she can \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m fake it, she can become it. So I was like, \"Yes, you are! You are supposed to be here! And tomorrow you're \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m going to fake it, you're going to make yourself powerful, and, you know -- (Applause) And you're going to go \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m into the classroom, and you are going to give the best comment ever.\" You know? And she gave the best comment \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m ever, and people turned around and were like, oh my God, I didn't even notice her sitting there. (Laughter) She \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m comes back to me months later, and I realized that she had not just faked it till she made it, she had actually \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m faked it till she became it. So she had changed. And so I want to say to you, don't fake it till you make it. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Fake it till you become it. Do it enough until you actually become it and internalize. The last thing I'm going \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m to leave you with is this. Tiny tweaks can lead to big changes. So, this is two minutes. Two minutes, two \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m minutes, two minutes. Before you go into the next stressful evaluative situation, for two minutes, try doing \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m this, in the elevator, in a bathroom stall, at your desk behind closed doors. That's what you want to do. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Configure your brain to cope the best in that situation. Get your testosterone up. Get your cortisol down. \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m Don't leave that situation feeling like, oh, I didn't show them who I am. Leave that situation feeling like, I \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m really feel like I got to say who I am and show who I am. So I want to ask you first, you know, both to try \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m power posing, and also I want to ask you to share the science, because this is simple. I don't have ego \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m involved in this. (Laughter) Give it away. Share it with people, because the people who can use it the most are \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m the ones with no resources and no technology and no status and no power. Give it to them bec... \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> { \"categories\": [ { \"name\": \"educational\", \"score\": 9, \"connotation\": \"positive\", \"reason\": \"The transcript <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> provides a detailed explanation of body language and its effects on personal and professional outcomes. It <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> includes scientific studies and practical advice, making it highly educational.\" }, { \"name\": \"clarity\", <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> \"score\": 8, \"connotation\": \"positive\", \"reason\": \"The transcript is clear in its explanation of concepts <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> related to body language and power dynamics. It uses examples and studies to illustrate points, although the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> length and detail might be overwhelming for some.\" } ], \"overall\": { \"score\": 8.5, \"reason\": \"The transcript is <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> highly educational and clear, providing valuable insights into body language and its impact on personal <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> empowerment. It effectively communicates scientific findings and practical applications.\" }, \"error\": \"\", <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> \"content_summary\": \"The transcript discusses the impact of body language on personal empowerment and <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> professional success. It explains scientific studies on nonverbal communication, power dynamics, and the <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> concept of 'faking it till you become it.' Practical advice is given on how to use body language to improve <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> self-confidence and outcomes in evaluative situations.\" } <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m { \"categories\": [ { \"name\": \"educational\", \"score\": 9, \"connotation\": \"positive\", \"reason\": \"The transcript \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m provides a detailed explanation of body language and its effects on personal and professional outcomes. It \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m includes scientific studies and practical advice, making it highly educational.\" }, { \"name\": \"clarity\", \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \"score\": 8, \"connotation\": \"positive\", \"reason\": \"The transcript is clear in its explanation of concepts \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m related to body language and power dynamics. It uses examples and studies to illustrate points, although the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m length and detail might be overwhelming for some.\" } ], \"overall\": { \"score\": 8.5, \"reason\": \"The transcript is \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m highly educational and clear, providing valuable insights into body language and its impact on personal \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m empowerment. It effectively communicates scientific findings and practical applications.\" }, \"error\": \"\", \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m \"content_summary\": \"The transcript discusses the impact of body language on personal empowerment and \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m professional success. It explains scientific studies on nonverbal communication, power dynamics, and the \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m concept of 'faking it till you become it.' Practical advice is given on how to use body language to improve \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m self-confidence and outcomes in evaluative situations.\" } \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"categories\": [\n",
" {\n",
" \"name\": \"educational\",\n",
" \"score\": 9,\n",
" \"connotation\": \"positive\",\n",
" \"reason\": \"The transcript provides a detailed explanation of body language and its effects on personal and professional outcomes. It includes scientific studies and practical advice, making it highly educational.\"\n",
" },\n",
" {\n",
" \"name\": \"clarity\",\n",
" \"score\": 8,\n",
" \"connotation\": \"positive\",\n",
" \"reason\": \"The transcript is clear in its explanation of concepts related to body language and power dynamics. It uses examples and studies to illustrate points, although the length and detail might be overwhelming for some.\"\n",
" }\n",
" ],\n",
" \"overall\": {\n",
" \"score\": 8.5,\n",
" \"reason\": \"The transcript is highly educational and clear, providing valuable insights into body language and its impact on personal empowerment. It effectively communicates scientific findings and practical applications.\"\n",
" },\n",
" \"error\": \"\",\n",
" \"content_summary\": \"The transcript discusses the impact of body language on personal empowerment and professional success. It explains scientific studies on nonverbal communication, power dynamics, and the concept of 'faking it till you become it.' Practical advice is given on how to use body language to improve self-confidence and outcomes in evaluative situations.\"\n",
"}\n"
]
}
],
"source": [
"# Example usage with a valid video URL (TED Talk with English transcript)\n",
"video_url = \"https://www.youtube.com/watch?v=Ks-_Mh1QhMc\" # TED: Your body language may shape who you are\n",
"categories = [\"hatred\", \"educational\", \"clarity\"]\n",
"result = analyze_youtube_content(video_url, categories)\n",
"print(result)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,618 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "wd6157NQTqfU",
"metadata": {
"id": "wd6157NQTqfU"
},
"source": [
"# 🔍 NLP + ASR Agent (Official BERT Large + Whisper Large V3)\n",
"This notebook runs an agent with:\n",
"- 🤖 **BERT Large Cased** for text classification or embedding\n",
"- 🎙️ **Whisper Large V3** for audio transcription\n",
"\n",
"✅ Compatible with Google Colab Free (if Whisper uses fp16 and BERT is used efficiently)\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "TD8pkIV8er1I",
"metadata": {
"id": "TD8pkIV8er1I"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/bert_whisper_agent.ipynb)\n"
]
},
{
"cell_type": "markdown",
"id": "xQ1v5o47ejyu",
"metadata": {
"id": "xQ1v5o47ejyu"
},
"source": [
"# Install required libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8yb2sVk7TqfX",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "8yb2sVk7TqfX",
"outputId": "13896ab6-f048-4850-d601-68435d0e0e8f"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m363.4/363.4 MB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m30.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.6/24.6 MB\u001b[0m \u001b[31m18.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m883.7/883.7 kB\u001b[0m \u001b[31m23.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m664.8/664.8 MB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.5/211.5 MB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.3/56.3 MB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m127.9/127.9 MB\u001b[0m \u001b[31m7.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m207.5/207.5 MB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.1/21.1 MB\u001b[0m \u001b[31m26.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"\n",
"!pip install -q transformers torchaudio accelerate torch"
]
},
{
"cell_type": "markdown",
"id": "-YcKPAAhelsQ",
"metadata": {
"id": "-YcKPAAhelsQ"
},
"source": [
"# Load BERT Large for text analysis"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "Ppdx98tJTqfY",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 177,
"referenced_widgets": [
"ef64ca729ce24516b53f811439c922de",
"d86e086af653488bb3bb4daa1bc420fa",
"18c04cece0c54cbb87cbb2391cc7150c",
"62ad256a8769475daf4e8aacbdb10379",
"0b1a3559484845c68d11951e9016a359",
"293bdc33534349088e329d186645f643",
"5da3f8d139a141a7b5ae2b87b8ab3a46",
"083de2b5fc4843f99e778e8aa453c1b8",
"41d9cffa0ec94a0f99c6a3e27dc97017",
"bbc1dcfe4d0c4cef8574d6a09db2a32a",
"ca9a87cbd99d491194edc4572ef7dc80",
"7ea44cea34114e6784ebc339d78a8cb0",
"0e0b43792f6e40aba2db124c465eb112",
"2c36bed80a05477b85c7fdd07824a0d5",
"0489bdfa20794a36a2757e75930fdeca",
"9833eb7529f1470a95c67134c198ed70",
"5986111ae7a34d9aa66278a6c9925960",
"408c73a369194ca2b6585dba212727c2",
"aec9f86597c842e388bfc7e495b702ab",
"2b5a6970568d46f5a12d6f1c7bb9e4ee",
"41597e7ccca34bc5ae22562260e764d1",
"8b3f68f1e84e4af9a29c57447ff94027",
"71296dd2da5e4c3d92d28204718d1d13",
"ba135575d04048bea21a7ae63085e89f",
"56bf69ca381f4c1895a15b61db7957e0",
"16178169fc7a4b4b8ba39038b332bfb2",
"692da53093d74e9bbba1c650ac7e6039",
"4419b35b980c401997962e7c2bfe4672",
"52c86dc445a24c5c9e2b8a02f12b9fb3",
"858e97e2461d4b69bce55afac2a91c9b",
"9a616db2cadb4618aa6492f1a1bef867",
"2631be99ee604ca6859060402811e990",
"b015448b956347b3867f19a8d5189517",
"5a1baf78fe7e43f1bef9349959c643b2",
"8aa423668aa545bbb6c3f332668b9bf5",
"818e6bb7bb8b4f36ab47b511d8eea4f2",
"879036aa5880478c80175ae0862cafc0",
"1e61b33581e9499e81bc710e4d09d856",
"ca424a49bdaa4653921f04f66295df8e",
"3841511d0a714a328b58deeb4f185b3b",
"ea6303e7aa264f739950572ec3eae4aa",
"761736c6489e458fad5d258ed8e6485e",
"15e90216f6c24b578106a08846739fcb",
"f787c65d91b8477f8a6a199c57075dc8",
"1ed0be1c90814e2c9f44b30f81db86b8",
"80a88d56d5094e9ab4a21c68f02548e9",
"1e0a05a8ca454a49addd483ee686d868",
"9c933fdac2df4769bba416b241ce78ed",
"a034c602568e4174a003045319c4f7ee",
"db3c2fc0735d463694876e49ccbbd9d3",
"1eaed0a8fdd94fd696431895e257c725",
"94b7fba203734eca84683d121cac4197",
"a0eb239bc63d44fd9866bd7b459a4bad",
"c48ddcd435f547818779302134f21e66",
"0c8d80a1ed8c4ad2b8921865064a9d3a"
]
},
"id": "Ppdx98tJTqfY",
"outputId": "cb35f398-ef79-4864-f5e9-4556fd05a936"
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ef64ca729ce24516b53f811439c922de",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"config.json: 0%| | 0.00/762 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7ea44cea34114e6784ebc339d78a8cb0",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model.safetensors: 0%| | 0.00/1.34G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "71296dd2da5e4c3d92d28204718d1d13",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/49.0 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5a1baf78fe7e43f1bef9349959c643b2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"vocab.txt: 0%| | 0.00/213k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1ed0be1c90814e2c9f44b30f81db86b8",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/436k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"from transformers import AutoTokenizer, AutoModel\n",
"import torch\n",
"\n",
"bert_model = AutoModel.from_pretrained(\"bert-large-cased\")\n",
"bert_tokenizer = AutoTokenizer.from_pretrained(\"bert-large-cased\")\n",
"\n",
"def classify_text(text):\n",
" inputs = bert_tokenizer(text, return_tensors=\"pt\")\n",
" with torch.no_grad():\n",
" outputs = bert_model(**inputs)\n",
" return outputs.last_hidden_state.mean(dim=1) # Sentence embedding"
]
},
{
"cell_type": "markdown",
"id": "bEjDTqPrens-",
"metadata": {
"id": "bEjDTqPrens-"
},
"source": [
"# Load Whisper Large V3 for audio transcription"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "R0AGFFqTTqfY",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 369,
"referenced_widgets": [
"012a21936d6c4884a7b84b2767584b58",
"99d6c0fad4b748aa8738fa9a35f4e96f",
"8ddf19cbbe724f58800c702b28e37801",
"f2881943ec1b48e8b5ace9484815820c",
"d6882c4c225a4b04af77d282bd7ce548",
"8ae9c3217d4242bb913f6c2af6e0e19b",
"0620a81309e249f490509ad62ce8afb6",
"7debeb90d88546478719e8a625cb38fb",
"07e65c48f16d4f9295ac639dd4b0b5c9",
"036a8f64dc44488cabd463e1c15c4c91",
"a9cb91371c374c288ee9b06d68327362",
"350dbbd7e33d4a38865a41a85f0da780",
"abbf7218263e44109604bac835e9e313",
"294dd7f394114d8d893e9a5242099f71",
"f4cc15dc389049c2b779439de6a59468",
"c4480e04078a4c4cb65f7eeb87bd2183",
"6a60214efc17431fac99e020321ddb64",
"d24212a4256a436fbb5ae2eac6cb8c74",
"bc6495fabaf6473a83c0c3a8a1b08422",
"fdf9507288f34b578f59afb403e8a899",
"c4c9f720c9eb4a71ad46bdf732273ed9",
"567034a346624e1896bca65ea663ad08",
"d5c0f34255d04845acee22ab2fd11275",
"0d58eb843d174c15aee2f4877295d115",
"0fd2307c7b894d68889f71345f48a2ad",
"0ef40308eecb4817be0b56cdda125c38",
"d673a07a18a54c5b915a8fa6580583bc",
"2b73ef94e8f94aa1ab5e28cf3ae09a30",
"75ad342121b3429aae7bbcf3aaf04fef",
"dbb026b79b724d68a5eecbf6bf5fd957",
"4d1c52a7062846ad8faf47d7aafb4127",
"50c1e37bb01340ee8fbd09a4d9510fe9",
"b29fb4842efc453b8f76e15859c091d9",
"49cfe6d1837f4e16b8d7a9f7a622977b",
"a75a0c15bc194163af7091e40ff31aa0",
"598aebd58dae453d9be0bd515b2b6cd6",
"98c7dbcdaf114ef0818c6a29200f414d",
"6a0dc52da74949ffb8a5f4d8b81ba69e",
"67adcfbdf31b4606b5b123402bbf1829",
"db13444109ba4a4f828f402a1798f44f",
"772e4b8bf52a4e098e76445a65487a4e",
"79712d86e8fa432a8cdd055097429d81",
"6b6a84ea89a64b208ef6989173e7b6c5",
"fee4b1fe846c4c90b5a81f7344d9d2fa",
"1859b8e9773d490880fb8f482bb2df7f",
"3739191045f749209730cba003eb6ea0",
"b9d5984462a243bbb490152374f00164",
"d42b2cf9e5c849aa8297d85978340fa4",
"4efc347cbbc54c1eb63edf2d1dd997c3",
"be19baf94af44562b2392094688dff8c",
"2d29827b9e154631bb2fdfbba8ad2e4f",
"d82000f2e8524367b11b1736e4eed376",
"a9e75f229ab04b1fb062d3dabe40d02e",
"06445a9779894cef921650facc3cb915",
"f9f294ebc94c40eab79b061bda373d60",
"8549e6d45d904cb9860807c2114939f6",
"329eb033407541e9a2c5854378d5bba9",
"635ca5b07be2495eaafa5126637ee427",
"43b284140ef14a0db4d9164d12333540",
"902398ce9f8143478a3889c1af9693e9",
"0bc9e112c9a2485fba38cad1e620d6d4",
"dcdb799810e84d0b8de6a471b256fe46",
"8b726a505b43413d853b1f5ba0404fd9",
"b6b50da93bab490f8abf19930fa28f46",
"2883a49d53fd4c0c9d4e97edf0005b9b",
"0f88de1a2bce4af6be5c3cb88d0c0b17",
"05d137a7667346abafdc2290320fedc2",
"d1de71b61b6b442ab60e5c9d8d745cbe",
"3662758074254935846f6eef56e6afd9",
"43aa89322bc94fc3ab06ec84cf9b80b6",
"9da6ad199a574479a75010da5b1a22dc",
"6826f0af1489463f9e5bebcf422cf000",
"486accbedd1648fe877cbafe9ceaf5a3",
"ff7b49296a6440bf84f8734afc9a8a7b",
"cb3b611a6ef04cd7a6a781dee1d0128d",
"963c8f0e2cbb4a6a857a05e41b9cdc41",
"4e551605bba34d12af90a9edb443e334",
"87a22b9d9c9a4e0691a77fd34f15be4a",
"327ba03562814fffaa695770e1f50235",
"76551436a17f482fa16131b4985720a4",
"86558c51b63b42fc9372779dd777379c",
"b52881719c6a49a1a2dbbc906571d996",
"71bd0c63a6564923b6c12cfd95bd0f99",
"8126ef033a5d4beb9fe5ecb126d817b8",
"557d5fa2a6404473960c9ad2d8ac9f61",
"2d21c4ff75f549308297f7d38238ba60",
"0a8b5af0b1e547ca9373b63f23724a52",
"41448615087f4344a58a862d00ab7b60",
"e801569aba0b4f51814d7498a362ae69",
"259fd1045f3c451fb5b2bd8df2ff47fc",
"cb885f28dcee412381d52e063a5d058b",
"c5728b07bb224c4fb0ca656fa64b1137",
"7b75953a78c847688eed9106a38bfec7",
"e330f81594ea46cea5c4e94206144605",
"bddcbf3209db4872aee6a7a6d8e57fdc",
"32154e90fdbf4ca1a293a8c6c5d8ffd9",
"ebc78e4a82d9430d8cc9047986e96185",
"d0d664ee23ad47c6b6bb193eafcdfbf1",
"1c39b174d83146e8a05b0af82c0191ef",
"7972b5df2e4e465d868dbc827850e7a4",
"e31441e745c04c308be3e81ebacf31c4",
"f7a2d47725fc45d0b2f65b81b8cfa925",
"f3f13df2d56a445ca472633188318b33",
"37b8a1408f284eefb36be7c7babd3aa7",
"0a2b79b882154b54bfd13090bf67af07",
"eddcb5465f5648b69ac37c03887e494c",
"49626d83e7c1403880ce17324fa7a514",
"ddc300dd7e504840bc9dffd4666c0984",
"b134fdc0b30445fa819a39bde44704d3",
"61ce458fc45e4c709f6e4e2af9b4c881",
"459a2c675632454c83a62b564853a6f3",
"8b90fbbf1d234202b6aaec0a624874d9",
"f104a1f9546e4f54ab86a44a4649ea33",
"ae01037b6e084a15b0310cedfc0a6d53",
"5050d0dbcfcc426f925fe39ecc975a72",
"f2855e5586ce429da7472c9bcef8a88b",
"05442b45864d417ab37710e2b3a9d05b",
"68f72ed9e852416798a42c6a1147e540",
"a6230b708cc24e9c85b9704ec0ece351",
"62ff7ab4106648d4a2bc07b3048e1857",
"3b1be73a026a4ea0b5686f10db107e3c"
]
},
"id": "R0AGFFqTTqfY",
"outputId": "31805e6b-a58c-49cc-ae17-a2c20c5e0077"
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "012a21936d6c4884a7b84b2767584b58",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"preprocessor_config.json: 0%| | 0.00/340 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "350dbbd7e33d4a38865a41a85f0da780",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/283k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d5c0f34255d04845acee22ab2fd11275",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"vocab.json: 0%| | 0.00/1.04M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "49cfe6d1837f4e16b8d7a9f7a622977b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/2.48M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1859b8e9773d490880fb8f482bb2df7f",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"merges.txt: 0%| | 0.00/494k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "8549e6d45d904cb9860807c2114939f6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"normalizer.json: 0%| | 0.00/52.7k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "05d137a7667346abafdc2290320fedc2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"added_tokens.json: 0%| | 0.00/34.6k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "87a22b9d9c9a4e0691a77fd34f15be4a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"special_tokens_map.json: 0%| | 0.00/2.07k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e801569aba0b4f51814d7498a362ae69",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"config.json: 0%| | 0.00/1.27k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7972b5df2e4e465d868dbc827850e7a4",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model.safetensors: 0%| | 0.00/3.09G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "459a2c675632454c83a62b564853a6f3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"generation_config.json: 0%| | 0.00/3.90k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"import torchaudio\n",
"from transformers import WhisperProcessor, WhisperForConditionalGeneration\n",
"\n",
"processor = WhisperProcessor.from_pretrained(\"openai/whisper-large-v3\")\n",
"model = WhisperForConditionalGeneration.from_pretrained(\"openai/whisper-large-v3\")\n",
"model = model.to(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
"\n",
"def transcribe_audio(file_path):\n",
" audio, rate = torchaudio.load(file_path)\n",
" if rate != 16000:\n",
" resampler = torchaudio.transforms.Resample(orig_freq=rate, new_freq=16000)\n",
" audio = resampler(audio)\n",
" input_features = processor(audio.squeeze().numpy(), sampling_rate=16000, return_tensors=\"pt\").input_features\n",
" input_features = input_features.to(model.device)\n",
" predicted_ids = model.generate(input_features)\n",
" return processor.batch_decode(predicted_ids, skip_special_tokens=True)[0]"
]
},
{
"cell_type": "markdown",
"id": "dSQGzAiGeqUS",
"metadata": {
"id": "dSQGzAiGeqUS"
},
"source": [
"# Example BERT"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7Q40yeA_TqfZ",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "7Q40yeA_TqfZ",
"outputId": "64785b48-77e1-4cd9-9d9b-6dec9e34b45c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BERT embedding shape: torch.Size([1, 1024])\n"
]
}
],
"source": [
"# Example usage (requires uploaded audio file like sample.wav)\n",
"# from google.colab import files\n",
"# uploaded = files.upload()\n",
"# print(transcribe_audio(\"sample.wav\"))\n",
"\n",
"embedding = classify_text(\"Google Colab is a great place to run small-scale NLP models.\")\n",
"print(\"BERT embedding shape:\", embedding.shape)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,401 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "W5cYeCT1jIBS",
"metadata": {
"id": "W5cYeCT1jIBS"
},
"source": [
"# 🗣️ Talk2Find: Voice-Driven Knowledge Agent (with Synthetic Audio)"
]
},
{
"cell_type": "markdown",
"id": "uTxgPYvKjJty",
"metadata": {
"id": "uTxgPYvKjJty"
},
"source": [
"This notebook demonstrates a voice-driven knowledge agent using PraisonAI Agents. It generates a valid WAV file from text using gTTS and pydub, transcribes the audio with SpeechRecognition, and then uses PraisonAI Agents to answer the spoken question. This workflow is robust, reproducible, and does not require manual audio uploads."
]
},
{
"cell_type": "markdown",
"id": "CJdIonVMjgU7",
"metadata": {
"id": "CJdIonVMjgU7"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/talk2find_voice_agent_demo.ipynb)\n"
]
},
{
"cell_type": "markdown",
"id": "wjVE-KWwjQxP",
"metadata": {
"id": "wjVE-KWwjQxP"
},
"source": [
"# Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "RFG1v766idiL",
"metadata": {
"id": "RFG1v766idiL"
},
"outputs": [],
"source": [
"!pip install praisonaiagents openai SpeechRecognition pydub gTTS --quiet"
]
},
{
"cell_type": "markdown",
"id": "0IYiVLgsjTJf",
"metadata": {
"id": "0IYiVLgsjTJf"
},
"source": [
"# Set API Key"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "3AVzmY5FilJ9",
"metadata": {
"id": "3AVzmY5FilJ9"
},
"outputs": [],
"source": [
"import os\n",
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your api key\" # <-- Replace with your actual OpenAI API key"
]
},
{
"cell_type": "markdown",
"id": "SfHMkOTHjVMa",
"metadata": {
"id": "SfHMkOTHjVMa"
},
"source": [
"# Tools"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "Hj28HfsNip9V",
"metadata": {
"id": "Hj28HfsNip9V"
},
"outputs": [],
"source": [
"from praisonaiagents import Agent\n",
"import speech_recognition as sr\n",
"from gtts import gTTS\n",
"from pydub import AudioSegment\n",
"from IPython.display import Audio"
]
},
{
"cell_type": "markdown",
"id": "8BIPQ6fzjXu4",
"metadata": {
"id": "8BIPQ6fzjXu4"
},
"source": [
"# Generate a Valid WAV File from Text"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "rdcn-AiYisHb",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 92
},
"id": "rdcn-AiYisHb",
"outputId": "2daf8cb4-93f6-4e02-ab2b-3e449d7deee0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ WAV file 'question.wav' has been created.\n"
]
},
{
"data": {
"text/html": [
"\n",
" <audio controls=\"controls\" >\n",
" <source src=\"data:audio/x-wav;base64,UklGRiRfAQBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAAZGF0YQBfAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAEAAAAAAAEAAQAAAAAAAAABAAEAAQAAAAEAAQABAAAA//8AAP//AAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAA//8BAP////8AAAAAAAAAAAAA//8AAAAAAAAAAAAAAAD//wEAAAAAAP//AAAAAAAA//8AAAAA//8AAP//AAAAAAAAAAAAAAAA/////wAAAAAAAAAA//8AAAAAAQABAAAAAAAAAAEAAQAAAAEAAQABAP//AQAAAP//AQAAAAEAAQAAAAAAAQABAAEAAAACAAIAAQABAAEAAQABAAEAAQABAAEAAgABAAEAAAABAAEAAQABAAAAAAD/////AAD//wAAAAAAAP///v8AAAAA/////wEA//////////8AAAAAAAD//wAA/v8AAAAA//8AAAAAAAAAAAAAAAAAAP//AQAAAAAAAAAAAAAAAAAAAAgABwD+/wEAAQD7//7/AgACAAEAAgAEAAQAAwABAAEAAAABAAEAAQD//wAA/v/8//3//f/+//7//v/9//3//v///////f/9/wAA/////wAAAQAAAP7////9/wEAAAD///3//P/8//7////+/wEA///+//7//v/+//z//v8AAP///v/9//z//v/8//r//f/9//v/+v/5//v/+//7//z/+v/7//r//P/6//n/+//6//z/+f/4//n/+v/8//3///////z/+///////AAAAAAIA///+//////8CAP7///8BAAMAAAD9//7/AQABAAEA///8/////P8AAP3/+//+//v//P/9//z/9f/4//3/+f/9//r/9f/5//j/9f/5//3/+P/7//b/9//2/Line truncated
" Your browser does not support the audio element.\n",
" </audio>\n",
" "
],
"text/plain": [
"<IPython.lib.display.Audio object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Step 1: Define the text you want to convert to speech\n",
"text = \"What time is the meeting?\"\n",
"\n",
"# Step 2: Generate speech from text and save as MP3\n",
"tts = gTTS(text=text, lang='en')\n",
"tts.save(\"question.mp3\")\n",
"\n",
"# Step 3: Convert MP3 to WAV using pydub\n",
"sound = AudioSegment.from_mp3(\"question.mp3\")\n",
"sound.export(\"question.wav\", format=\"wav\")\n",
"\n",
"print(\"✅ WAV file 'question.wav' has been created.\")\n",
"\n",
"# Optional: Play the audio (works in Jupyter/Colab)\n",
"try:\n",
" display(Audio(\"question.wav\"))\n",
"except:\n",
" print(\"You can now play 'question.wav' manually.\")"
]
},
{
"cell_type": "markdown",
"id": "AuA3Cj7mjamh",
"metadata": {
"id": "AuA3Cj7mjamh"
},
"source": [
"# YAML Prompt (Role, Goal, Instructions)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "Au5fg-6UiwDP",
"metadata": {
"id": "Au5fg-6UiwDP"
},
"outputs": [],
"source": [
"ROLE = \"Voice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, concise answers.\"\n",
"GOAL = \"Transcribe the user's voice input and answer their question or find relevant information.\"\n",
"INSTRUCTIONS = \"Given a transcribed user question, provide a clear, factual, and helpful answer. If the question is unclear, ask for clarification.\""
]
},
{
"cell_type": "markdown",
"id": "yz4P9xvpjc4b",
"metadata": {
"id": "yz4P9xvpjc4b"
},
"source": [
"# Main (Transcription + Agent)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "ubYuWOYCiyCx",
"metadata": {
"id": "ubYuWOYCiyCx"
},
"outputs": [],
"source": [
"def transcribe_audio(audio_file):\n",
" recognizer = sr.Recognizer()\n",
" with sr.AudioFile(audio_file) as source:\n",
" audio = recognizer.record(source)\n",
" try:\n",
" return recognizer.recognize_google(audio)\n",
" except Exception as e:\n",
" print(\"Transcription error:\", e)\n",
" return None\n",
"\n",
"def talk2find_agent(audio_file):\n",
" query = transcribe_audio(audio_file)\n",
" if not query:\n",
" return {\"error\": \"Could not transcribe audio.\"}\n",
" print(\"Transcribed text:\", query)\n",
" agent = Agent(role=ROLE, goal=GOAL, instructions=INSTRUCTIONS)\n",
" return agent.start(query)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "VDMMruvCiz8r",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 314,
"referenced_widgets": [
"b72c0f15f2e24a678edcf696b7cc13a3",
"99867a03f5474e4c9f22ec5ea948a6ed"
]
},
"id": "VDMMruvCiz8r",
"outputId": "14354595-25ef-4600-c3c8-8b1ff9c4aba0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Transcribed text: what time is the meeting\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Voice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">concise answers.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mVoice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mconcise answers.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b72c0f15f2e24a678edcf696b7cc13a3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"</pre>\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 2.3s</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[2mResponse generated in 2.3s\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> what time is the meeting <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m what time is the meeting \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> about which meeting you're referring to? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
"\u001b[36m│\u001b[0m I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information \u001b[36m│\u001b[0m\n",
"\u001b[36m│\u001b[0m about which meeting you're referring to? \u001b[36m│\u001b[0m\n",
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information about which meeting you're referring to?\n"
]
}
],
"source": [
"audio_path = \"question.wav\"\n",
"result = talk2find_agent(audio_path)\n",
"print(result)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.x"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+133
View File
@@ -0,0 +1,133 @@
"""
Code Agent Example
This example demonstrates a comprehensive code agent that can write, analyze, debug, and execute code.
It includes self-reflection for improving code quality and multiple specialized tools.
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import CodeInterpreter
# Initialize code execution tool
code_interpreter = CodeInterpreter()
# Custom code analysis tool
def analyze_code_complexity(code: str) -> str:
"""Analyze code complexity and provide feedback."""
lines = code.strip().split('\n')
num_lines = len(lines)
num_functions = sum(1 for line in lines if line.strip().startswith('def '))
num_classes = sum(1 for line in lines if line.strip().startswith('class '))
return f"""Code Analysis:
- Lines of code: {num_lines}
- Functions: {num_functions}
- Classes: {num_classes}
- Complexity: {'Simple' if num_lines < 50 else 'Moderate' if num_lines < 200 else 'Complex'}"""
# Create specialized code agents
code_writer = Agent(
name="CodeWriter",
role="Expert Python developer",
goal="Write clean, efficient, and well-documented Python code",
backstory="You are a senior Python developer with 10+ years of experience in writing production-quality code.",
instructions="Write Python code that follows PEP 8 standards, includes proper error handling, and has clear documentation.",
self_reflect=True,
min_reflect=2,
max_reflect=5
)
code_reviewer = Agent(
name="CodeReviewer",
role="Code quality expert",
goal="Review code for bugs, security issues, and best practices",
backstory="You are a code review specialist who ensures code quality and maintainability.",
instructions="Review the provided code for potential issues, suggest improvements, and ensure it follows best practices.",
tools=[analyze_code_complexity]
)
code_executor = Agent(
name="CodeExecutor",
role="Code execution specialist",
goal="Safely execute and test Python code",
backstory="You are responsible for running code and reporting results or errors.",
instructions="Execute the provided code safely and report the output or any errors encountered.",
tools=[code_interpreter]
)
# Example tasks
def demonstrate_code_agent():
# Task 1: Write a function
write_task = Task(
name="write_function",
description="Write a Python function that calculates the Fibonacci sequence up to n terms",
expected_output="A well-documented Python function with error handling",
agent=code_writer
)
# Task 2: Review the code
review_task = Task(
name="review_code",
description="Review the Fibonacci function for quality and suggest improvements",
expected_output="Detailed code review with suggestions",
agent=code_reviewer,
context=[write_task]
)
# Task 3: Execute and test
execute_task = Task(
name="execute_code",
description="Execute the Fibonacci function with n=10 and verify it works correctly",
expected_output="Execution results showing the first 10 Fibonacci numbers",
agent=code_executor,
context=[write_task]
)
# Create workflow
workflow = PraisonAIAgents(
agents=[code_writer, code_reviewer, code_executor],
tasks=[write_task, review_task, execute_task],
process="sequential",
verbose=True
)
# Run the workflow
result = workflow.start()
return result
# Standalone code agent for general programming tasks
general_code_agent = Agent(
name="GeneralCodeAgent",
role="Full-stack programming assistant",
goal="Help with any programming task including writing, debugging, and explaining code",
backstory="You are an AI programming assistant with expertise in multiple languages and frameworks.",
instructions="""You can:
1. Write code in any programming language
2. Debug and fix code issues
3. Explain code concepts
4. Refactor code for better performance
5. Add tests and documentation""",
tools=[code_interpreter, analyze_code_complexity],
self_reflect=True,
min_reflect=1,
max_reflect=3
)
if __name__ == "__main__":
# Example 1: Run the multi-agent workflow
print("=== Multi-Agent Code Workflow ===")
result = demonstrate_code_agent()
print(f"Workflow Result: {result}")
# Example 2: Use the general code agent
print("\n=== General Code Agent ===")
response = general_code_agent.start("""
Write a Python class for a simple Calculator with methods for:
- Addition
- Subtraction
- Multiplication
- Division (with error handling for division by zero)
Then create a simple test to verify it works.
""")
print(response)
+188
View File
@@ -0,0 +1,188 @@
"""
Math Agent Example
This example demonstrates a mathematical problem-solving agent that can handle various math tasks
including calculations, equation solving, and step-by-step explanations.
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from typing import Dict, Any
import math
import re
# Custom math tools
def basic_calculator(expression: str) -> str:
"""Evaluate basic mathematical expressions safely."""
try:
# Remove any non-mathematical characters for safety
safe_expr = re.sub(r'[^0-9+\-*/().,\s]', '', expression)
result = eval(safe_expr)
return f"Result: {result}"
except Exception as e:
return f"Error in calculation: {str(e)}"
def solve_quadratic(a: float, b: float, c: float) -> str:
"""Solve quadratic equation ax² + bx + c = 0."""
discriminant = b**2 - 4*a*c
if discriminant > 0:
x1 = (-b + math.sqrt(discriminant)) / (2*a)
x2 = (-b - math.sqrt(discriminant)) / (2*a)
return f"Two real solutions: x₁ = {x1:.4f}, x₂ = {x2:.4f}"
elif discriminant == 0:
x = -b / (2*a)
return f"One real solution: x = {x:.4f}"
else:
real_part = -b / (2*a)
imag_part = math.sqrt(-discriminant) / (2*a)
return f"Two complex solutions: x₁ = {real_part:.4f} + {imag_part:.4f}i, x₂ = {real_part:.4f} - {imag_part:.4f}i"
def calculate_statistics(numbers: list) -> str:
"""Calculate basic statistics for a list of numbers."""
if not numbers:
return "No numbers provided"
n = len(numbers)
mean = sum(numbers) / n
sorted_nums = sorted(numbers)
median = sorted_nums[n//2] if n % 2 else (sorted_nums[n//2-1] + sorted_nums[n//2]) / 2
variance = sum((x - mean)**2 for x in numbers) / n
std_dev = math.sqrt(variance)
return f"""Statistics:
- Count: {n}
- Mean: {mean:.4f}
- Median: {median:.4f}
- Standard Deviation: {std_dev:.4f}
- Min: {min(numbers)}
- Max: {max(numbers)}"""
# Create specialized math agents
calculation_agent = Agent(
name="CalculationAgent",
role="Mathematical calculation specialist",
goal="Perform accurate mathematical calculations and computations",
backstory="You are an expert mathematician who can handle complex calculations with precision.",
instructions="Perform the requested calculations step by step, showing your work clearly.",
tools=[basic_calculator, solve_quadratic, calculate_statistics],
self_reflect=True,
min_reflect=1,
max_reflect=2
)
problem_solver_agent = Agent(
name="ProblemSolver",
role="Mathematical problem solver",
goal="Solve complex math problems with detailed explanations",
backstory="You are a math teacher who excels at breaking down complex problems into understandable steps.",
instructions="""When solving math problems:
1. Identify the type of problem
2. List the given information
3. Determine what needs to be found
4. Show each step of the solution
5. Verify the answer makes sense""",
self_reflect=True,
min_reflect=2,
max_reflect=4
)
math_tutor_agent = Agent(
name="MathTutor",
role="Mathematics tutor and explainer",
goal="Explain mathematical concepts clearly and help users understand math",
backstory="You are a patient math tutor who can explain concepts at any level from elementary to advanced.",
instructions="Explain mathematical concepts using simple language, provide examples, and check for understanding."
)
# Example workflow for solving complex problems
def solve_math_problem_workflow():
# Task 1: Understand the problem
understand_task = Task(
name="understand_problem",
description="""A farmer has a rectangular field. The length is 3 meters more than twice the width.
If the perimeter is 96 meters, what are the dimensions of the field?""",
expected_output="Clear problem statement with identified variables and equations",
agent=problem_solver_agent
)
# Task 2: Solve the problem
solve_task = Task(
name="solve_problem",
description="Solve for the dimensions using the equations identified",
expected_output="The width and length of the field with calculations shown",
agent=calculation_agent,
context=[understand_task]
)
# Task 3: Verify and explain
verify_task = Task(
name="verify_solution",
description="Verify the solution is correct and explain why it makes sense",
expected_output="Verification that the solution satisfies all conditions",
agent=math_tutor_agent,
context=[solve_task]
)
workflow = PraisonAIAgents(
agents=[problem_solver_agent, calculation_agent, math_tutor_agent],
tasks=[understand_task, solve_task, verify_task],
process="sequential",
verbose=True
)
return workflow.start()
# General math assistant combining all capabilities
math_assistant = Agent(
name="MathAssistant",
role="Comprehensive mathematics assistant",
goal="Help with any mathematical task from basic arithmetic to complex problem solving",
backstory="You are an AI math assistant with expertise in all areas of mathematics.",
instructions="""You can help with:
1. Basic arithmetic and calculations
2. Algebra and equation solving
3. Geometry and trigonometry
4. Calculus and advanced mathematics
5. Statistics and probability
6. Math tutoring and explanations
Always show your work step by step.""",
tools=[basic_calculator, solve_quadratic, calculate_statistics],
self_reflect=True,
min_reflect=1,
max_reflect=3
)
if __name__ == "__main__":
# Example 1: Basic calculation
print("=== Basic Calculation ===")
result = calculation_agent.start("Calculate: (15 + 23) * 4 - 18 / 3")
print(result)
# Example 2: Quadratic equation
print("\n=== Quadratic Equation ===")
result = calculation_agent.start("Solve the equation: 2x² - 5x + 3 = 0")
print(result)
# Example 3: Statistics
print("\n=== Statistics ===")
result = calculation_agent.start("Calculate statistics for: [12, 15, 18, 20, 22, 25, 28, 30]")
print(result)
# Example 4: Complex problem workflow
print("\n=== Complex Problem Workflow ===")
result = solve_math_problem_workflow()
print(f"Workflow Result: {result}")
# Example 5: General math assistance
print("\n=== General Math Assistance ===")
result = math_assistant.start("""
I need help with this problem:
A ball is thrown upward with an initial velocity of 20 m/s.
The height h(t) = 20t - 5t² where t is time in seconds.
1. When does the ball reach maximum height?
2. What is the maximum height?
3. When does the ball hit the ground?
""")
print(result)
+49
View File
@@ -0,0 +1,49 @@
"""
Chat with PDF Example
This example demonstrates how to create an agent that can read and answer questions about PDF documents.
It uses the knowledge parameter to load PDF files and provides interactive Q&A capabilities.
"""
from praisonaiagents import Agent
# Configure vector store for PDF storage
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "pdf_chat",
"path": ".praison_pdf_chat",
}
}
}
# Create a PDF chat agent
pdf_agent = Agent(
name="PDF Assistant",
role="PDF document expert",
goal="Help users understand and extract information from PDF documents",
backstory="You are an expert at reading, analyzing, and answering questions about PDF documents. You provide accurate, detailed answers based on the document content.",
instructions="Read the provided PDF document and answer questions about its content. Be specific and cite relevant sections when possible.",
knowledge=["document.pdf"], # Replace with your PDF file path
knowledge_config=config,
self_reflect=True,
min_reflect=1,
max_reflect=3
)
# Example usage
if __name__ == "__main__":
# Single question
response = pdf_agent.start("What are the main topics covered in this document?")
print(response)
# Interactive chat
print("\nPDF Chat Assistant Ready! Type 'quit' to exit.")
while True:
question = input("\nYour question: ")
if question.lower() == 'quit':
break
response = pdf_agent.start(question)
print(f"\nAnswer: {response}")
@@ -0,0 +1,281 @@
"""
Reasoning Extraction Example
This example demonstrates how to extract and utilize reasoning patterns in PraisonAI:
- Chain of Thought (CoT) reasoning
- Step-by-step problem decomposition
- Reasoning visualization
- Decision rationale extraction
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from typing import Dict, List, Tuple
from pydantic import BaseModel
import json
# Pydantic models for structured reasoning
class ReasoningStep(BaseModel):
step_number: int
description: str
reasoning: str
conclusion: str
class ChainOfThought(BaseModel):
problem: str
steps: List[ReasoningStep]
final_answer: str
confidence: float
# Tool for saving reasoning chains
def save_reasoning_chain(chain: ChainOfThought) -> str:
"""Save a chain of thought reasoning to analyze patterns."""
filename = f"reasoning_{chain.problem[:20].replace(' ', '_')}.json"
with open(filename, 'w') as f:
json.dump(chain.dict(), f, indent=2)
return f"Reasoning chain saved to {filename}"
# Example 1: Chain of Thought Agent
cot_agent = Agent(
name="ChainOfThoughtAgent",
role="Systematic reasoning specialist",
goal="Solve problems using explicit chain of thought reasoning",
backstory="You are a logic expert who breaks down complex problems into clear reasoning steps.",
instructions="""When solving problems:
1. State the problem clearly
2. Break it down into logical steps
3. Show your reasoning for each step
4. Draw conclusions from each step
5. Arrive at the final answer
6. Assess your confidence level
Always make your thinking process explicit and transparent.""",
self_reflect=True,
min_reflect=2,
max_reflect=3
)
# Example 2: Reasoning Extractor Agent
reasoning_extractor = Agent(
name="ReasoningExtractor",
role="Reasoning pattern analyzer",
goal="Extract and analyze reasoning patterns from problem-solving processes",
backstory="You specialize in understanding how problems are solved and extracting the underlying reasoning.",
instructions="""Analyze the problem-solving process and extract:
1. Key reasoning steps
2. Decision points and rationale
3. Assumptions made
4. Logic patterns used
5. Potential alternative approaches""",
tools=[save_reasoning_chain]
)
# Example 3: Multi-Step Reasoning Workflow
def demonstrate_reasoning_extraction():
"""Show how to extract reasoning from a complex problem-solving process."""
# Step 1: Present a complex problem
problem_task = Task(
name="solve_problem",
description="""Solve this problem step by step:
A small tech startup has $50,000 budget for the next quarter.
They need to decide between:
1. Hiring 2 junior developers ($25,000 each)
2. Hiring 1 senior developer ($40,000) + marketing budget ($10,000)
3. Investing in AI tools ($30,000) + 1 junior developer ($20,000)
Consider: current team size is 3, main challenge is product development speed,
but they also lack market visibility.""",
expected_output="Detailed solution with reasoning for each consideration",
agent=cot_agent,
output_pydantic=ChainOfThought
)
# Step 2: Extract reasoning patterns
extract_task = Task(
name="extract_reasoning",
description="Extract and analyze the reasoning patterns used in solving the problem",
expected_output="Structured analysis of reasoning patterns",
agent=reasoning_extractor,
context=[problem_task]
)
workflow = PraisonAIAgents(
agents=[cot_agent, reasoning_extractor],
tasks=[problem_task, extract_task],
process="sequential",
verbose=True
)
return workflow.start()
# Example 4: Socratic Reasoning Agent
socratic_agent = Agent(
name="SocraticReasoner",
role="Socratic method practitioner",
goal="Guide reasoning through questions and answers",
backstory="You use the Socratic method to help uncover reasoning through thoughtful questions.",
instructions="""Use the Socratic method:
1. Ask clarifying questions
2. Challenge assumptions
3. Explore implications
4. Consider alternatives
5. Synthesize insights
Make the reasoning process interactive and exploratory."""
)
# Example 5: Reasoning Validator
reasoning_validator = Agent(
name="ReasoningValidator",
role="Logic and reasoning validator",
goal="Validate reasoning chains for logical consistency",
backstory="You are an expert at identifying logical fallacies and validating reasoning.",
instructions="""Check reasoning for:
1. Logical consistency
2. Valid premises
3. Sound conclusions
4. Hidden assumptions
5. Potential biases"""
)
# Example 6: Advanced Reasoning Patterns
def advanced_reasoning_patterns():
"""Demonstrate different types of reasoning extraction."""
# Deductive reasoning
deductive_task = Task(
name="deductive_reasoning",
description="""Use deductive reasoning to solve:
All successful startups have strong leadership.
Company X is a successful startup.
What can we conclude about Company X?""",
expected_output="Deductive reasoning chain with clear premises and conclusion",
agent=cot_agent
)
# Inductive reasoning
inductive_task = Task(
name="inductive_reasoning",
description="""Use inductive reasoning based on these observations:
- 5 observed AI companies grew 200% after implementing MLOps
- 3 observed AI companies without MLOps grew only 50%
What general conclusion might we draw?""",
expected_output="Inductive reasoning with probability assessment",
agent=cot_agent
)
# Abductive reasoning
abductive_task = Task(
name="abductive_reasoning",
description="""Use abductive reasoning:
The server is down and users can't access the app.
What are the most likely explanations?""",
expected_output="Abductive reasoning with ranked hypotheses",
agent=cot_agent
)
# Validate all reasoning
validation_task = Task(
name="validate_reasoning",
description="Validate all three reasoning approaches for logical soundness",
expected_output="Validation report for each reasoning type",
agent=reasoning_validator,
context=[deductive_task, inductive_task, abductive_task]
)
workflow = PraisonAIAgents(
agents=[cot_agent, reasoning_validator],
tasks=[deductive_task, inductive_task, abductive_task, validation_task],
process="sequential",
verbose=True
)
return workflow.start()
# Example 7: Reasoning Patterns Library
class ReasoningPattern:
"""Base class for different reasoning patterns."""
@staticmethod
def analogical_reasoning(source: str, target: str) -> str:
"""Extract reasoning by analogy."""
return f"If {source} works like X, then {target} might work like Y"
@staticmethod
def causal_reasoning(cause: str, effect: str) -> str:
"""Extract cause-effect reasoning."""
return f"Because {cause}, therefore {effect}"
@staticmethod
def counterfactual_reasoning(fact: str, alternative: str) -> str:
"""Extract counterfactual reasoning."""
return f"If {alternative} instead of {fact}, then what would change?"
# Specialized reasoning agent using patterns
pattern_reasoning_agent = Agent(
name="PatternReasoner",
role="Reasoning pattern specialist",
goal="Apply specific reasoning patterns to solve problems",
backstory="You are an expert in various reasoning patterns and their applications.",
instructions="""Apply these reasoning patterns as appropriate:
1. Analogical: Find similar situations
2. Causal: Identify cause-effect relationships
3. Counterfactual: Explore what-if scenarios
4. Systems thinking: Consider interconnections
5. Probabilistic: Assess likelihoods""",
self_reflect=True
)
# Example 8: Interactive Reasoning Extraction
def interactive_reasoning_demo():
"""Interactive demonstration of reasoning extraction."""
print("=== Interactive Reasoning Extraction Demo ===\n")
# Problem categories
problems = {
"logical": "If all cats have tails, and Fluffy is a cat, what can we conclude?",
"mathematical": "A store offers 20% off, then an additional 15% off. What's the total discount?",
"strategic": "Should a startup focus on growth or profitability in its second year?",
"ethical": "Is it ethical to use AI for hiring decisions?"
}
for category, problem in problems.items():
print(f"\n{category.upper()} REASONING:")
print(f"Problem: {problem}")
# Extract reasoning
result = cot_agent.start(f"Solve this {category} problem with clear reasoning: {problem}")
print(f"Reasoning: {result}")
if __name__ == "__main__":
# Basic chain of thought demonstration
print("=== Chain of Thought Reasoning ===")
cot_result = cot_agent.start("""
A company's revenue increased by 40% but profit decreased by 10%.
What might this indicate about the company's situation?
Show your reasoning step by step.
""")
print(cot_result)
# Reasoning extraction workflow
print("\n=== Reasoning Extraction Workflow ===")
extraction_result = demonstrate_reasoning_extraction()
print(f"Result: {extraction_result}")
# Advanced reasoning patterns
print("\n=== Advanced Reasoning Patterns ===")
advanced_result = advanced_reasoning_patterns()
print(f"Result: {advanced_result}")
# Interactive demo
interactive_reasoning_demo()
# Summary
print("\n=== Reasoning Extraction Benefits ===")
print("1. Transparency: Makes decision-making process clear")
print("2. Debugging: Helps identify where reasoning might be flawed")
print("3. Learning: Extracts patterns for future use")
print("4. Trust: Builds confidence through explainable AI")
print("5. Improvement: Enables iterative refinement of reasoning")
@@ -0,0 +1,299 @@
"""
Routing Patterns Example
This example demonstrates various routing patterns in PraisonAI including:
- Conditional routing based on task outcomes
- Loop patterns for iterative processing
- Decision trees for complex workflows
- Dynamic task selection
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from typing import Dict, Any
import random
# Agents for different routing scenarios
analyzer_agent = Agent(
name="Analyzer",
role="Data analyst",
goal="Analyze input and determine appropriate routing",
backstory="You are an expert at analyzing data and making routing decisions.",
instructions="Analyze the input and determine the best path forward."
)
processor_agent = Agent(
name="Processor",
role="Data processor",
goal="Process data according to specific requirements",
backstory="You specialize in processing different types of data.",
instructions="Process the data based on the routing decision."
)
validator_agent = Agent(
name="Validator",
role="Quality validator",
goal="Validate processed data and determine if reprocessing is needed",
backstory="You ensure data quality and correctness.",
instructions="Validate the data and decide if it meets quality standards."
)
# Example 1: Basic Conditional Routing
def conditional_routing_example():
"""Demonstrates routing based on analysis results."""
# Initial analysis task
analysis_task = Task(
name="analyze_data",
description="Analyze the customer data and categorize as: high_value, medium_value, or low_value",
expected_output="Customer category: high_value, medium_value, or low_value",
agent=analyzer_agent,
task_type="decision",
condition={
"high_value": ["premium_processing"],
"medium_value": ["standard_processing"],
"low_value": ["basic_processing"]
}
)
# Different processing paths
premium_task = Task(
name="premium_processing",
description="Apply premium processing with personalized features",
expected_output="Premium processed data with personalization",
agent=processor_agent
)
standard_task = Task(
name="standard_processing",
description="Apply standard processing",
expected_output="Standard processed data",
agent=processor_agent
)
basic_task = Task(
name="basic_processing",
description="Apply basic processing",
expected_output="Basic processed data",
agent=processor_agent
)
workflow = PraisonAIAgents(
agents=[analyzer_agent, processor_agent],
tasks=[analysis_task, premium_task, standard_task, basic_task],
process="workflow",
verbose=True
)
return workflow.start()
# Example 2: Loop Pattern with Exit Condition
def loop_pattern_example():
"""Demonstrates iterative processing with loop control."""
# Process items in a loop until quality threshold is met
process_task = Task(
name="process_batch",
description="Process the current batch of items and check quality",
expected_output="Processed batch with quality score",
agent=processor_agent,
task_type="loop",
condition={
"quality below threshold": ["process_batch"], # Loop back
"quality meets threshold": ["finalize_batch"] # Exit loop
}
)
finalize_task = Task(
name="finalize_batch",
description="Finalize the batch processing and generate report",
expected_output="Final batch report",
agent=validator_agent
)
workflow = PraisonAIAgents(
agents=[processor_agent, validator_agent],
tasks=[process_task, finalize_task],
process="workflow",
verbose=True
)
return workflow.start()
# Example 3: Complex Decision Tree
def decision_tree_example():
"""Demonstrates multi-level decision tree routing."""
# Level 1: Initial categorization
categorize_task = Task(
name="categorize_request",
description="Categorize the request as: technical, business, or general",
expected_output="Request category",
agent=analyzer_agent,
task_type="decision",
condition={
"technical": ["technical_analysis"],
"business": ["business_analysis"],
"general": ["general_handling"]
}
)
# Level 2: Technical branch
technical_task = Task(
name="technical_analysis",
description="Analyze technical complexity: simple, moderate, or complex",
expected_output="Technical complexity level",
agent=analyzer_agent,
task_type="decision",
condition={
"simple": ["quick_fix"],
"moderate": ["standard_solution"],
"complex": ["expert_consultation"]
}
)
# Level 2: Business branch
business_task = Task(
name="business_analysis",
description="Analyze business impact: high, medium, or low",
expected_output="Business impact level",
agent=analyzer_agent,
task_type="decision",
condition={
"high": ["executive_review"],
"medium": ["manager_approval"],
"low": ["auto_approve"]
}
)
# Terminal tasks
terminal_tasks = [
Task(name="general_handling", description="Handle general request",
expected_output="General response", agent=processor_agent),
Task(name="quick_fix", description="Apply quick fix",
expected_output="Quick fix applied", agent=processor_agent),
Task(name="standard_solution", description="Apply standard solution",
expected_output="Standard solution applied", agent=processor_agent),
Task(name="expert_consultation", description="Consult with expert",
expected_output="Expert consultation result", agent=processor_agent),
Task(name="executive_review", description="Send for executive review",
expected_output="Executive decision", agent=processor_agent),
Task(name="manager_approval", description="Send for manager approval",
expected_output="Manager decision", agent=processor_agent),
Task(name="auto_approve", description="Auto-approve request",
expected_output="Auto-approved", agent=processor_agent)
]
all_tasks = [categorize_task, technical_task, business_task] + terminal_tasks
workflow = PraisonAIAgents(
agents=[analyzer_agent, processor_agent],
tasks=all_tasks,
process="workflow",
verbose=True
)
return workflow.start()
# Example 4: Dynamic Router Agent
dynamic_router = Agent(
name="DynamicRouter",
role="Intelligent routing specialist",
goal="Dynamically route tasks based on complex conditions",
backstory="You are an AI routing expert who can analyze multiple factors to determine optimal task paths.",
instructions="""Analyze the input and determine routing based on:
1. Content type and complexity
2. Priority and urgency
3. Available resources
4. Historical performance
5. Current system load
Provide clear routing decisions with reasoning.""",
self_reflect=True
)
def dynamic_routing_example():
"""Demonstrates dynamic routing based on multiple factors."""
# Custom routing function
def determine_route(task_output) -> str:
"""Custom function to determine routing based on output."""
# Simulate complex routing logic
factors = task_output.raw.lower()
if "urgent" in factors and "complex" in factors:
return "escalate"
elif "simple" in factors:
return "automate"
elif "review" in factors:
return "manual_review"
else:
return "standard"
# Dynamic routing task
route_task = Task(
name="dynamic_route",
description="""Analyze this request and determine routing:
- Request type: Customer complaint
- Complexity: Moderate
- Priority: Urgent
- Customer tier: Premium""",
expected_output="Routing decision with reasoning",
agent=dynamic_router,
task_type="decision",
condition=determine_route # Use custom function for routing
)
# Possible routes
escalate_task = Task(
name="escalate",
description="Escalate to senior team",
expected_output="Escalation complete",
agent=processor_agent
)
automate_task = Task(
name="automate",
description="Process automatically",
expected_output="Automated processing complete",
agent=processor_agent
)
review_task = Task(
name="manual_review",
description="Send for manual review",
expected_output="Manual review complete",
agent=processor_agent
)
standard_task = Task(
name="standard",
description="Standard processing",
expected_output="Standard processing complete",
agent=processor_agent
)
workflow = PraisonAIAgents(
agents=[dynamic_router, processor_agent],
tasks=[route_task, escalate_task, automate_task, review_task, standard_task],
process="workflow",
verbose=True
)
return workflow.start()
if __name__ == "__main__":
print("=== Conditional Routing Example ===")
result = conditional_routing_example()
print(f"Result: {result}\n")
print("=== Loop Pattern Example ===")
result = loop_pattern_example()
print(f"Result: {result}\n")
print("=== Decision Tree Example ===")
result = decision_tree_example()
print(f"Result: {result}\n")
print("=== Dynamic Routing Example ===")
result = dynamic_routing_example()
print(f"Result: {result}")
@@ -0,0 +1,263 @@
"""
Self-Reflection Details Example
This example demonstrates the self-reflection capabilities in PraisonAI agents:
- How self-reflection works
- Configuring reflection parameters
- Different reflection strategies
- Impact on output quality
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from typing import Dict, Any
import time
# Example 1: Basic Self-Reflection
basic_reflection_agent = Agent(
name="BasicReflector",
role="Content creator with self-improvement",
goal="Create high-quality content through iterative reflection",
backstory="You are a perfectionist writer who reviews and improves your work multiple times.",
instructions="""When creating content:
1. Write your initial draft
2. Review it critically
3. Identify areas for improvement
4. Revise and enhance
5. Repeat until satisfied""",
self_reflect=True, # Enable self-reflection
min_reflect=1, # Minimum 1 reflection iteration
max_reflect=3 # Maximum 3 reflection iterations
)
# Example 2: Advanced Reflection with Different Strategies
quality_focused_agent = Agent(
name="QualityFocused",
role="Quality-obsessed analyst",
goal="Produce extremely high-quality analysis through deep reflection",
backstory="You never settle for mediocre work and always strive for excellence.",
instructions="""Your reflection process should focus on:
- Accuracy and correctness
- Completeness of analysis
- Clarity of presentation
- Logical flow
- Supporting evidence""",
self_reflect=True,
min_reflect=3, # Higher minimum for quality
max_reflect=5 # Allow more iterations
)
efficiency_balanced_agent = Agent(
name="EfficiencyBalanced",
role="Balanced performer",
goal="Achieve good quality with reasonable reflection time",
backstory="You balance quality with efficiency, knowing when good enough is sufficient.",
instructions="Create good content with 1-2 rounds of improvement.",
self_reflect=True,
min_reflect=1,
max_reflect=2 # Limit iterations for efficiency
)
# Example 3: No Reflection for Comparison
no_reflection_agent = Agent(
name="NoReflection",
role="Quick responder",
goal="Provide immediate responses without reflection",
backstory="You provide quick, first-draft responses.",
instructions="Respond immediately with your first thought.",
self_reflect=False # Disable reflection
)
# Demonstration function to show reflection in action
def demonstrate_reflection_levels():
"""Show how different reflection settings affect output quality."""
test_prompt = """Write a compelling product description for an innovative smart water bottle that:
- Tracks hydration levels
- Reminds users to drink water
- Syncs with fitness apps
- Has a 24-hour battery life"""
print("=== Testing Different Reflection Levels ===\n")
# Test without reflection
print("1. WITHOUT REFLECTION:")
start_time = time.time()
result_no_reflect = no_reflection_agent.start(test_prompt)
time_no_reflect = time.time() - start_time
print(f"Time: {time_no_reflect:.2f}s")
print(f"Result: {result_no_reflect}\n")
# Test with basic reflection
print("2. BASIC REFLECTION (1-3 iterations):")
start_time = time.time()
result_basic = basic_reflection_agent.start(test_prompt)
time_basic = time.time() - start_time
print(f"Time: {time_basic:.2f}s")
print(f"Result: {result_basic}\n")
# Test with quality-focused reflection
print("3. QUALITY-FOCUSED REFLECTION (3-5 iterations):")
start_time = time.time()
result_quality = quality_focused_agent.start(test_prompt)
time_quality = time.time() - start_time
print(f"Time: {time_quality:.2f}s")
print(f"Result: {result_quality}\n")
# Example 4: Reflection in Multi-Agent Workflows
def reflection_workflow_example():
"""Demonstrate how reflection works in multi-agent scenarios."""
# Initial creator with reflection
creator_agent = Agent(
name="Creator",
role="Initial content creator",
goal="Create first draft with self-improvement",
backstory="You create initial drafts and refine them through reflection.",
self_reflect=True,
min_reflect=2,
max_reflect=3
)
# Reviewer without reflection (provides feedback)
reviewer_agent = Agent(
name="Reviewer",
role="Content reviewer",
goal="Provide constructive feedback",
backstory="You review content and provide specific improvement suggestions.",
self_reflect=False # No reflection needed for reviewing
)
# Final polisher with reflection
polisher_agent = Agent(
name="Polisher",
role="Final content polisher",
goal="Perfect the content based on feedback",
backstory="You take feedback and create the final, polished version.",
self_reflect=True,
min_reflect=1,
max_reflect=2
)
# Workflow tasks
create_task = Task(
name="create_content",
description="Create a blog post about 'The Future of AI in Healthcare' (200 words)",
expected_output="Initial blog post draft",
agent=creator_agent
)
review_task = Task(
name="review_content",
description="Review the blog post and provide specific feedback for improvement",
expected_output="Detailed feedback with specific suggestions",
agent=reviewer_agent,
context=[create_task]
)
polish_task = Task(
name="polish_content",
description="Create the final version incorporating all feedback",
expected_output="Polished final blog post",
agent=polisher_agent,
context=[create_task, review_task]
)
workflow = PraisonAIAgents(
agents=[creator_agent, reviewer_agent, polisher_agent],
tasks=[create_task, review_task, polish_task],
process="sequential",
verbose=True
)
return workflow.start()
# Example 5: Custom Reflection Control
class ReflectionController:
"""Custom controller to demonstrate programmatic reflection control."""
def __init__(self):
self.iteration_count = 0
self.quality_threshold = 0.8
def should_continue_reflecting(self, current_output: str) -> bool:
"""Custom logic to determine if more reflection is needed."""
self.iteration_count += 1
# Simple quality check (in practice, this could be more sophisticated)
quality_indicators = [
len(current_output) > 100,
'.' in current_output,
any(word in current_output.lower() for word in ['innovative', 'comprehensive', 'detailed'])
]
quality_score = sum(quality_indicators) / len(quality_indicators)
return quality_score < self.quality_threshold and self.iteration_count < 5
# Agent with custom reflection behavior
custom_reflection_agent = Agent(
name="CustomReflector",
role="Adaptive content creator",
goal="Create content with dynamic reflection based on quality",
backstory="You adapt your reflection process based on content quality.",
instructions="""Create content and reflect on it.
Continue improving until quality standards are met or maximum iterations reached.""",
self_reflect=True,
min_reflect=1,
max_reflect=5
)
# Example 6: Reflection Impact Analysis
def analyze_reflection_impact():
"""Analyze and visualize the impact of reflection on output."""
test_cases = [
"Explain quantum computing in one sentence",
"Write a haiku about artificial intelligence",
"Create a tagline for a sustainable energy company"
]
results = []
for test in test_cases:
print(f"\nTest Case: {test}")
print("-" * 50)
# Without reflection
result_no = no_reflection_agent.start(test)
# With reflection
result_yes = quality_focused_agent.start(test)
results.append({
'test': test,
'without_reflection': result_no,
'with_reflection': result_yes,
'improvement': len(result_yes) > len(result_no) # Simple metric
})
print(f"Without Reflection: {result_no}")
print(f"With Reflection: {result_yes}")
return results
if __name__ == "__main__":
# Demonstrate different reflection levels
demonstrate_reflection_levels()
# Show reflection in workflows
print("\n=== Reflection in Multi-Agent Workflow ===")
workflow_result = reflection_workflow_example()
print(f"Workflow Result: {workflow_result}")
# Analyze reflection impact
print("\n=== Reflection Impact Analysis ===")
impact_results = analyze_reflection_impact()
# Summary
print("\n=== Summary of Reflection Benefits ===")
print("1. Improved Quality: Reflection iterations allow agents to refine their outputs")
print("2. Error Correction: Agents can catch and fix mistakes through self-review")
print("3. Completeness: Multiple passes ensure all requirements are addressed")
print("4. Coherence: Reflection improves logical flow and consistency")
print("5. Customization: Reflection parameters can be tuned for different use cases")
@@ -0,0 +1,226 @@
# Minimal Latency Tracking for PraisonAI MCP Server
This solution provides latency tracking for MCP servers without modifying any PraisonAI core files. It's implemented as a custom tool that can be used externally.
## Overview
The latency tracking solution measures three key phases:
1. **Planning Process** - Time taken for agent planning and decision making
2. **Tool Usage** - Time spent executing tools
3. **LLM Answer Generation** - Time spent generating responses
## Quick Start
### Option 1: Use as a Custom Tool
```python
from latency_tracker_tool import latency_tracking_tool
# Add to your agent
agent = Agent(
name="Assistant",
role="Helper",
tools=[latency_tracking_tool]
)
# Track manually
latency_tracking_tool("start", "planning", "request_1")
response = agent.chat("Your query")
latency_tracking_tool("end", "planning", "request_1")
# Get metrics
metrics = latency_tracking_tool("metrics", request_id="request_1")
```
### Option 2: Use Context Managers
```python
from latency_tracker_tool import tracker
# Track with context manager
with tracker.track("planning", "request_1"):
response = agent.chat("Your query")
# Get metrics
metrics = tracker.get_metrics("request_1")
```
### Option 3: Use Wrapper Classes
```python
from latency_tracker_tool import create_tracked_agent
# Create tracked agent class
TrackedAgent = create_tracked_agent(Agent)
# Use like normal agent
agent = TrackedAgent(
name="Assistant",
role="Helper",
request_id="request_1"
)
# Operations are automatically tracked
response = agent.chat("Your query")
```
## MCP Server Integration
### Basic MCP Tracking
```python
from latency_tracker_tool import tracker
def handle_mcp_request(request_data):
request_id = request_data.get('id', 'default')
with tracker.track("total_request", request_id):
# Track planning
with tracker.track("planning", request_id):
plan = create_plan(request_data)
# Track tool usage
with tracker.track("tool_usage", request_id):
tool_results = execute_tools(plan)
# Track LLM generation
with tracker.track("llm_generation", request_id):
response = generate_response(tool_results)
# Include metrics in response
metrics = tracker.get_metrics(request_id)
return {
"response": response,
"latency_metrics": metrics
}
```
### Advanced MCP Server Wrapper
```python
from latency_tracker_tool import tracker
def add_tracking_to_mcp_server(mcp_server):
"""Add tracking to existing MCP server."""
original_handle = mcp_server.handle_request
def tracked_handle(request_data):
request_id = request_data.get('id', 'mcp_request')
with tracker.track("mcp_total", request_id):
response = original_handle(request_data)
return response
mcp_server.handle_request = tracked_handle
return mcp_server
```
## Tools with Built-in Tracking
Create a `tools.py` file in your project root:
```python
from latency_tracker_tool import track_latency, tracker
@track_latency("tool_search", "current_request")
def search_tool(query: str) -> str:
"""Search with automatic latency tracking."""
# Your search logic
return results
def get_latency_report(request_id: str = "current_request") -> str:
"""Get latency metrics as a tool."""
metrics = tracker.get_metrics(request_id)
# Format and return report
return formatted_report
```
## API Reference
### LatencyTracker Class
- `start_timer(phase, request_id)` - Start timing a phase
- `end_timer(phase, request_id)` - End timing and return elapsed time
- `track(phase, request_id)` - Context manager for tracking
- `get_metrics(request_id)` - Get metrics for a request
- `get_summary()` - Get summary of all requests
- `clear(request_id)` - Clear tracking data
### Metrics Format
```json
{
"planning": {
"count": 1,
"total": 1.234,
"average": 1.234,
"min": 1.234,
"max": 1.234,
"latest": 1.234
},
"tool_usage": {
"count": 3,
"total": 0.567,
"average": 0.189,
"min": 0.150,
"max": 0.250,
"latest": 0.167
}
}
```
## Examples
See the following example files:
- `example_latency_tracking.py` - Basic usage examples
- `mcp_server_latency_example.py` - MCP server integration
- `tools_with_latency.py` - Tools with built-in tracking
## Benefits
1. **No Core Modifications** - Works without changing PraisonAI source code
2. **Flexible** - Multiple ways to integrate (tool, decorator, wrapper, context manager)
3. **Thread-Safe** - Supports concurrent requests
4. **Minimal Overhead** - Lightweight tracking with negligible performance impact
5. **Extensible** - Easy to add custom phases and metrics
## Use Cases
1. **Performance Monitoring** - Track and optimize MCP server performance
2. **Debugging** - Identify bottlenecks in request processing
3. **SLA Monitoring** - Ensure response times meet requirements
4. **Capacity Planning** - Understand resource usage patterns
5. **A/B Testing** - Compare performance of different implementations
## Tips
1. Use unique request IDs for concurrent request tracking
2. Clear old tracking data periodically to free memory
3. Add tracking to critical paths only to minimize overhead
4. Use phase names consistently across your application
5. Consider logging metrics for long-term analysis
## Integration with Existing Monitoring
The metrics can be easily exported to monitoring systems:
```python
# Export to Prometheus
def export_to_prometheus():
summary = tracker.get_summary()
# Convert to Prometheus format
# Export to CloudWatch
def export_to_cloudwatch():
metrics = tracker.get_metrics()
# Send to CloudWatch
# Export to custom logging
import json
import logging
def log_metrics(request_id):
metrics = tracker.get_metrics(request_id)
logging.info(f"Latency metrics: {json.dumps(metrics)}")
```
@@ -0,0 +1,195 @@
"""
Example: Using Latency Tracking Tool with PraisonAI
This example shows how to track latency without modifying core files.
"""
from praisonaiagents import Agent, PraisonAIAgents
from latency_tracker_tool import (
latency_tracking_tool,
create_tracked_agent,
create_tracked_llm,
tracker,
get_latency_metrics,
get_latency_summary
)
import json
# Example 1: Using the latency tracking tool directly with agents
def example_with_tool():
"""Example using latency_tracking_tool as a custom tool."""
print("=== Example 1: Using Latency Tracking Tool ===\n")
# Create an agent with the latency tracking tool
researcher = Agent(
name="Researcher",
role="Information Researcher",
goal="Research and provide information",
tools=[latency_tracking_tool], # Add our custom tool
llm="gpt-4o-mini"
)
# Start tracking manually
latency_tracking_tool("start", "planning", "request_1")
# Agent performs task
response = researcher.chat("What is the capital of France?")
# End tracking
latency_tracking_tool("end", "planning", "request_1")
# Get metrics
metrics_json = latency_tracking_tool("metrics", request_id="request_1")
metrics = json.loads(metrics_json)
print(f"Response: {response}")
print(f"Metrics: {json.dumps(metrics, indent=2)}")
# Example 2: Using wrapper classes for automatic tracking
def example_with_wrappers():
"""Example using wrapper classes for automatic tracking."""
print("\n=== Example 2: Using Wrapper Classes ===\n")
# Create tracked agent class
TrackedAgent = create_tracked_agent(Agent)
# Create agent with tracking
analyst = TrackedAgent(
name="Analyst",
role="Data Analyst",
goal="Analyze data and provide insights",
llm="gpt-4o-mini",
request_id="request_2" # Unique request ID
)
# Operations are automatically tracked
response = analyst.chat("Calculate the sum of 1 to 10")
# Get metrics
metrics = get_latency_metrics("request_2")
print(f"Response: {response}")
print(f"Metrics: {json.dumps(metrics, indent=2)}")
# Example 3: Using context manager for fine-grained tracking
def example_with_context_manager():
"""Example using context manager for custom phase tracking."""
print("\n=== Example 3: Using Context Manager ===\n")
agent = Agent(
name="Calculator",
role="Math Expert",
goal="Solve mathematical problems",
llm="gpt-4o-mini"
)
request_id = "request_3"
# Track different phases manually
with tracker.track("initialization", request_id):
# Simulate initialization
pass
with tracker.track("planning", request_id):
response = agent.chat("What is 15% of 200?")
with tracker.track("post_processing", request_id):
# Simulate post-processing
result = f"Formatted result: {response}"
# Get comprehensive metrics
metrics = get_latency_metrics(request_id)
print(f"Result: {result}")
print(f"Metrics by phase:")
for phase, data in metrics.items():
print(f" {phase}: {data['total']:.3f}s")
# Example 4: Tracking MCP server requests
def example_mcp_tracking():
"""Example for tracking MCP server operations."""
print("\n=== Example 4: MCP Server Tracking ===\n")
# Simulate MCP server request handling
request_id = "mcp_request_1"
# Start tracking the entire request
with tracker.track("total_request", request_id):
# Track planning phase
with tracker.track("planning", request_id):
agent = Agent(
name="Assistant",
role="MCP Assistant",
goal="Handle MCP requests",
llm="gpt-4o-mini"
)
plan = agent.chat("Plan: Search for Python documentation")
# Track tool usage
with tracker.track("tool_usage", request_id):
# Simulate tool execution
tool_result = "Found 5 relevant documentation pages"
# Track LLM generation
with tracker.track("llm_generation", request_id):
final_response = agent.chat(f"Based on {tool_result}, provide a summary")
# Get detailed metrics
metrics = get_latency_metrics(request_id)
print("MCP Request Metrics:")
print(f"Total time: {metrics['total_request']['total']:.3f}s")
print(f"Breakdown:")
for phase in ['planning', 'tool_usage', 'llm_generation']:
if phase in metrics:
print(f" - {phase}: {metrics[phase]['total']:.3f}s")
# Example 5: Tracking multiple concurrent requests
def example_concurrent_tracking():
"""Example tracking multiple concurrent requests."""
print("\n=== Example 5: Concurrent Request Tracking ===\n")
# Simulate multiple MCP requests
for i in range(3):
request_id = f"concurrent_{i}"
with tracker.track("total", request_id):
agent = Agent(
name=f"Agent_{i}",
role="Concurrent Worker",
goal="Process requests concurrently",
llm="gpt-4o-mini"
)
with tracker.track("processing", request_id):
agent.chat(f"Process request {i}")
# Get summary of all requests
summary = get_latency_summary()
print("Summary of all requests:")
print(json.dumps(summary, indent=2))
if __name__ == "__main__":
# Run all examples
example_with_tool()
example_with_wrappers()
example_with_context_manager()
example_mcp_tracking()
example_concurrent_tracking()
# Final summary
print("\n=== Final Summary ===")
final_summary = get_latency_summary()
print(f"Total requests tracked: {len(final_summary)}")
# Clear all tracking data
tracker.clear()
print("\nAll tracking data cleared.")
@@ -0,0 +1,210 @@
"""
Minimal Latency Tracking Tool for PraisonAI MCP Server
This tool provides latency tracking without modifying core files.
It uses decorators and wrapper functions to track execution times
for planning, tool usage, and LLM generation phases.
"""
import time
import json
import threading
from typing import Dict, Any, Callable, Optional
from functools import wraps
from contextlib import contextmanager
class LatencyTracker:
"""Minimal latency tracking tool for MCP server operations."""
def __init__(self):
self._data = {}
self._lock = threading.Lock()
self._active_timers = {}
def start_timer(self, phase: str, request_id: str = "default"):
"""Start timing a phase."""
with self._lock:
key = f"{request_id}_{phase}"
self._active_timers[key] = time.time()
def end_timer(self, phase: str, request_id: str = "default") -> float:
"""End timing a phase and return elapsed time."""
with self._lock:
key = f"{request_id}_{phase}"
if key not in self._active_timers:
return 0.0
elapsed = time.time() - self._active_timers[key]
del self._active_timers[key]
# Store the timing
if request_id not in self._data:
self._data[request_id] = {}
if phase not in self._data[request_id]:
self._data[request_id][phase] = []
self._data[request_id][phase].append(elapsed)
return elapsed
@contextmanager
def track(self, phase: str, request_id: str = "default"):
"""Context manager for tracking a phase."""
self.start_timer(phase, request_id)
try:
yield
finally:
self.end_timer(phase, request_id)
def get_metrics(self, request_id: str = "default") -> Dict[str, Any]:
"""Get metrics for a specific request."""
with self._lock:
if request_id not in self._data:
return {}
metrics = {}
for phase, timings in self._data[request_id].items():
if timings:
metrics[phase] = {
'count': len(timings),
'total': sum(timings),
'average': sum(timings) / len(timings),
'min': min(timings),
'max': max(timings),
'latest': timings[-1]
}
return metrics
def get_summary(self) -> Dict[str, Any]:
"""Get summary of all tracked requests."""
with self._lock:
summary = {}
for request_id, phases in self._data.items():
summary[request_id] = self.get_metrics(request_id)
return summary
def clear(self, request_id: Optional[str] = None):
"""Clear tracking data."""
with self._lock:
if request_id:
self._data.pop(request_id, None)
else:
self._data.clear()
self._active_timers.clear()
# Global tracker instance
tracker = LatencyTracker()
def track_latency(phase: str, request_id: str = "default"):
"""Decorator to track function execution latency."""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args, **kwargs):
with tracker.track(phase, request_id):
return func(*args, **kwargs)
return wrapper
return decorator
def create_tracked_agent(agent_class):
"""Create a wrapper class that tracks agent operations."""
class TrackedAgent(agent_class):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._request_id = kwargs.get('request_id', 'default')
def chat(self, *args, **kwargs):
"""Tracked chat method for planning phase."""
with tracker.track('planning', self._request_id):
return super().chat(*args, **kwargs)
def execute_tool(self, *args, **kwargs):
"""Tracked execute_tool method."""
with tracker.track('tool_usage', self._request_id):
return super().execute_tool(*args, **kwargs)
return TrackedAgent
def create_tracked_llm(llm_class):
"""Create a wrapper class that tracks LLM operations."""
class TrackedLLM(llm_class):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._request_id = kwargs.get('request_id', 'default')
def get_response(self, *args, **kwargs):
"""Tracked get_response method for LLM generation."""
with tracker.track('llm_generation', self._request_id):
return super().get_response(*args, **kwargs)
return TrackedLLM
# Custom tool function for manual tracking
def latency_tracking_tool(action: str, phase: str = "", request_id: str = "default") -> str:
"""
Manual latency tracking tool for PraisonAI agents.
Args:
action: One of 'start', 'end', 'metrics', 'summary', 'clear'
phase: Phase name (for 'start' and 'end' actions)
request_id: Request identifier for tracking
Returns:
str: JSON string with results
"""
if action == "start":
if not phase:
return json.dumps({"error": "Phase name required for start action"})
tracker.start_timer(phase, request_id)
return json.dumps({"status": "started", "phase": phase, "request_id": request_id})
elif action == "end":
if not phase:
return json.dumps({"error": "Phase name required for end action"})
elapsed = tracker.end_timer(phase, request_id)
return json.dumps({
"status": "ended",
"phase": phase,
"request_id": request_id,
"elapsed": elapsed
})
elif action == "metrics":
metrics = tracker.get_metrics(request_id)
return json.dumps({"request_id": request_id, "metrics": metrics})
elif action == "summary":
summary = tracker.get_summary()
return json.dumps({"summary": summary})
elif action == "clear":
tracker.clear(request_id)
return json.dumps({"status": "cleared", "request_id": request_id})
else:
return json.dumps({"error": f"Unknown action: {action}"})
# Convenience functions for external use
def start_tracking(phase: str, request_id: str = "default"):
"""Start tracking a phase."""
tracker.start_timer(phase, request_id)
def end_tracking(phase: str, request_id: str = "default") -> float:
"""End tracking a phase and return elapsed time."""
return tracker.end_timer(phase, request_id)
def get_latency_metrics(request_id: str = "default") -> Dict[str, Any]:
"""Get latency metrics for a request."""
return tracker.get_metrics(request_id)
def get_latency_summary() -> Dict[str, Any]:
"""Get summary of all latency tracking."""
return tracker.get_summary()
@@ -0,0 +1,173 @@
"""
MCP Server with Latency Tracking Example
This shows how to add latency tracking to an MCP server
without modifying PraisonAI core files.
"""
from praisonaiagents import Agent, PraisonAIAgents
from praisonaiagents.mcp import HostedMCPServer
from latency_tracker_tool import tracker, get_latency_metrics
import json
class LatencyTrackedMCPServer(HostedMCPServer):
"""MCP Server with built-in latency tracking."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Import and use the original agents, not wrapped ones
self._original_handle_request = self.handle_request
self.handle_request = self._tracked_handle_request
def _tracked_handle_request(self, request_data):
"""Wrapped request handler with latency tracking."""
request_id = request_data.get('id', 'mcp_request')
# Track the entire request
with tracker.track("mcp_total_request", request_id):
# Call original handler
response = self._original_handle_request(request_data)
# Add latency metrics to response if requested
if request_data.get('include_latency_metrics', False):
metrics = get_latency_metrics(request_id)
response['latency_metrics'] = metrics
return response
def create_mcp_agent_with_tracking(request_id: str = "mcp_request"):
"""Create an agent that tracks its operations."""
class TrackedOperationAgent(Agent):
"""Agent that tracks planning, tool usage, and LLM calls."""
def chat(self, *args, **kwargs):
with tracker.track("planning", request_id):
return super().chat(*args, **kwargs)
def execute_tool(self, *args, **kwargs):
with tracker.track("tool_usage", request_id):
return super().execute_tool(*args, **kwargs)
# Create the tracked agent
agent = TrackedOperationAgent(
name="MCPAssistant",
role="MCP Request Handler",
goal="Handle MCP requests with latency tracking",
llm="gpt-4o-mini"
)
return agent
# Example usage for MCP server operators
def example_mcp_with_tracking():
"""Example showing how to use latency tracking with MCP server."""
print("=== MCP Server Latency Tracking Example ===\n")
# Simulate handling an MCP request
request_id = "mcp_example_1"
# Create tracked agent
agent = create_mcp_agent_with_tracking(request_id)
# Simulate the three phases mentioned in the issue
print("1. Planning Phase:")
with tracker.track("planning", request_id):
planning_result = agent.chat("Plan how to search for Python async documentation")
print(f" Plan: {planning_result[:100]}...")
print("\n2. Tool Usage Phase:")
# If you have actual tools, they would be executed here
with tracker.track("tool_usage", request_id):
# Simulate tool execution
import time
time.sleep(0.1) # Simulate tool delay
tool_result = "Found 10 documentation pages about Python async"
print(f" Tool result: {tool_result}")
print("\n3. LLM Answer Generation Phase:")
with tracker.track("llm_generation", request_id):
final_answer = agent.chat(f"Based on finding that {tool_result}, provide a concise summary")
print(f" Answer: {final_answer[:100]}...")
# Get and display metrics
print("\n=== Latency Metrics ===")
metrics = get_latency_metrics(request_id)
for phase, data in metrics.items():
print(f"{phase}:")
print(f" - Total time: {data['total']:.3f}s")
print(f" - Count: {data['count']}")
print(f" - Average: {data['average']:.3f}s")
# Calculate total time
total_time = sum(data['total'] for data in metrics.values())
print(f"\nTotal execution time: {total_time:.3f}s")
# Show percentage breakdown
print("\nTime breakdown:")
for phase, data in metrics.items():
percentage = (data['total'] / total_time) * 100
print(f" - {phase}: {percentage:.1f}%")
# Function to wrap existing MCP server with tracking
def add_tracking_to_mcp_server(mcp_server):
"""Add latency tracking to an existing MCP server instance."""
original_handle = mcp_server.handle_request
def tracked_handle(request_data):
request_id = request_data.get('id', 'mcp_request')
with tracker.track("mcp_request_total", request_id):
# You can add more granular tracking here based on request type
request_type = request_data.get('method', 'unknown')
with tracker.track(f"mcp_{request_type}", request_id):
response = original_handle(request_data)
return response
mcp_server.handle_request = tracked_handle
return mcp_server
# Utility function for MCP server monitoring
def get_mcp_latency_summary():
"""Get a formatted summary of MCP server latency."""
summary = tracker.get_summary()
if not summary:
return "No MCP requests tracked yet."
report = "MCP Server Latency Summary\n"
report += "=" * 50 + "\n"
for request_id, metrics in summary.items():
if request_id.startswith("mcp_"):
report += f"\nRequest: {request_id}\n"
total_time = 0
for phase, data in metrics.items():
phase_time = data['total']
total_time += phase_time
report += f" {phase}: {phase_time:.3f}s\n"
report += f" Total: {total_time:.3f}s\n"
return report
if __name__ == "__main__":
# Run the example
example_mcp_with_tracking()
# Show overall summary
print("\n" + "=" * 50)
print(get_mcp_latency_summary())
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""
Minimal Example: Latency Tracking for MCP Server
This is the simplest way to add latency tracking to your MCP server
without modifying any core PraisonAI files.
"""
from praisonaiagents import Agent
from latency_tracker_tool import tracker
import time
# Example: Track MCP request handling
def handle_mcp_request(query: str, request_id: str = "mcp_1"):
"""Simulate handling an MCP request with latency tracking."""
print(f"\nHandling MCP request: {request_id}")
print(f"Query: {query}")
# 1. Planning Phase
tracker.start_timer("planning", request_id)
agent = Agent(
name="Assistant",
role="MCP Handler",
goal="Process requests",
llm="gpt-4o-mini"
)
plan = f"I will search for information about {query}"
time.sleep(0.1) # Simulate planning time
planning_time = tracker.end_timer("planning", request_id)
# 2. Tool Usage Phase
tracker.start_timer("tool_usage", request_id)
# Simulate tool execution
time.sleep(0.2) # Simulate tool execution time
tool_result = f"Found 5 results for {query}"
tool_time = tracker.end_timer("tool_usage", request_id)
# 3. LLM Generation Phase
tracker.start_timer("llm_generation", request_id)
# In real usage, this would be: response = agent.chat(prompt)
time.sleep(0.15) # Simulate LLM response time
response = f"Based on my search, here's information about {query}..."
llm_time = tracker.end_timer("llm_generation", request_id)
# Get metrics
metrics = tracker.get_metrics(request_id)
# Display results
print(f"\nResponse: {response}")
print(f"\nLatency Breakdown:")
print(f" Planning: {planning_time:.3f}s")
print(f" Tool Usage: {tool_time:.3f}s")
print(f" LLM Generation: {llm_time:.3f}s")
print(f" Total: {planning_time + tool_time + llm_time:.3f}s")
return response, metrics
if __name__ == "__main__":
# Simulate multiple MCP requests
queries = [
"Python async programming",
"Machine learning basics",
"Docker best practices"
]
for i, query in enumerate(queries):
handle_mcp_request(query, f"mcp_request_{i}")
# Show summary
print("\n" + "="*50)
print("OVERALL LATENCY SUMMARY")
print("="*50)
summary = tracker.get_summary()
for request_id, phases in summary.items():
print(f"\n{request_id}:")
total = sum(phase_data['total'] for phase_data in phases.values())
for phase, data in phases.items():
percentage = (data['total'] / total) * 100
print(f" {phase}: {data['total']:.3f}s ({percentage:.1f}%)")
@@ -0,0 +1,150 @@
"""
Example tools.py file with integrated latency tracking.
This shows how to add latency tracking to your tools without modifying core files.
Place this as tools.py in your project root for automatic loading.
"""
import time
from typing import List, Dict
from latency_tracker_tool import tracker, track_latency
# Example 1: Simple tool with manual tracking
def search_with_tracking(query: str) -> str:
"""
Search tool with built-in latency tracking.
Args:
query: Search query string
Returns:
str: Search results
"""
# Manual tracking approach
tracker.start_timer("tool_search", "current_request")
# Simulate search operation
time.sleep(0.1) # Simulate API call
result = f"Found 3 results for '{query}'"
elapsed = tracker.end_timer("tool_search", "current_request")
# Include timing in result (optional)
return f"{result} (took {elapsed:.3f}s)"
# Example 2: Tool with decorator-based tracking
@track_latency("tool_calculation", "current_request")
def calculate_with_tracking(expression: str) -> str:
"""
Calculator tool with automatic latency tracking via decorator.
Args:
expression: Mathematical expression to evaluate
Returns:
str: Calculation result
"""
# Simulate calculation
time.sleep(0.05)
try:
result = eval(expression)
return f"Result: {result}"
except Exception as e:
return f"Error: {str(e)}"
# Example 3: Tool with context manager tracking
def analyze_with_tracking(data: str) -> Dict[str, any]:
"""
Analysis tool with fine-grained latency tracking.
Args:
data: Data to analyze
Returns:
dict: Analysis results with timing breakdown
"""
results = {}
# Track different phases of analysis
with tracker.track("analysis_preprocessing", "current_request"):
# Simulate preprocessing
time.sleep(0.02)
processed_data = data.lower().strip()
with tracker.track("analysis_main", "current_request"):
# Simulate main analysis
time.sleep(0.08)
word_count = len(processed_data.split())
char_count = len(processed_data)
with tracker.track("analysis_postprocessing", "current_request"):
# Simulate postprocessing
time.sleep(0.01)
results = {
"word_count": word_count,
"char_count": char_count,
"processed": True
}
# Get metrics for this analysis
metrics = tracker.get_metrics("current_request")
if "analysis_preprocessing" in metrics:
results["timing"] = {
"preprocessing": metrics["analysis_preprocessing"]["latest"],
"main": metrics["analysis_main"]["latest"],
"postprocessing": metrics["analysis_postprocessing"]["latest"]
}
return results
# Latency reporting tool - allows agents to get latency metrics
def get_latency_report(request_id: str = "current_request") -> str:
"""
Get a latency report for the current or specified request.
Args:
request_id: Request identifier (default: "current_request")
Returns:
str: Formatted latency report
"""
metrics = tracker.get_metrics(request_id)
if not metrics:
return "No latency data available for this request."
report = f"Latency Report for {request_id}:\n"
report += "-" * 40 + "\n"
total_time = 0
for phase, data in metrics.items():
phase_time = data['total']
total_time += phase_time
report += f"{phase}: {phase_time:.3f}s (avg: {data['average']:.3f}s, count: {data['count']})\n"
report += "-" * 40 + "\n"
report += f"Total tracked time: {total_time:.3f}s\n"
return report
# Clear latency data tool
def clear_latency_data(request_id: str = None) -> str:
"""
Clear latency tracking data.
Args:
request_id: Specific request to clear (None clears all)
Returns:
str: Confirmation message
"""
tracker.clear(request_id)
if request_id:
return f"Cleared latency data for request: {request_id}"
else:
return "Cleared all latency tracking data"
+141
View File
@@ -0,0 +1,141 @@
"""
Advanced handoff example with callbacks, input types, and filters.
This example demonstrates advanced handoff features including:
- Custom handoff callbacks
- Structured input data
- Input filters
- Custom tool names and descriptions
"""
from praisonaiagents import Agent, handoff, handoff_filters, prompt_with_handoff_instructions
from pydantic import BaseModel
from typing import Optional
import logging
logging.basicConfig(level=logging.INFO)
# Define structured input for escalation
class EscalationData(BaseModel):
reason: str
priority: Optional[str] = "normal"
customer_sentiment: Optional[str] = None
# Callback function for logging handoffs
def log_handoff(source_agent: Agent):
"""Log when a handoff occurs"""
logging.info(f"Handoff initiated from {source_agent.name}")
# Callback function with input data
def log_escalation(source_agent: Agent, input_data: EscalationData):
"""Log escalation with structured data"""
logging.info(f"ESCALATION from {source_agent.name}: {input_data.reason} (Priority: {input_data.priority})")
# Create specialized agents
faq_agent = Agent(
name="FAQ Agent",
role="FAQ Specialist",
goal="Answer frequently asked questions using knowledge base",
backstory="I have access to comprehensive FAQ documentation and can quickly provide accurate answers."
)
escalation_agent = Agent(
name="Escalation Agent",
role="Senior Support Manager",
goal="Handle escalated issues that require special attention",
backstory="I handle complex cases that need senior-level intervention and decision-making."
)
# Create support agent with custom handoffs
support_agent = Agent(
name="Support Agent",
role="Customer Support Representative",
goal="Provide first-line support and escalate when necessary",
backstory="I help customers with their issues and know when to involve specialists.",
instructions=prompt_with_handoff_instructions(
"""Help customers with their requests. You should:
1. Try to resolve issues yourself first
2. Transfer to FAQ Agent for common questions you can't answer
3. Escalate to senior management for complex or sensitive issues
When escalating, always provide a clear reason and assess the priority.""",
None # Agent will be set later
),
handoffs=[
# Simple handoff with callback
handoff(
faq_agent,
on_handoff=log_handoff,
input_filter=handoff_filters.remove_all_tools # Remove tool calls from history
),
# Advanced handoff with structured input
handoff(
escalation_agent,
tool_name_override="escalate_to_manager",
tool_description_override="Escalate complex or sensitive issues to senior management",
on_handoff=log_escalation,
input_type=EscalationData
)
]
)
# Update the instructions with the agent reference
support_agent.instructions = prompt_with_handoff_instructions(
support_agent.instructions,
support_agent
)
# Example with custom input filter
def custom_filter(data):
"""Keep only last 3 messages and remove system messages"""
data = handoff_filters.keep_last_n_messages(3)(data)
data = handoff_filters.remove_system_messages(data)
return data
# Agent with custom filtered handoff
filtered_agent = Agent(
name="Filtered Support",
role="Support with Privacy",
goal="Handle support while maintaining privacy",
backstory="I ensure customer privacy by filtering sensitive conversation history.",
handoffs=[
handoff(
faq_agent,
tool_description_override="Transfer to FAQ (filtered history)",
input_filter=custom_filter
)
]
)
# Example usage
if __name__ == "__main__":
print("=== Advanced Handoff Examples ===\n")
# Test escalation with structured data
print("Test 1: Escalation with structured input")
response = support_agent.chat(
"I've been waiting for my refund for 3 weeks and I'm very frustrated! "
"I need this resolved immediately or I'll take legal action!"
)
print(f"Response: {response}\n")
# Test FAQ handoff
print("\nTest 2: FAQ handoff with filtering")
response = support_agent.chat(
"How do I reset my password? I can't find the option in settings."
)
print(f"Response: {response}\n")
# Test filtered handoff
print("\nTest 3: Filtered handoff")
# Add some conversation history
filtered_agent.chat("My account number is 12345")
filtered_agent.chat("I have a sensitive issue")
response = filtered_agent.chat("I need help with FAQ about privacy policy")
print(f"Response: {response}\n")
+61
View File
@@ -0,0 +1,61 @@
"""
Basic handoff example demonstrating agent-to-agent delegation.
This example shows how agents can hand off tasks to specialized agents.
"""
from praisonaiagents import Agent
# Create specialized agents
billing_agent = Agent(
name="Billing Agent",
role="Billing Specialist",
goal="Handle all billing-related inquiries and tasks",
backstory="I am an expert in billing systems, payment processing, and invoice management."
)
refund_agent = Agent(
name="Refund Agent",
role="Refund Specialist",
goal="Process refund requests and handle refund-related issues",
backstory="I specialize in processing refunds, evaluating refund eligibility, and ensuring customer satisfaction."
)
technical_support_agent = Agent(
name="Technical Support",
role="Technical Support Specialist",
goal="Resolve technical issues and provide technical assistance",
backstory="I am skilled in troubleshooting technical problems and providing solutions."
)
# Create a triage agent with handoffs to specialized agents
triage_agent = Agent(
name="Triage Agent",
role="Customer Service Triage",
goal="Understand customer needs and route them to the appropriate specialist",
backstory="I analyze customer requests and direct them to the most suitable specialist for efficient resolution.",
instructions="""Analyze the customer's request and determine which specialist can best help:
- For billing questions, payment issues, or invoices, transfer to the Billing Agent
- For refund requests or refund status inquiries, transfer to the Refund Agent
- For technical problems or product issues, transfer to Technical Support
Always explain why you're transferring the customer before doing so.""",
handoffs=[billing_agent, refund_agent, technical_support_agent]
)
# Example usage
if __name__ == "__main__":
print("=== Customer Service Triage System ===\n")
# Test different types of requests
test_requests = [
"I need a refund for my last purchase",
"Why was I charged twice on my credit card?",
"The app keeps crashing when I try to login"
]
for request in test_requests:
print(f"\nCustomer: {request}")
response = triage_agent.chat(request)
print(f"Response: {response}")
print("-" * 50)
@@ -0,0 +1,162 @@
"""
Complete customer service workflow example with handoffs.
This example demonstrates a realistic customer service scenario with:
- Order status checking
- Refund processing
- Technical support
- FAQ handling
- Escalation management
"""
from praisonaiagents import Agent, handoff, RECOMMENDED_PROMPT_PREFIX
import random
# Mock functions for demonstration
def check_order_status(order_id: str) -> str:
"""Check the status of an order"""
statuses = ["shipped", "processing", "delivered", "pending"]
return f"Order {order_id} is {random.choice(statuses)}"
def process_refund(order_id: str, reason: str) -> str:
"""Process a refund request"""
return f"Refund initiated for order {order_id}. Reason: {reason}. Expected in 3-5 business days."
def get_faq_answer(question: str) -> str:
"""Get answer from FAQ database"""
faqs = {
"shipping": "Standard shipping takes 5-7 business days. Express shipping takes 2-3 business days.",
"returns": "You can return items within 30 days of purchase in original condition.",
"warranty": "All products come with a 1-year manufacturer warranty.",
"payment": "We accept credit cards, debit cards, PayPal, and Apple Pay."
}
for key, answer in faqs.items():
if key in question.lower():
return answer
return "I'll need to check our documentation for that specific question."
# Create specialized agents with tools
order_agent = Agent(
name="Order Specialist",
role="Order Management Specialist",
goal="Handle all order-related inquiries including tracking, modifications, and status updates",
backstory="I specialize in order management and have access to the order tracking system.",
tools=[check_order_status],
instructions=f"""{RECOMMENDED_PROMPT_PREFIX}
I can help with:
- Checking order status
- Tracking shipments
- Order modifications
- Delivery issues
For refunds, I'll transfer you to our Refund Specialist.
For technical issues, I'll connect you with Technical Support."""
)
refund_agent = Agent(
name="Refund Specialist",
role="Refund and Returns Specialist",
goal="Process refunds and handle return requests efficiently",
backstory="I'm authorized to process refunds and handle all return-related matters.",
tools=[process_refund],
instructions="""I process refunds and returns. I need the order ID and reason for the refund.
I ensure all refunds are processed according to our policy."""
)
faq_agent = Agent(
name="FAQ Assistant",
role="Knowledge Base Specialist",
goal="Provide quick answers to frequently asked questions",
backstory="I have access to our comprehensive FAQ database.",
tools=[get_faq_answer],
instructions="I provide answers to common questions about shipping, returns, warranty, and payments."
)
technical_agent = Agent(
name="Technical Support",
role="Technical Support Engineer",
goal="Resolve technical issues with products and services",
backstory="I'm trained in troubleshooting all our products and technical services.",
instructions="""I help with:
- Product setup and configuration
- Troubleshooting technical issues
- Software problems
- Hardware diagnostics"""
)
escalation_agent = Agent(
name="Senior Manager",
role="Customer Experience Manager",
goal="Handle escalated issues and ensure customer satisfaction",
backstory="I'm a senior manager with authority to make exceptions and handle complex cases.",
instructions="""I handle:
- Escalated complaints
- Special requests requiring manager approval
- Complex issues that need executive decisions
- Customer retention situations"""
)
# Create main customer service agent with handoffs
customer_service_agent = Agent(
name="Customer Service",
role="Customer Service Representative",
goal="Provide excellent customer service by understanding needs and routing to the right specialist",
backstory="I'm your first point of contact and I'll make sure you get the help you need.",
instructions=f"""{RECOMMENDED_PROMPT_PREFIX}
Welcome! I'm here to help you today. I can assist with various requests or connect you with the right specialist:
- For order tracking and status → Order Specialist
- For refunds and returns → Refund Specialist
- For common questions → FAQ Assistant
- For technical problems → Technical Support
- For complaints or special requests → Senior Manager
How can I help you today?""",
handoffs=[
order_agent,
refund_agent,
faq_agent,
technical_agent,
handoff(
escalation_agent,
tool_description_override="Escalate to senior management for complex issues or complaints"
)
]
)
# Example interaction
if __name__ == "__main__":
print("=== Customer Service System ===")
print("Welcome to our customer service! Type 'quit' to exit.\n")
# Simulated customer interactions
test_scenarios = [
"I need to check the status of my order #12345",
"I want a refund for order #67890, the product was damaged",
"What's your return policy?",
"My device won't turn on after the update",
"I'm very unhappy with the service and want to speak to a manager!",
"How long does shipping usually take?"
]
print("Running automated test scenarios:\n")
for scenario in test_scenarios:
print(f"Customer: {scenario}")
response = customer_service_agent.chat(scenario)
print(f"Agent: {response}")
print("-" * 80)
# Interactive mode
print("\nNow entering interactive mode. You can ask questions directly:")
while True:
user_input = input("\nYou: ")
if user_input.lower() == 'quit':
break
response = customer_service_agent.chat(user_input)
print(f"Agent: {response}")
+167
View File
@@ -0,0 +1,167 @@
# Agent Handoffs
Agent handoffs allow agents to delegate tasks to other specialized agents. This is useful when you have agents with different areas of expertise that need to collaborate.
## Basic Usage
```python
from praisonaiagents import Agent, handoff
# Create specialized agents
billing_agent = Agent(name="Billing Agent", role="Billing Specialist")
refund_agent = Agent(name="Refund Agent", role="Refund Specialist")
# Create main agent with handoffs
triage_agent = Agent(
name="Triage Agent",
role="Customer Service",
handoffs=[billing_agent, refund_agent] # Can hand off to these agents
)
```
## How Handoffs Work
1. Handoffs are automatically converted to tools that the agent can use
2. The agent decides when to hand off based on the conversation context
3. When a handoff occurs, the target agent receives the conversation history
4. The target agent's response is returned to the user
## Advanced Features
### Custom Handoff Configuration
Use the `handoff()` function for more control:
```python
from praisonaiagents import Agent, handoff
agent = Agent(name="Target Agent")
custom_handoff = handoff(
agent=agent,
tool_name_override="escalate_to_specialist",
tool_description_override="Escalate complex issues to a specialist",
on_handoff=lambda ctx: print(f"Handoff from {ctx.name}"),
input_filter=handoff_filters.remove_all_tools
)
main_agent = Agent(
name="Main Agent",
handoffs=[custom_handoff]
)
```
### Handoff Callbacks
Execute custom logic when a handoff occurs:
```python
# Create target agent
target_agent = Agent(name="Target Agent", role="Specialist")
def log_handoff(source_agent):
print(f"Handoff initiated from {source_agent.name}")
handoff_with_callback = handoff(
target_agent,
on_handoff=log_handoff
)
```
### Structured Input
Require specific data when handing off:
```python
from pydantic import BaseModel
class EscalationData(BaseModel):
reason: str
priority: str
# Create escalation agent
escalation_agent = Agent(name="Escalation Agent", role="Senior Manager")
def handle_escalation(source_agent, data: EscalationData):
print(f"Escalation: {data.reason} (Priority: {data.priority})")
escalation_handoff = handoff(
escalation_agent,
on_handoff=handle_escalation,
input_type=EscalationData
)
```
### Input Filters
Control what conversation history is passed to the target agent:
```python
from praisonaiagents import handoff_filters
# Create target agent for filtering examples
agent = Agent(name="Target Agent", role="Specialist")
# Remove all tool calls from history
filtered_handoff = handoff(
agent,
input_filter=handoff_filters.remove_all_tools
)
# Keep only last N messages
limited_handoff = handoff(
agent,
input_filter=handoff_filters.keep_last_n_messages(5)
)
# Remove system messages
clean_handoff = handoff(
agent,
input_filter=handoff_filters.remove_system_messages
)
```
## Recommended Prompts
Include handoff instructions in your agent prompts:
```python
from praisonaiagents import RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions
# Create specialized agents
billing_agent = Agent(name="Billing Agent", role="Billing Specialist")
technical_agent = Agent(name="Technical Agent", role="Technical Support")
agent = Agent(
name="Support Agent",
handoffs=[billing_agent, technical_agent]
)
# After creating the agent, update its instructions
agent.instructions = prompt_with_handoff_instructions(
"Help customers and transfer to specialists when needed.",
agent # Pass the agent to auto-generate handoff info
)
```
## Complete Example
See the examples directory for complete working examples:
- `examples/handoff_basic.py` - Simple handoff demonstration
- `examples/handoff_advanced.py` - Advanced features with callbacks and filters
- `examples/handoff_customer_service.py` - Real-world customer service workflow
## Best Practices
1. **Clear Role Definition**: Give each agent a clear role and area of expertise
2. **Handoff Instructions**: Include when to hand off in agent instructions
3. **Context Preservation**: Use input filters carefully to maintain necessary context
4. **Logging**: Use callbacks to track handoffs for debugging and analytics
5. **Testing**: Test handoff paths to ensure smooth transitions
## Backward Compatibility
The handoff feature is fully backward compatible:
- Existing agents work without modification
- The `handoffs` parameter is optional
- All existing agent functionality is preserved
@@ -0,0 +1,163 @@
"""
Advanced Dynamic Input Example for PraisonAI
This example demonstrates an advanced system that dynamically creates agents and tasks
based on user inputs, including conditional logic, custom configurations, and file output.
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
import os
from typing import Dict, List
class DynamicAgentSystem:
"""Advanced system for handling dynamic user inputs"""
def __init__(self):
self.user_preferences = {}
self.llm_config = {
"model": os.getenv("LLM_MODEL", "gpt-4o-mini"),
"temperature": 0.7
}
def collect_user_inputs(self) -> Dict[str, str]:
"""Collect multiple user inputs"""
inputs = {}
inputs['topic'] = input("What topic would you like to explore? ")
inputs['depth'] = input("Analysis depth (quick/detailed)? ").lower() or "quick"
inputs['output_format'] = input("Output format (summary/report/bullets)? ").lower() or "summary"
inputs['language'] = input("Language preference (en/es/fr)? ").lower() or "en"
return inputs
def create_dynamic_agents(self, inputs: Dict[str, str]) -> List[Agent]:
"""Create agents based on user inputs"""
agents = []
# Research agent with dynamic configuration
research_agent = Agent(
name="ResearchExpert",
role=f"{'Detailed' if inputs['depth'] == 'detailed' else 'Quick'} Research Specialist",
goal=f"Conduct {inputs['depth']} research on {inputs['topic']} in {inputs['language']}",
backstory=f"Multilingual expert specializing in {inputs['depth']} analysis",
tools=[duckduckgo],
self_reflect=inputs['depth'] == 'detailed',
llm=self.llm_config
)
agents.append(research_agent)
# Format agent based on output preference
format_agent = Agent(
name="FormatExpert",
role=f"{inputs['output_format'].title()} Formatter",
goal=f"Format research into {inputs['output_format']} style",
backstory=f"Expert in creating {inputs['output_format']} documents",
llm=self.llm_config
)
agents.append(format_agent)
# Optional quality agent for detailed analysis
if inputs['depth'] == 'detailed':
quality_agent = Agent(
name="QualityChecker",
role="Quality Assurance Specialist",
goal="Verify accuracy and completeness",
backstory="Expert in fact-checking and quality control",
llm=self.llm_config
)
agents.append(quality_agent)
return agents
def create_dynamic_tasks(self, agents: List[Agent], inputs: Dict[str, str]) -> List[Task]:
"""Create tasks based on user inputs and agents"""
tasks = []
# Research task
research_task = Task(
description=f"""
Research '{inputs['topic']}' with the following requirements:
- Depth: {inputs['depth']}
- Language: {inputs['language']}
- Find {'5-10' if inputs['depth'] == 'detailed' else '3-5'} key points
- Include sources and citations
""",
expected_output=f"Research findings about {inputs['topic']} with sources",
agent=agents[0], # Research agent
name="research_phase"
)
tasks.append(research_task)
# Formatting task
format_instructions = {
'summary': "Create a concise paragraph summary",
'report': "Create a structured report with sections",
'bullets': "Create a bullet-point list of key findings"
}
format_task = Task(
description=f"""
Format the research findings as follows:
- Style: {format_instructions[inputs['output_format']]}
- Language: {inputs['language']}
- Maintain all source citations
""",
expected_output=f"{inputs['output_format'].title()} of {inputs['topic']}",
agent=agents[1], # Format agent
context=[research_task],
name="formatting_phase"
)
tasks.append(format_task)
# Quality check task (if detailed)
if inputs['depth'] == 'detailed' and len(agents) > 2:
quality_task = Task(
description="Verify all facts, check sources, and ensure completeness",
expected_output="Quality-assured final output with verification notes",
agent=agents[2], # Quality agent
context=[format_task],
name="quality_phase"
)
tasks.append(quality_task)
return tasks
def run(self):
"""Main execution flow"""
# Collect inputs
print("🎯 PraisonAI Dynamic Input System")
print("-" * 40)
inputs = self.collect_user_inputs()
# Create dynamic agents and tasks
agents = self.create_dynamic_agents(inputs)
tasks = self.create_dynamic_tasks(agents, inputs)
# Configure process based on depth
process = "hierarchical" if inputs['depth'] == 'detailed' else "sequential"
# Run the system
print(f"\n🚀 Starting {process} analysis for '{inputs['topic']}'...")
praison_agents = PraisonAIAgents(
agents=agents,
tasks=tasks,
process=process,
verbose=inputs['depth'] == 'detailed'
)
result = praison_agents.start()
# Save results if detailed
if inputs['depth'] == 'detailed':
filename = f"{inputs['topic'].replace(' ', '_')}_{inputs['output_format']}.txt"
with open(filename, 'w', encoding='utf-8') as f:
f.write(result)
print(f"\n📄 Results saved to: {filename}")
return result
# Usage
if __name__ == "__main__":
system = DynamicAgentSystem()
result = system.run()
print("\n📊 Final Result:")
print(result)
@@ -0,0 +1,60 @@
"""
Environment Variable Input Example for PraisonAI
This example demonstrates how to use environment variables combined with user input
to create flexible agent configurations that can be pre-configured via environment.
"""
import os
from praisonaiagents import Agent, Task, PraisonAIAgents
# Set via environment or use default
default_topic = os.getenv("RESEARCH_TOPIC", "AI trends")
user_topic = input(f"Topic to research [{default_topic}]: ") or default_topic
# Get other configuration from environment
llm_model = os.getenv("LLM_MODEL", "gpt-4o-mini")
temperature = float(os.getenv("LLM_TEMPERATURE", "0.7"))
max_retries = int(os.getenv("MAX_RETRIES", "3"))
# Create agent with environment-based configuration
agent = Agent(
name="Researcher",
role="Research Assistant",
goal=f"Research {user_topic}",
backstory="Expert researcher with configurable capabilities",
llm={
"model": llm_model,
"temperature": temperature
},
max_retry_limit=max_retries
)
# Create task
task = Task(
description=f"Research and summarize: {user_topic}",
expected_output="Comprehensive summary with key findings",
agent=agent
)
# Show configuration
print(f"\n🔧 Configuration:")
print(f" - Topic: {user_topic}")
print(f" - Model: {llm_model}")
print(f" - Temperature: {temperature}")
print(f" - Max Retries: {max_retries}")
print("\n" + "="*50 + "\n")
# Run agents
agents = PraisonAIAgents(agents=[agent], tasks=[task])
result = agents.start()
# Save to environment-specified location if provided
output_path = os.getenv("OUTPUT_PATH")
if output_path:
output_file = os.path.join(output_path, f"{user_topic.replace(' ', '_')}_research.txt")
with open(output_file, 'w', encoding='utf-8') as f:
f.write(result)
print(f"\n📁 Results saved to: {output_file}")
print("\n✅ Research completed!")
@@ -0,0 +1,55 @@
"""
Medium Complexity Input Example for PraisonAI
This example shows how to use multiple user inputs to create a more sophisticated
agent system with tools, multiple agents, and context passing between tasks.
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Get multiple inputs
topic = input("Enter search topic: ")
num_results = input("How many results? (default: 5): ") or "5"
# Create search agent with tools
search_agent = Agent(
name="WebSearcher",
role="Search Specialist",
goal=f"Find {num_results} relevant results about {topic}",
backstory="Expert in internet research and data collection",
tools=[duckduckgo],
self_reflect=False
)
# Create analysis agent
analysis_agent = Agent(
name="Analyzer",
role="Data Analyst",
goal="Analyze and summarize search results",
backstory="Expert in data synthesis and reporting"
)
# Create tasks with context passing
search_task = Task(
description=f"Search for '{topic}' and find top {num_results} results",
expected_output=f"List of {num_results} relevant results with sources",
agent=search_agent,
name="search_task"
)
analyze_task = Task(
description="Analyze the search results and create a summary report",
expected_output="Comprehensive summary with key insights",
agent=analysis_agent,
context=[search_task], # Receives results from search_task
name="analysis_task"
)
# Run sequential process
agents = PraisonAIAgents(
agents=[search_agent, analysis_agent],
tasks=[search_task, analyze_task],
process="sequential"
)
agents.start()
+30
View File
@@ -0,0 +1,30 @@
"""
Simple Input Example for PraisonAI
This example demonstrates how to use basic user input to create dynamic agents and tasks.
The user is prompted for a search query, and the agent searches for information about it.
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
# Get user input
user_query = input("What would you like to search for? ")
# Create agent
agent = Agent(
name="SearchAgent",
role="Information Finder",
goal="Find information about user's query",
backstory="Expert researcher with web access"
)
# Create task with dynamic input
task = Task(
description=f"Search for information about: {user_query}",
expected_output=f"Summary of findings about {user_query}",
agent=agent
)
# Run
agents = PraisonAIAgents(agents=[agent], tasks=[task])
agents.start()
+177
View File
@@ -0,0 +1,177 @@
"""
Streamlit UI Input Example for PraisonAI
This example demonstrates how to create a web-based UI for dynamic user input
using Streamlit, making it easy for users to interact with PraisonAI agents.
To run this example:
1. Install streamlit: pip install streamlit
2. Run: streamlit run streamlit_ui_input.py
"""
import streamlit as st
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Set page configuration
st.set_page_config(
page_title="PraisonAI Dynamic Input",
page_icon="🤖",
layout="wide"
)
st.title("🤖 PraisonAI Dynamic Input Interface")
st.markdown("---")
# Create sidebar for configuration
with st.sidebar:
st.header("⚙️ Configuration")
# Model selection
model = st.selectbox(
"Select Model",
["gpt-4o-mini", "gpt-4o", "gpt-3.5-turbo", "claude-3-opus"],
index=0
)
# Temperature slider
temperature = st.slider(
"Creativity Level (Temperature)",
min_value=0.0,
max_value=1.0,
value=0.7,
step=0.1
)
# Process type
process_type = st.radio(
"Process Type",
["sequential", "hierarchical"],
index=0
)
# Enable tools
use_tools = st.checkbox("Enable Web Search", value=True)
# Main content area
col1, col2 = st.columns([2, 1])
with col1:
# User input
user_query = st.text_area(
"What would you like to know?",
placeholder="Enter your question or research topic here...",
height=100
)
# Additional options
with st.expander("Advanced Options"):
max_search_results = st.number_input(
"Max Search Results",
min_value=1,
max_value=20,
value=5
)
output_format = st.selectbox(
"Output Format",
["Summary", "Detailed Report", "Bullet Points"],
index=0
)
include_sources = st.checkbox("Include Sources", value=True)
with col2:
st.info(
"💡 **Tips:**\n"
"- Be specific with your questions\n"
"- Use higher temperature for creative tasks\n"
"- Enable web search for current information"
)
# Submit button
if st.button("🚀 Submit", type="primary", use_container_width=True):
if user_query:
# Create progress container
progress_container = st.container()
with progress_container:
with st.spinner("🔄 Processing your request..."):
try:
# Create agent with dynamic configuration
agent = Agent(
name="Assistant",
role=f"{output_format} Specialist",
goal=f"Answer: {user_query}",
backstory="Knowledgeable assistant with configurable capabilities",
tools=[duckduckgo] if use_tools else [],
llm={
"model": model,
"temperature": temperature
}
)
# Create task with dynamic parameters
task_description = f"Provide a {output_format.lower()} answer for: {user_query}"
if use_tools:
task_description += f"\nSearch for up to {max_search_results} relevant results."
if include_sources:
task_description += "\nInclude sources for all information."
task = Task(
description=task_description,
expected_output=f"{output_format} with clear, helpful information",
agent=agent
)
# Run agents
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
process=process_type
)
result = agents.start()
# Display results
st.success("✅ Processing complete!")
# Show result in a nice format
st.markdown("### 📊 Results")
# Create tabs for different views
tab1, tab2, tab3 = st.tabs(["Result", "Configuration", "Raw Output"])
with tab1:
st.markdown(result)
with tab2:
st.json({
"model": model,
"temperature": temperature,
"process": process_type,
"tools_enabled": use_tools,
"output_format": output_format,
"query": user_query
})
with tab3:
st.code(result, language="markdown")
# Download button
st.download_button(
label="📥 Download Results",
data=result,
file_name=f"{user_query[:30].replace(' ', '_')}_results.txt",
mime="text/plain"
)
except Exception as e:
st.error(f"❌ An error occurred: {str(e)}")
st.exception(e)
else:
st.warning("⚠️ Please enter a question or topic to research.")
# Footer
st.markdown("---")
st.markdown("Built with ❤️ using PraisonAI and Streamlit")
@@ -0,0 +1,34 @@
# Example: Using Ollama with a remote host via base_url parameter
# pip install praisonaiagents
from praisonaiagents import Agent
# Method 1: Using base_url parameter directly (NEW)
agent = Agent(
instructions="You are a helpful assistant",
llm="ollama/llama3.2",
base_url="http://remote-host:11434"
)
response = agent.start("Why is the sky blue?")
print(response)
# Method 2: Using dict configuration
agent2 = Agent(
instructions="You are a helpful assistant",
llm={
"model": "ollama/llama3.2",
"base_url": "http://remote-host:11434"
}
)
response2 = agent2.start("What is the capital of France?")
print(response2)
# Method 3: Using environment variable (existing method)
# export OPENAI_BASE_URL=http://remote-host:11434
# Then just:
# agent3 = Agent(
# instructions="You are a helpful assistant",
# llm="ollama/llama3.2"
# )
@@ -0,0 +1,207 @@
#!/usr/bin/env python3
"""
Basic State Management Example
==============================
This example demonstrates the fundamental state management capabilities in PraisonAI.
It shows how to set, get, update, and manage state values in a multi-agent workflow.
Run this example:
python 01_basic_state_management.py
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
import json
from typing import Dict, Any
def display_project_status() -> str:
"""Tool to display current project status from workflow state"""
# Access state from the global workflow variable
project_name = workflow.get_state("project_name", "Unknown Project")
budget = workflow.get_state("budget", 0)
stage = workflow.get_state("stage", "not_started")
team_size = workflow.get_state("team_size", 0)
features = workflow.get_state("features", [])
status = f"""
Project Status Report
====================
Project: {project_name}
Budget: ${budget:,}
Stage: {stage}
Team Size: {team_size}
Features: {', '.join(features) if features else 'None added yet'}
"""
return status
def add_feature(feature_name: str) -> str:
"""Tool to add a new feature to the project"""
features = workflow.get_state("features", [])
features.append(feature_name)
workflow.set_state("features", features)
return f"Added feature: {feature_name}. Total features: {len(features)}"
def update_project_stage(new_stage: str) -> str:
"""Tool to update the project stage"""
old_stage = workflow.get_state("stage", "not_started")
workflow.set_state("stage", new_stage)
# Log stage transition
transitions = workflow.get_state("stage_transitions", [])
transitions.append({"from": old_stage, "to": new_stage})
workflow.set_state("stage_transitions", transitions)
return f"Project stage updated from '{old_stage}' to '{new_stage}'"
def check_budget_health() -> Dict[str, Any]:
"""Tool to check budget health"""
budget = workflow.get_state("budget", 0)
spent = workflow.get_state("spent", 0)
if budget == 0:
health = "undefined"
percentage = 0
else:
percentage = (spent / budget) * 100
if percentage > 90:
health = "critical"
elif percentage > 70:
health = "warning"
else:
health = "healthy"
return {
"budget": budget,
"spent": spent,
"remaining": budget - spent,
"percentage_used": percentage,
"health": health
}
# Create agents
project_manager = Agent(
name="ProjectManager",
role="Manage project state and status",
goal="Track and report project progress",
backstory="An experienced project manager who keeps track of all project details",
tools=[display_project_status, update_project_stage],
llm="gpt-4o-mini",
verbose=True
)
developer = Agent(
name="Developer",
role="Add features to the project",
goal="Implement new features and track them in state",
backstory="A skilled developer who implements features",
tools=[add_feature, display_project_status],
llm="gpt-4o-mini",
verbose=True
)
finance_manager = Agent(
name="FinanceManager",
role="Monitor project budget",
goal="Ensure project stays within budget",
backstory="A careful finance manager who tracks spending",
tools=[check_budget_health],
llm="gpt-4o-mini",
verbose=True
)
# Create tasks
task1 = Task(
name="initialize_project",
description="Initialize the project and display initial status",
expected_output="Initial project status report",
agent=project_manager,
tools=[display_project_status]
)
task2 = Task(
name="add_core_features",
description="Add the following core features to the project: 'User Authentication', 'Dashboard', 'API Integration'",
expected_output="Confirmation of added features",
agent=developer,
tools=[add_feature]
)
task3 = Task(
name="update_to_development",
description="Update the project stage to 'development' and show updated status",
expected_output="Updated project status",
agent=project_manager,
tools=[update_project_stage, display_project_status]
)
task4 = Task(
name="check_budget",
description="Check the current budget health and provide a financial report",
expected_output="Budget health report",
agent=finance_manager,
tools=[check_budget_health]
)
# Create workflow (global variable for state access in tools)
workflow = PraisonAIAgents(
agents=[project_manager, developer, finance_manager],
tasks=[task1, task2, task3, task4],
verbose=True,
process="sequential"
)
# Set initial state values
print("\n=== Setting Initial State ===")
workflow.set_state("project_name", "AI Assistant Platform")
workflow.set_state("budget", 100000)
workflow.set_state("spent", 25000)
workflow.set_state("features", [])
# Update multiple state values at once
workflow.update_state({
"stage": "planning",
"team_size": 5,
"project_manager": "Alice",
"tech_stack": ["Python", "React", "PostgreSQL"]
})
# Demonstrate state operations
print("\n=== State Operations Demo ===")
# Check if state exists
if workflow.has_state("budget"):
budget = workflow.get_state("budget")
print(f"Project budget: ${budget:,}")
# Get all state
all_state = workflow.get_all_state()
print(f"\nAll state keys: {list(all_state.keys())}")
# Get state with default
priority = workflow.get_state("priority", "medium")
print(f"Project priority: {priority}")
# Run the workflow
print("\n=== Starting Workflow ===")
result = workflow.start()
# Display final state
print("\n=== Final State ===")
final_state = workflow.get_all_state()
print(json.dumps(final_state, indent=2))
# Demonstrate state deletion
print("\n=== State Cleanup Demo ===")
workflow.delete_state("project_manager")
print(f"State after deletion: {list(workflow.get_all_state().keys())}")
# Clear all state (commented out to preserve results)
# workflow.clear_state()
# print(f"State after clear: {workflow.get_all_state()}")
@@ -0,0 +1,307 @@
#!/usr/bin/env python3
"""
State in Tool Functions Example
==============================
This example shows how to use workflow state within tool functions.
Tools can read and modify state to share information between agents and tasks.
Run this example:
python 02_state_in_tool_functions.py
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
import time
import json
from typing import Dict, Any
from datetime import datetime
def track_progress() -> Dict[str, Any]:
"""Tool that tracks task progress using workflow state"""
# Access current progress from state
current_stage = workflow.get_state("stage", "not_started")
completed_tasks = workflow.get_state("completed_tasks", 0)
total_tasks = workflow.get_state("total_tasks", 10)
# Increment completed tasks counter
workflow.increment_state("completed_tasks", 1)
# Track task completion time
workflow.append_to_state("task_history", {
"task_id": completed_tasks + 1,
"stage": current_stage,
"timestamp": datetime.now().isoformat(),
"status": "completed"
}, max_length=10) # Keep only last 10 entries
# Calculate progress
new_completed = completed_tasks + 1
progress_percentage = (new_completed / total_tasks) * 100
return {
"stage": current_stage,
"tasks_completed": new_completed,
"total_tasks": total_tasks,
"progress": f"{progress_percentage:.1f}%",
"remaining": total_tasks - new_completed
}
def log_error(error_type: str, error_message: str) -> str:
"""Tool that logs errors to state"""
# Increment error counter
workflow.increment_state(f"error_count_{error_type}", 1, default=0)
# Append to error log with timestamp
error_entry = {
"type": error_type,
"message": error_message,
"timestamp": datetime.now().isoformat()
}
workflow.append_to_state("error_log", error_entry, max_length=50)
# Update last error timestamp
workflow.set_state("last_error_time", datetime.now().isoformat())
# Get current error count
error_count = workflow.get_state(f"error_count_{error_type}", 0)
return f"Error logged: {error_type} (Total {error_type} errors: {error_count})"
def process_data_batch() -> Dict[str, Any]:
"""Tool that processes data in batches using state for coordination"""
# Get or initialize batch processing state
if not workflow.has_state("batch_total"):
workflow.set_state("batch_total", 5)
workflow.set_state("batch_current", 0)
workflow.set_state("batch_results", [])
# Get current batch info
batch_current = workflow.get_state("batch_current")
batch_total = workflow.get_state("batch_total")
# Process next batch
batch_current += 1
workflow.set_state("batch_current", batch_current)
# Simulate batch processing
result = {
"batch_id": batch_current,
"records_processed": 100,
"processing_time": 0.5,
"status": "success"
}
# Store batch result
workflow.append_to_state("batch_results", result)
# Update statistics
workflow.increment_state("total_records_processed", 100, default=0)
return {
"batch": batch_current,
"total_batches": batch_total,
"result": result,
"more_batches": batch_current < batch_total
}
def generate_report() -> str:
"""Tool that generates a report from accumulated state data"""
# Gather all state data
completed_tasks = workflow.get_state("completed_tasks", 0)
total_tasks = workflow.get_state("total_tasks", 10)
task_history = workflow.get_state("task_history", [])
error_log = workflow.get_state("error_log", [])
batch_results = workflow.get_state("batch_results", [])
total_records = workflow.get_state("total_records_processed", 0)
# Count errors by type
error_types = {}
for key in workflow.get_all_state().keys():
if key.startswith("error_count_"):
error_type = key.replace("error_count_", "")
error_types[error_type] = workflow.get_state(key)
report = f"""
===== WORKFLOW REPORT =====
Task Progress:
- Completed: {completed_tasks}/{total_tasks} ({(completed_tasks/total_tasks*100):.1f}%)
- Recent Tasks: {len(task_history)} tracked
Batch Processing:
- Batches Processed: {len(batch_results)}
- Total Records: {total_records}
Errors:
- Total Errors: {len(error_log)}
- Error Types: {json.dumps(error_types, indent=2) if error_types else 'None'}
Recent Activity:
"""
# Add recent task history
if task_history:
report += "\n Recent Tasks:\n"
for task in task_history[-3:]: # Last 3 tasks
report += f" - Task {task['task_id']} completed at {task['timestamp']}\n"
# Add recent errors
if error_log:
report += "\n Recent Errors:\n"
for error in error_log[-3:]: # Last 3 errors
report += f" - {error['type']}: {error['message']} at {error['timestamp']}\n"
return report
def update_configuration(key: str, value: Any) -> str:
"""Tool that updates configuration stored in state"""
# Get current config
config = workflow.get_state("config", {})
# Store old value for audit
old_value = config.get(key, "not_set")
# Update config
config[key] = value
workflow.set_state("config", config)
# Log configuration change
workflow.append_to_state("config_changes", {
"key": key,
"old_value": old_value,
"new_value": value,
"timestamp": datetime.now().isoformat()
}, max_length=100)
return f"Configuration updated: {key} = {value} (was: {old_value})"
# Create agents
progress_tracker = Agent(
name="ProgressTracker",
role="Track and report task progress",
goal="Monitor workflow progress using state",
backstory="A meticulous tracker who monitors every task",
tools=[track_progress, generate_report],
llm="gpt-4o-mini",
verbose=True
)
data_processor = Agent(
name="DataProcessor",
role="Process data in batches",
goal="Efficiently process all data batches",
backstory="A data processing specialist",
tools=[process_data_batch],
llm="gpt-4o-mini",
verbose=True
)
error_handler = Agent(
name="ErrorHandler",
role="Handle and log errors",
goal="Track all errors and maintain error logs",
backstory="An error handling expert",
tools=[log_error],
llm="gpt-4o-mini",
verbose=True
)
config_manager = Agent(
name="ConfigManager",
role="Manage system configuration",
goal="Update and track configuration changes",
backstory="A configuration management specialist",
tools=[update_configuration],
llm="gpt-4o-mini",
verbose=True
)
# Create tasks
task1 = Task(
name="initialize_tracking",
description="Initialize the workflow and track the first progress update",
expected_output="Initial progress report",
agent=progress_tracker,
tools=[track_progress]
)
task2 = Task(
name="update_config",
description="Update configuration settings: set 'batch_size' to 100 and 'retry_limit' to 3",
expected_output="Configuration update confirmations",
agent=config_manager,
tools=[update_configuration]
)
task3 = Task(
name="process_all_batches",
description="Process all data batches and track progress",
expected_output="All batch processing results",
agent=data_processor,
tools=[process_data_batch]
)
task4 = Task(
name="simulate_errors",
description="Log some sample errors: 'connection' error 'Failed to connect to database' and 'validation' error 'Invalid data format'",
expected_output="Error logging confirmations",
agent=error_handler,
tools=[log_error]
)
task5 = Task(
name="track_more_progress",
description="Track progress for 3 more tasks",
expected_output="Progress updates",
agent=progress_tracker,
tools=[track_progress]
)
task6 = Task(
name="generate_final_report",
description="Generate a comprehensive report of all activities",
expected_output="Final workflow report",
agent=progress_tracker,
tools=[generate_report]
)
# Create workflow (global variable for state access in tools)
workflow = PraisonAIAgents(
agents=[progress_tracker, data_processor, error_handler, config_manager],
tasks=[task1, task2, task3, task4, task5, task6],
verbose=True,
process="sequential"
)
# Initialize workflow state
print("\n=== Initializing Workflow State ===")
workflow.set_state("stage", "processing")
workflow.set_state("total_tasks", 10)
workflow.set_state("completed_tasks", 0)
# Run the workflow
print("\n=== Starting Workflow ===")
result = workflow.start()
# Display final state summary
print("\n=== Final State Summary ===")
final_state = workflow.get_all_state()
print(f"Total state keys: {len(final_state)}")
print(f"Completed tasks: {final_state.get('completed_tasks', 0)}")
print(f"Total errors logged: {len(final_state.get('error_log', []))}")
print(f"Batches processed: {len(final_state.get('batch_results', []))}")
print(f"Configuration changes: {len(final_state.get('config_changes', []))}")
# Show some state details
print("\n=== State Details ===")
print(f"Current configuration: {json.dumps(final_state.get('config', {}), indent=2)}")
print(f"Error counts by type: ", end="")
error_counts = {k: v for k, v in final_state.items() if k.startswith("error_count_")}
print(json.dumps(error_counts, indent=2) if error_counts else "None")
@@ -0,0 +1,421 @@
#!/usr/bin/env python3
"""
Conditional Task Execution with State Example
============================================
This example demonstrates how to use state to control task flow with conditional execution.
Tasks can make decisions based on state values to determine which tasks execute next.
Run this example:
python 03_conditional_task_execution.py
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
import json
from typing import Dict, Any
def check_budget_status() -> str:
"""Check budget and return decision based on spending"""
budget = workflow.get_state("budget", 0)
spent = workflow.get_state("spent", 0)
if budget == 0:
return "no_budget"
percentage_spent = (spent / budget) * 100
# Store budget analysis in state
workflow.set_state("budget_analysis", {
"budget": budget,
"spent": spent,
"remaining": budget - spent,
"percentage_spent": percentage_spent
})
# Return decision based on budget status
if percentage_spent >= 90:
workflow.set_state("budget_alert", "critical")
return "over_budget"
elif percentage_spent >= 70:
workflow.set_state("budget_alert", "warning")
return "within_budget"
else:
workflow.set_state("budget_alert", "healthy")
return "under_budget"
def reduce_costs() -> str:
"""Implement cost reduction measures"""
current_spent = workflow.get_state("spent", 0)
# Simulate cost reduction
savings = current_spent * 0.15 # 15% reduction
new_spent = current_spent - savings
workflow.set_state("spent", new_spent)
workflow.set_state("cost_reduction_applied", True)
workflow.set_state("savings_achieved", savings)
# Log action
workflow.append_to_state("actions_taken", {
"action": "cost_reduction",
"savings": savings,
"new_spent": new_spent
})
return f"Cost reduction implemented. Saved ${savings:,.2f}. New spending: ${new_spent:,.2f}"
def continue_development() -> str:
"""Continue with normal development"""
# Add new features
features = workflow.get_state("features", [])
new_features = ["Feature A", "Feature B"]
features.extend(new_features)
workflow.set_state("features", features)
# Update development status
workflow.set_state("development_status", "active")
# Log action
workflow.append_to_state("actions_taken", {
"action": "continue_development",
"features_added": new_features
})
return f"Continuing development. Added features: {', '.join(new_features)}"
def expand_features() -> str:
"""Expand project with additional features"""
# Add premium features
features = workflow.get_state("features", [])
premium_features = ["Premium Feature X", "Premium Feature Y", "Premium Feature Z"]
features.extend(premium_features)
workflow.set_state("features", features)
# Increase budget allocation
additional_budget = 20000
current_budget = workflow.get_state("budget", 0)
workflow.set_state("budget", current_budget + additional_budget)
# Update status
workflow.set_state("development_status", "expanded")
# Log action
workflow.append_to_state("actions_taken", {
"action": "expand_features",
"premium_features_added": premium_features,
"budget_increased": additional_budget
})
return f"Expanded project scope. Added premium features and increased budget by ${additional_budget:,}"
def check_performance() -> str:
"""Check system performance and return status"""
# Simulate performance metrics
cpu_usage = workflow.get_state("cpu_usage", 45) # percentage
memory_usage = workflow.get_state("memory_usage", 60) # percentage
response_time = workflow.get_state("response_time", 200) # milliseconds
# Store performance metrics
workflow.set_state("performance_metrics", {
"cpu_usage": cpu_usage,
"memory_usage": memory_usage,
"response_time": response_time
})
# Determine performance status
if cpu_usage > 80 or memory_usage > 85 or response_time > 500:
return "poor_performance"
elif cpu_usage > 60 or memory_usage > 70 or response_time > 300:
return "moderate_performance"
else:
return "good_performance"
def optimize_performance() -> str:
"""Optimize system performance"""
# Simulate optimization
workflow.set_state("cpu_usage", 40)
workflow.set_state("memory_usage", 50)
workflow.set_state("response_time", 150)
workflow.set_state("optimization_applied", True)
# Log action
workflow.append_to_state("actions_taken", {
"action": "optimize_performance",
"improvements": "Applied caching, code optimization, and resource cleanup"
})
return "Performance optimization completed. All metrics improved."
def scale_infrastructure() -> str:
"""Scale up infrastructure"""
# Simulate scaling
current_servers = workflow.get_state("server_count", 2)
new_servers = current_servers + 2
workflow.set_state("server_count", new_servers)
workflow.set_state("infrastructure_scaled", True)
# Log action
workflow.append_to_state("actions_taken", {
"action": "scale_infrastructure",
"servers_added": 2,
"total_servers": new_servers
})
return f"Infrastructure scaled. Added 2 servers. Total servers: {new_servers}"
def maintain_current_setup() -> str:
"""Maintain current setup without changes"""
workflow.set_state("system_status", "stable")
# Log action
workflow.append_to_state("actions_taken", {
"action": "maintain_current",
"reason": "Performance is good, no changes needed"
})
return "System performing well. Maintaining current setup."
def generate_decision_report() -> str:
"""Generate report on all decisions made"""
actions = workflow.get_state("actions_taken", [])
budget_analysis = workflow.get_state("budget_analysis", {})
performance_metrics = workflow.get_state("performance_metrics", {})
report = """
Decision Flow Report
===================
Budget Analysis:
"""
if budget_analysis:
report += f"""
- Budget: ${budget_analysis.get('budget', 0):,}
- Spent: ${budget_analysis.get('spent', 0):,}
- Remaining: ${budget_analysis.get('remaining', 0):,}
- Percentage Spent: {budget_analysis.get('percentage_spent', 0):.1f}%
- Alert Level: {workflow.get_state('budget_alert', 'unknown')}
"""
report += "\n Performance Metrics:\n"
if performance_metrics:
report += f"""
- CPU Usage: {performance_metrics.get('cpu_usage', 0)}%
- Memory Usage: {performance_metrics.get('memory_usage', 0)}%
- Response Time: {performance_metrics.get('response_time', 0)}ms
"""
report += "\n Actions Taken:\n"
for i, action in enumerate(actions, 1):
report += f" {i}. {action['action'].replace('_', ' ').title()}\n"
for key, value in action.items():
if key != 'action':
report += f" - {key}: {value}\n"
# Add final state summary
report += f"""
Final State:
- Features: {len(workflow.get_state('features', []))} total
- Development Status: {workflow.get_state('development_status', 'unknown')}
- System Status: {workflow.get_state('system_status', 'unknown')}
"""
return report
# Create agents
finance_agent = Agent(
name="FinanceAgent",
role="Monitor budget and make financial decisions",
goal="Ensure project stays within budget constraints",
backstory="A financial expert who makes budget decisions",
tools=[check_budget_status],
llm="gpt-4o-mini",
verbose=True
)
cost_manager = Agent(
name="CostManager",
role="Implement cost reduction strategies",
goal="Reduce costs when budget is tight",
backstory="A cost optimization specialist",
tools=[reduce_costs],
llm="gpt-4o-mini",
verbose=True
)
development_agent = Agent(
name="DevelopmentAgent",
role="Manage feature development",
goal="Develop features based on budget availability",
backstory="A development manager who adapts to budget constraints",
tools=[continue_development, expand_features],
llm="gpt-4o-mini",
verbose=True
)
performance_agent = Agent(
name="PerformanceAgent",
role="Monitor and optimize system performance",
goal="Ensure optimal system performance",
backstory="A performance engineer",
tools=[check_performance, optimize_performance, scale_infrastructure, maintain_current_setup],
llm="gpt-4o-mini",
verbose=True
)
report_agent = Agent(
name="ReportAgent",
role="Generate comprehensive reports",
goal="Document all decisions and actions taken",
backstory="A reporting specialist",
tools=[generate_decision_report],
llm="gpt-4o-mini",
verbose=True
)
# Create conditional tasks
budget_decision_task = Task(
name="budget_decision",
description="Check current budget status and decide next action",
expected_output="Budget status decision",
agent=finance_agent,
tools=[check_budget_status],
task_type="decision",
condition={
"over_budget": ["cost_reduction_task"],
"within_budget": ["continue_development_task"],
"under_budget": ["expand_features_task"],
"no_budget": ["report_task"] # Skip to report if no budget
}
)
cost_reduction_task = Task(
name="cost_reduction_task",
description="Implement cost reduction measures due to budget constraints",
expected_output="Cost reduction confirmation",
agent=cost_manager,
tools=[reduce_costs],
next_tasks=["performance_check_task"]
)
continue_development_task = Task(
name="continue_development_task",
description="Continue with planned development",
expected_output="Development continuation confirmation",
agent=development_agent,
tools=[continue_development],
next_tasks=["performance_check_task"]
)
expand_features_task = Task(
name="expand_features_task",
description="Expand project with additional premium features",
expected_output="Feature expansion confirmation",
agent=development_agent,
tools=[expand_features],
next_tasks=["performance_check_task"]
)
performance_check_task = Task(
name="performance_check_task",
description="Check system performance and decide on optimization needs",
expected_output="Performance status decision",
agent=performance_agent,
tools=[check_performance],
task_type="decision",
condition={
"poor_performance": ["optimize_performance_task"],
"moderate_performance": ["scale_infrastructure_task"],
"good_performance": ["maintain_setup_task"]
}
)
optimize_performance_task = Task(
name="optimize_performance_task",
description="Optimize system performance due to poor metrics",
expected_output="Performance optimization confirmation",
agent=performance_agent,
tools=[optimize_performance],
next_tasks=["report_task"]
)
scale_infrastructure_task = Task(
name="scale_infrastructure_task",
description="Scale infrastructure to handle moderate load",
expected_output="Infrastructure scaling confirmation",
agent=performance_agent,
tools=[scale_infrastructure],
next_tasks=["report_task"]
)
maintain_setup_task = Task(
name="maintain_setup_task",
description="Maintain current setup as performance is good",
expected_output="Setup maintenance confirmation",
agent=performance_agent,
tools=[maintain_current_setup],
next_tasks=["report_task"]
)
report_task = Task(
name="report_task",
description="Generate comprehensive report of all decisions and actions",
expected_output="Complete decision flow report",
agent=report_agent,
tools=[generate_decision_report]
)
# Create workflow
workflow = PraisonAIAgents(
agents=[finance_agent, cost_manager, development_agent, performance_agent, report_agent],
tasks=[
budget_decision_task,
cost_reduction_task,
continue_development_task,
expand_features_task,
performance_check_task,
optimize_performance_task,
scale_infrastructure_task,
maintain_setup_task,
report_task
],
verbose=True,
process="sequential"
)
# Test different scenarios by changing initial state
print("\n=== Scenario 1: Over Budget with Poor Performance ===")
workflow.set_state("budget", 100000)
workflow.set_state("spent", 92000) # 92% spent - over budget
workflow.set_state("cpu_usage", 85) # High CPU - poor performance
workflow.set_state("memory_usage", 88)
workflow.set_state("response_time", 600)
workflow.set_state("features", [])
workflow.set_state("actions_taken", [])
# Run workflow
result = workflow.start()
# To test other scenarios, uncomment and run:
"""
print("\n\n=== Scenario 2: Under Budget with Good Performance ===")
workflow.clear_state()
workflow.set_state("budget", 100000)
workflow.set_state("spent", 40000) # 40% spent - under budget
workflow.set_state("cpu_usage", 35) # Low usage - good performance
workflow.set_state("memory_usage", 45)
workflow.set_state("response_time", 150)
workflow.set_state("features", [])
workflow.set_state("actions_taken", [])
result = workflow.start()
"""
@@ -0,0 +1,345 @@
#!/usr/bin/env python3
"""
Session State Persistence Example
================================
This example demonstrates how to save and restore workflow state using sessions.
This is useful for long-running workflows that may need to be paused and resumed.
Run this example:
python 04_session_state_persistence.py
"""
from praisonaiagents import Agent, Task, PraisonAIAgents, Session
import json
import time
from datetime import datetime
from typing import Dict, Any
def process_customer_data(customer_id: str) -> Dict[str, Any]:
"""Process customer data and update state"""
# Track which customers have been processed
processed_customers = workflow.get_state("processed_customers", [])
# Simulate data processing
processing_result = {
"customer_id": customer_id,
"status": "processed",
"timestamp": datetime.now().isoformat(),
"records_processed": 150
}
# Update state
processed_customers.append(customer_id)
workflow.set_state("processed_customers", processed_customers)
# Increment counters
workflow.increment_state("total_customers_processed", 1, default=0)
workflow.increment_state("total_records_processed", 150, default=0)
# Add to processing history
workflow.append_to_state("processing_history", processing_result, max_length=100)
return processing_result
def check_processing_status() -> str:
"""Check current processing status"""
total_customers = workflow.get_state("total_customers_processed", 0)
total_records = workflow.get_state("total_records_processed", 0)
processed_list = workflow.get_state("processed_customers", [])
session_id = workflow.get_state("session_id", "unknown")
status = f"""
Processing Status (Session: {session_id})
========================================
Total Customers Processed: {total_customers}
Total Records Processed: {total_records}
Customers: {', '.join(processed_list) if processed_list else 'None'}
"""
# Check if we need to continue
remaining_customers = workflow.get_state("remaining_customers", [])
if remaining_customers:
status += f"\nRemaining Customers: {', '.join(remaining_customers)}"
return status
def save_checkpoint() -> str:
"""Save current state as a checkpoint"""
session_id = workflow.get_state("session_id", "session_001")
# Add checkpoint metadata
workflow.set_state("last_checkpoint", datetime.now().isoformat())
workflow.set_state("checkpoint_number", workflow.get_state("checkpoint_number", 0) + 1)
# Save session state
workflow.save_session_state(session_id, include_memory=True)
checkpoint_num = workflow.get_state("checkpoint_number")
return f"Checkpoint #{checkpoint_num} saved for session {session_id}"
def simulate_long_task() -> str:
"""Simulate a long-running task that updates progress"""
task_name = "data_migration"
# Initialize or get current progress
progress = workflow.get_state(f"{task_name}_progress", 0)
# Simulate work in chunks
chunk_size = 20
progress += chunk_size
# Update state
workflow.set_state(f"{task_name}_progress", progress)
workflow.set_state(f"{task_name}_last_update", datetime.now().isoformat())
# Check if complete
if progress >= 100:
workflow.set_state(f"{task_name}_status", "completed")
return f"Task '{task_name}' completed!"
else:
workflow.set_state(f"{task_name}_status", "in_progress")
return f"Task '{task_name}' progress: {progress}%"
def generate_session_report() -> str:
"""Generate a report for the current session"""
session_id = workflow.get_state("session_id", "unknown")
start_time = workflow.get_state("session_start_time", "unknown")
checkpoints = workflow.get_state("checkpoint_number", 0)
# Get all task statuses
all_state = workflow.get_all_state()
task_statuses = {}
for key, value in all_state.items():
if key.endswith("_status"):
task_name = key.replace("_status", "")
task_statuses[task_name] = value
report = f"""
Session Report
==============
Session ID: {session_id}
Start Time: {start_time}
Checkpoints: {checkpoints}
Processing Summary:
- Customers Processed: {workflow.get_state('total_customers_processed', 0)}
- Records Processed: {workflow.get_state('total_records_processed', 0)}
Task Statuses:
"""
for task, status in task_statuses.items():
progress = workflow.get_state(f"{task}_progress", "N/A")
report += f" - {task}: {status} (Progress: {progress}%)\n"
# Add processing history summary
history = workflow.get_state("processing_history", [])
if history:
report += f"\n Recent Processing ({len(history)} total):\n"
for entry in history[-3:]: # Last 3 entries
report += f" - {entry['customer_id']} at {entry['timestamp']}\n"
return report
# Create agents
data_processor = Agent(
name="DataProcessor",
role="Process customer data",
goal="Process all customer data efficiently",
backstory="A data processing specialist",
tools=[process_customer_data],
llm="gpt-4o-mini",
verbose=True
)
status_monitor = Agent(
name="StatusMonitor",
role="Monitor processing status",
goal="Track and report processing progress",
backstory="A monitoring specialist",
tools=[check_processing_status, save_checkpoint],
llm="gpt-4o-mini",
verbose=True
)
task_runner = Agent(
name="TaskRunner",
role="Run long-running tasks",
goal="Execute tasks that may span multiple sessions",
backstory="A task execution specialist",
tools=[simulate_long_task],
llm="gpt-4o-mini",
verbose=True
)
report_generator = Agent(
name="ReportGenerator",
role="Generate session reports",
goal="Create comprehensive session reports",
backstory="A reporting specialist",
tools=[generate_session_report],
llm="gpt-4o-mini",
verbose=True
)
# Create tasks for initial session
initial_tasks = [
Task(
name="check_initial_status",
description="Check the initial processing status",
expected_output="Initial status report",
agent=status_monitor,
tools=[check_processing_status]
),
Task(
name="process_customer_1",
description="Process customer data for customer 'CUST001'",
expected_output="Processing result for CUST001",
agent=data_processor,
tools=[process_customer_data]
),
Task(
name="process_customer_2",
description="Process customer data for customer 'CUST002'",
expected_output="Processing result for CUST002",
agent=data_processor,
tools=[process_customer_data]
),
Task(
name="run_long_task",
description="Run the long-running data migration task",
expected_output="Task progress update",
agent=task_runner,
tools=[simulate_long_task]
),
Task(
name="save_checkpoint_1",
description="Save a checkpoint of the current state",
expected_output="Checkpoint confirmation",
agent=status_monitor,
tools=[save_checkpoint]
),
Task(
name="generate_report_1",
description="Generate a report for the current session",
expected_output="Session report",
agent=report_generator,
tools=[generate_session_report]
)
]
# Create workflow with memory enabled
workflow = PraisonAIAgents(
agents=[data_processor, status_monitor, task_runner, report_generator],
tasks=initial_tasks,
verbose=True,
process="sequential",
memory=True # Enable memory for persistence
)
# Initialize session
session_id = "project_session_001"
print(f"\n=== Starting Session: {session_id} ===")
# Set initial session state
workflow.set_state("session_id", session_id)
workflow.set_state("session_start_time", datetime.now().isoformat())
workflow.set_state("remaining_customers", ["CUST003", "CUST004", "CUST005"])
# Run initial workflow
print("\n=== Running Initial Workflow ===")
result = workflow.start()
# Save session state
print("\n=== Saving Session State ===")
workflow.save_session_state(session_id)
saved_state = workflow.get_all_state()
print(f"Saved {len(saved_state)} state keys")
# Simulate session interruption
print("\n=== Simulating Session Interruption ===")
print("Clearing current state to simulate new session...")
workflow.clear_state()
print(f"State after clear: {len(workflow.get_all_state())} keys")
# Create tasks for resumed session
resumed_tasks = [
Task(
name="check_resumed_status",
description="Check the status after resuming",
expected_output="Resumed status report",
agent=status_monitor,
tools=[check_processing_status]
),
Task(
name="process_remaining_customers",
description="Process remaining customers: CUST003, CUST004",
expected_output="Processing results for remaining customers",
agent=data_processor,
tools=[process_customer_data]
),
Task(
name="continue_long_task",
description="Continue the long-running data migration task",
expected_output="Updated task progress",
agent=task_runner,
tools=[simulate_long_task]
),
Task(
name="save_checkpoint_2",
description="Save another checkpoint",
expected_output="Checkpoint confirmation",
agent=status_monitor,
tools=[save_checkpoint]
),
Task(
name="generate_final_report",
description="Generate final session report",
expected_output="Final session report",
agent=report_generator,
tools=[generate_session_report]
)
]
# Create new workflow instance for resumed session
resumed_workflow = PraisonAIAgents(
agents=[data_processor, status_monitor, task_runner, report_generator],
tasks=resumed_tasks,
verbose=True,
process="sequential",
memory=True
)
# Make resumed_workflow available globally for tools
workflow = resumed_workflow
# Restore session state
print(f"\n=== Resuming Session: {session_id} ===")
workflow.restore_session_state(session_id)
restored_state = workflow.get_all_state()
print(f"Restored {len(restored_state)} state keys")
# Show what was restored
print("\nRestored state includes:")
print(f"- Processed customers: {workflow.get_state('processed_customers', [])}")
print(f"- Total records: {workflow.get_state('total_records_processed', 0)}")
print(f"- Task progress: {workflow.get_state('data_migration_progress', 0)}%")
# Continue workflow
print("\n=== Continuing Workflow ===")
result = resumed_workflow.start()
# Final state summary
print("\n=== Final Session Summary ===")
final_state = workflow.get_all_state()
print(f"Total customers processed: {workflow.get_state('total_customers_processed', 0)}")
print(f"Total records processed: {workflow.get_state('total_records_processed', 0)}")
print(f"Checkpoints created: {workflow.get_state('checkpoint_number', 0)}")
print(f"Task status: {workflow.get_state('data_migration_status', 'unknown')}")
@@ -0,0 +1,396 @@
#!/usr/bin/env python3
"""
Loop Control with State Example
==============================
This example demonstrates how to use state to control loops and iterative processes.
Tasks can loop based on state conditions until certain criteria are met.
Run this example:
python 05_loop_control_with_state.py
"""
from praisonaiagents import Agent, Task, PraisonAIAgents
import time
import random
from datetime import datetime
from typing import Dict, Any
def process_batch() -> str:
"""Process data in batches using state to track progress"""
# Initialize batch state if needed
if not workflow.has_state("batch_total"):
workflow.set_state("batch_total", 5)
workflow.set_state("batch_current", 0)
workflow.set_state("batch_start_time", datetime.now().isoformat())
# Get current batch info
batch_current = workflow.get_state("batch_current")
batch_total = workflow.get_state("batch_total")
# Process next batch
batch_current += 1
workflow.set_state("batch_current", batch_current)
# Simulate batch processing with random success/failure
success = random.random() > 0.2 # 80% success rate
records_processed = random.randint(80, 120) if success else 0
# Create batch result
batch_result = {
"batch_id": batch_current,
"records_processed": records_processed,
"status": "success" if success else "failed",
"timestamp": datetime.now().isoformat()
}
# Store batch result
workflow.append_to_state("batch_results", batch_result)
# Update statistics
if success:
workflow.increment_state("successful_batches", 1, default=0)
workflow.increment_state("total_records_processed", records_processed, default=0)
else:
workflow.increment_state("failed_batches", 1, default=0)
# Add to retry queue
workflow.append_to_state("retry_queue", batch_current)
# Determine if more batches
if batch_current < batch_total:
return "more_batches"
else:
# Check if we have retries
retry_queue = workflow.get_state("retry_queue", [])
if retry_queue:
return "process_retries"
else:
return "all_batches_complete"
def process_retry_batch() -> str:
"""Process failed batches from retry queue"""
retry_queue = workflow.get_state("retry_queue", [])
if not retry_queue:
return "no_retries"
# Get next batch to retry
batch_id = retry_queue.pop(0)
workflow.set_state("retry_queue", retry_queue)
# Increment retry counter
workflow.increment_state(f"batch_{batch_id}_retry_count", 1, default=0)
retry_count = workflow.get_state(f"batch_{batch_id}_retry_count")
# Process with higher success rate on retry
success = random.random() > 0.1 # 90% success rate on retry
records_processed = random.randint(80, 120) if success else 0
# Update batch result
retry_result = {
"batch_id": batch_id,
"records_processed": records_processed,
"status": "retry_success" if success else "retry_failed",
"retry_attempt": retry_count,
"timestamp": datetime.now().isoformat()
}
workflow.append_to_state("retry_results", retry_result)
if success:
workflow.increment_state("successful_retries", 1, default=0)
workflow.increment_state("total_records_processed", records_processed, default=0)
else:
# Check retry limit
if retry_count < 3:
# Add back to retry queue
retry_queue.append(batch_id)
workflow.set_state("retry_queue", retry_queue)
else:
# Mark as permanently failed
workflow.append_to_state("permanently_failed_batches", batch_id)
# Check if more retries needed
retry_queue = workflow.get_state("retry_queue", [])
if retry_queue:
return "more_retries"
else:
return "retries_complete"
def collect_paginated_data() -> str:
"""Collect data from paginated API using state"""
# Initialize pagination state
if not workflow.has_state("current_page"):
workflow.set_state("current_page", 1)
workflow.set_state("total_pages", 0) # Will be set after first call
workflow.set_state("items_collected", [])
current_page = workflow.get_state("current_page")
# Simulate API call
if current_page == 1:
# First call - determine total pages
total_pages = 4
workflow.set_state("total_pages", total_pages)
# Simulate collecting items
items_per_page = random.randint(8, 12)
new_items = [f"item_{current_page}_{i}" for i in range(items_per_page)]
# Add to collected items
items = workflow.get_state("items_collected", [])
items.extend(new_items)
workflow.set_state("items_collected", items)
# Update page counter
workflow.increment_state("current_page", 1)
# Log page processing
workflow.append_to_state("page_log", {
"page": current_page,
"items_collected": items_per_page,
"timestamp": datetime.now().isoformat()
})
# Check if more pages
total_pages = workflow.get_state("total_pages")
if current_page < total_pages:
return "more_pages"
else:
return "pagination_complete"
def validate_collected_items() -> str:
"""Validate all collected items"""
items = workflow.get_state("items_collected", [])
# Initialize validation state
if not workflow.has_state("validation_index"):
workflow.set_state("validation_index", 0)
workflow.set_state("valid_items", [])
workflow.set_state("invalid_items", [])
validation_index = workflow.get_state("validation_index")
batch_size = 5 # Validate 5 items at a time
# Get items to validate in this iteration
end_index = min(validation_index + batch_size, len(items))
items_to_validate = items[validation_index:end_index]
# Simulate validation
for item in items_to_validate:
# Random validation (90% valid)
is_valid = random.random() > 0.1
if is_valid:
workflow.append_to_state("valid_items", item)
else:
workflow.append_to_state("invalid_items", item)
# Update validation index
workflow.set_state("validation_index", end_index)
# Check if more items to validate
if end_index < len(items):
return "more_validation"
else:
return "validation_complete"
def generate_loop_report() -> str:
"""Generate comprehensive report on all loop operations"""
# Batch processing stats
batch_total = workflow.get_state("batch_total", 0)
successful_batches = workflow.get_state("successful_batches", 0)
failed_batches = workflow.get_state("failed_batches", 0)
successful_retries = workflow.get_state("successful_retries", 0)
permanently_failed = len(workflow.get_state("permanently_failed_batches", []))
total_records = workflow.get_state("total_records_processed", 0)
# Pagination stats
total_pages = workflow.get_state("total_pages", 0)
items_collected = len(workflow.get_state("items_collected", []))
# Validation stats
valid_items = len(workflow.get_state("valid_items", []))
invalid_items = len(workflow.get_state("invalid_items", []))
# Calculate timing
start_time = workflow.get_state("batch_start_time", "unknown")
report = f"""
Loop Operations Report
=====================
Batch Processing:
- Total Batches: {batch_total}
- Successful: {successful_batches}
- Failed Initially: {failed_batches}
- Successful Retries: {successful_retries}
- Permanently Failed: {permanently_failed}
- Total Records Processed: {total_records}
- Success Rate: {((successful_batches + successful_retries) / batch_total * 100):.1f}%
Pagination Collection:
- Pages Processed: {total_pages}
- Items Collected: {items_collected}
- Average Items/Page: {items_collected / total_pages:.1f}
Validation Results:
- Total Items: {items_collected}
- Valid Items: {valid_items}
- Invalid Items: {invalid_items}
- Validation Rate: {(valid_items / items_collected * 100):.1f}%
Processing Started: {start_time}
"""
# Add batch failure details
retry_results = workflow.get_state("retry_results", [])
if retry_results:
report += "\n Retry Details:\n"
for result in retry_results[-3:]: # Last 3 retries
report += f" - Batch {result['batch_id']}: {result['status']} (Attempt {result['retry_attempt']})\n"
return report
# Create agents
batch_processor = Agent(
name="BatchProcessor",
role="Process data in batches",
goal="Process all batches successfully with retry logic",
backstory="A batch processing expert",
tools=[process_batch, process_retry_batch],
llm="gpt-4o-mini",
verbose=True
)
data_collector = Agent(
name="DataCollector",
role="Collect paginated data",
goal="Collect all data from paginated source",
backstory="A data collection specialist",
tools=[collect_paginated_data],
llm="gpt-4o-mini",
verbose=True
)
validator = Agent(
name="Validator",
role="Validate collected items",
goal="Validate all collected items in batches",
backstory="A data validation expert",
tools=[validate_collected_items],
llm="gpt-4o-mini",
verbose=True
)
reporter = Agent(
name="Reporter",
role="Generate reports",
goal="Create comprehensive reports on loop operations",
backstory="A reporting specialist",
tools=[generate_loop_report],
llm="gpt-4o-mini",
verbose=True
)
# Create loop tasks
batch_loop_task = Task(
name="process_batches",
description="Process all data batches",
expected_output="Batch processing status",
agent=batch_processor,
tools=[process_batch],
task_type="loop",
condition={
"more_batches": ["process_batches"], # Loop back to itself
"process_retries": ["retry_failed_batches"],
"all_batches_complete": ["collect_pages"] # Go to next task
}
)
retry_loop_task = Task(
name="retry_failed_batches",
description="Retry processing for failed batches",
expected_output="Retry processing status",
agent=batch_processor,
tools=[process_retry_batch],
task_type="loop",
condition={
"more_retries": ["retry_failed_batches"], # Loop back to itself
"retries_complete": ["collect_pages"],
"no_retries": ["collect_pages"]
}
)
pagination_loop_task = Task(
name="collect_pages",
description="Collect all pages of data",
expected_output="Page collection status",
agent=data_collector,
tools=[collect_paginated_data],
task_type="loop",
condition={
"more_pages": ["collect_pages"], # Loop back to itself
"pagination_complete": ["validate_items"]
}
)
validation_loop_task = Task(
name="validate_items",
description="Validate all collected items in batches",
expected_output="Validation status",
agent=validator,
tools=[validate_collected_items],
task_type="loop",
condition={
"more_validation": ["validate_items"], # Loop back to itself
"validation_complete": ["generate_report"]
}
)
report_task = Task(
name="generate_report",
description="Generate final report on all loop operations",
expected_output="Comprehensive loop operations report",
agent=reporter,
tools=[generate_loop_report]
)
# Create workflow
workflow = PraisonAIAgents(
agents=[batch_processor, data_collector, validator, reporter],
tasks=[batch_loop_task, retry_loop_task, pagination_loop_task, validation_loop_task, report_task],
verbose=True,
process="sequential"
)
# Initialize workflow
print("\n=== Starting Loop Control Example ===")
print("This example will demonstrate:")
print("1. Batch processing with automatic retry on failure")
print("2. Paginated data collection")
print("3. Iterative validation of collected items")
print("4. All controlled by state-based loop conditions")
# Run workflow
result = workflow.start()
# Display loop statistics
print("\n=== Loop Statistics ===")
print(f"Total loop iterations:")
print(f"- Batch processing: {workflow.get_state('batch_current', 0)} batches")
print(f"- Retry processing: {len(workflow.get_state('retry_results', []))} retries")
print(f"- Page collection: {workflow.get_state('current_page', 1) - 1} pages")
print(f"- Item validation: {workflow.get_state('validation_index', 0)} items validated")
# Show state size
print(f"\n=== State Management ===")
print(f"Total state keys: {len(workflow.get_all_state())}")
print(f"Batch results stored: {len(workflow.get_state('batch_results', []))}")
print(f"Items collected: {len(workflow.get_state('items_collected', []))}")
Loaded 100 of 137 files, more files were not shown because too many files have changed in this diff. Show more