From 9c38645da61226ba8a3fdbab39b78a6eb9aa1f21 Mon Sep 17 00:00:00 2001 From: Vedant Sahai Date: Wed, 2 Oct 2024 15:06:29 -0400 Subject: [PATCH 01/16] doc: Added Readme for cookbooks and updated the Colab links (#550) > [!IMPORTANT] > Add `README.md` to `cookbooks` with Jupyter notebook overview and Colab links. > > - **Documentation**: > - Adds `README.md` to `cookbooks` directory. > - Provides an overview of Jupyter notebooks for AI tasks. > - Includes Colab links for each notebook: `01-Website_Crawler_using_Spider.ipynb`, `02-Sarcastic_News_Headline_Generator.ipynb`, `03-SmartResearcher_With_WebSearch.ipynb`, `04-TripPlanner_With_Weather_And_WikiInfo.ipynb`. > - Contact information and contribution guidelines included. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for a1ad58e6c8b460962b4b76ee428f9e7934f1be25. It will automatically update as commits are pushed. --------- Signed-off-by: Diwank Singh Tomer Co-authored-by: Diwank Singh Tomer --- .../01-Website_Crawler_using_Spider.ipynb | 4 +-- ...02-Sarcastic_News_Headline_Generator.ipynb | 2 +- .../03-SmartResearcher_With_WebSearch.ipynb | 2 +- ...ripPlanner_With_Weather_And_WikiInfo.ipynb | 2 +- cookbooks/README.md | 29 +++++++++++++++++++ 5 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 cookbooks/README.md diff --git a/cookbooks/01-Website_Crawler_using_Spider.ipynb b/cookbooks/01-Website_Crawler_using_Spider.ipynb index 251e699f4..36a77d525 100644 --- a/cookbooks/01-Website_Crawler_using_Spider.ipynb +++ b/cookbooks/01-Website_Crawler_using_Spider.ipynb @@ -30,11 +30,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Implementation\n", + "## Implementation\n", "\n", "To recreate the notebook and see the code implementation for this task, you can access the Google Colab notebook using the link below:\n", "\n", - "\n", + "\n", " \"Open\n", "\n", "\n", diff --git a/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb b/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb index 618d95df9..fded810a1 100644 --- a/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb +++ b/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb @@ -60,7 +60,7 @@ "\n", "To recreate the notebook and see the code implementation for this task, you can access the Google Colab notebook using the link below:\n", "\n", - "\n", + "\n", " \"Open\n", "\n", "\n", diff --git a/cookbooks/03-SmartResearcher_With_WebSearch.ipynb b/cookbooks/03-SmartResearcher_With_WebSearch.ipynb index b32d0f95b..c01b54652 100644 --- a/cookbooks/03-SmartResearcher_With_WebSearch.ipynb +++ b/cookbooks/03-SmartResearcher_With_WebSearch.ipynb @@ -73,7 +73,7 @@ "\n", "To recreate the notebook and see the code implementation for this task, you can access the Google Colab notebook using the link below:\n", "\n", - "\n", + "\n", " \"Open\n", "\n", "\n", diff --git a/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb b/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb index cfc95f3c2..d7fc39840 100644 --- a/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb +++ b/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb @@ -80,7 +80,7 @@ "\n", "To recreate the notebook and see the code implementation for this task, you can access the Google Colab notebook using the link below:\n", "\n", - "\n", + "\n", " \"Open\n", "\n", "\n", diff --git a/cookbooks/README.md b/cookbooks/README.md new file mode 100644 index 000000000..2b89ca22a --- /dev/null +++ b/cookbooks/README.md @@ -0,0 +1,29 @@ +
+ julep +
+ +# Julep AI - Notebook Overview + +Welcome to the **Julep AI Notebook Collection**! This directory contains a set of Jupyter notebooks designed for a variety of AI and automation tasks. + +Each notebook explores a unique use case, ranging from web crawling to running complex workflows using AI Agents. + +Below is a quick overview of the notebooks, their purpose, and a link to run each of them on Google Colab. + +| **Notebook Name** | **Colab Link** | **Description** | +|------------------------------------------------- |---------------------------------------------------------------------------- |--------------------------------------------------------------------| +| `01-Website_Crawler_using_Spider.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/01-Website_Crawler_using_Spider.ipynb) | Implements a web crawler using a spider to extract website content. | +| `02-Sarcastic_News_Headline_Generator.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb) | Generates sarcastic news headlines using a Brave Search Tool. | +| `03-SmartResearcher_With_WebSearch.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/03-SmartResearcher_With_WebSearch.ipynb) | Searches and aggregates web information for research purposes using Brave Search. | +| `04-TripPlanner_With_Weather_And_WikiInfo.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb) | Plans trips using weather data and Wikipedia information. | + +### Additional Information + +For more details about the task or if you have any questions, please don't hesitate to contact the author: + +**Author:** Julep AI +**Contact:** [hey@julep.ai](mailto:hey@julep.ai) or Discord + +--- + +If you have feedback or would like to contribute to the notebooks, feel free to open an issue(s) in the [repository](https://github.com/julep-ai/julep). From 4d12e8bae1948459cc21fc95f4d41ac5eac0db45 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 16:23:11 -0400 Subject: [PATCH 02/16] doc: Add ideas to implement in cookbooks/README.md Signed-off-by: Diwank Singh Tomer --- cookbooks/README.md | 150 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 11 deletions(-) diff --git a/cookbooks/README.md b/cookbooks/README.md index 2b89ca22a..e7a6bfa89 100644 --- a/cookbooks/README.md +++ b/cookbooks/README.md @@ -4,26 +4,154 @@ # Julep AI - Notebook Overview -Welcome to the **Julep AI Notebook Collection**! This directory contains a set of Jupyter notebooks designed for a variety of AI and automation tasks. +Welcome to the **Julep AI Notebook Collection**! This directory contains a set of Jupyter notebooks designed to showcase various AI and automation tasks using Julep's features. -Each notebook explores a unique use case, ranging from web crawling to running complex workflows using AI Agents. +Each notebook explores a unique use case, demonstrating different aspects of Julep's capabilities. Below is a quick overview of the notebooks, their purpose, and a link to run each of them on Google Colab. -Below is a quick overview of the notebooks, their purpose, and a link to run each of them on Google Colab. +| **Notebook Name** | **Colab Link** | **Description** | **Implemented** | +|------------------------------------------------- |---------------------------------------------------------------------------- |--------------------------------------------------------------------|-----------------| +| `01-Website_Crawler_using_Spider.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/01-Website_Crawler_using_Spider.ipynb) | Implements a web crawler using a spider to extract website content. | Yes | +| `02-Sarcastic_News_Headline_Generator.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb) | Generates sarcastic news headlines using a Brave Search Tool. | Yes | +| `03-SmartResearcher_With_WebSearch.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/03-SmartResearcher_With_WebSearch.ipynb) | Searches and aggregates web information for research purposes using Brave Search. | Yes | +| `04-TripPlanner_With_Weather_And_WikiInfo.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb) | Plans trips using weather data and Wikipedia information. | Yes | +| `05-Basic_Agent_Creation_and_Interaction.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/05-Basic_Agent_Creation_and_Interaction.ipynb) | Demonstrates how to create a basic agent and interact with it. | No | +| `06-Designing_Multi-Step_Tasks.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/06-Designing_Multi-Step_Tasks.ipynb) | Explores creating tasks with various step types. | No | +| `07-Integrating_External_Tools_and_APIs.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/07-Integrating_External_Tools_and_APIs.ipynb) | Shows how to integrate and use external tools and APIs. | No | +| `08-Managing_Persistent_Sessions.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/08-Managing_Persistent_Sessions.ipynb) | Covers creating and managing persistent sessions with context. | No | +| `09-User_Management_and_Personalization.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/09-User_Management_and_Personalization.ipynb) | Demonstrates user management and personalized interactions. | No | +| `10-Document_Management_and_Search.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/10-Document_Management_and_Search.ipynb) | Explores document upload, management, and search capabilities. | No | +| `11-Advanced_Chat_Interactions.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/11-Advanced_Chat_Interactions.ipynb) | Covers advanced chat features and context handling. | No | +| `12-Monitoring_Task_Executions.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/12-Monitoring_Task_Executions.ipynb) | Shows how to monitor and manage task executions. | No | +| `13-Error_Handling_and_Recovery.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/13-Error_Handling_and_Recovery.ipynb) | Demonstrates implementing error handling and recovery in tasks. | No | +| `14-API_Versioning_and_Configurations.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/14-API_Versioning_and_Configurations.ipynb) | Explores API versioning and server configuration options. | No | -| **Notebook Name** | **Colab Link** | **Description** | -|------------------------------------------------- |---------------------------------------------------------------------------- |--------------------------------------------------------------------| -| `01-Website_Crawler_using_Spider.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/01-Website_Crawler_using_Spider.ipynb) | Implements a web crawler using a spider to extract website content. | -| `02-Sarcastic_News_Headline_Generator.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/02-Sarcastic_News_Headline_Generator.ipynb) | Generates sarcastic news headlines using a Brave Search Tool. | -| `03-SmartResearcher_With_WebSearch.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/03-SmartResearcher_With_WebSearch.ipynb) | Searches and aggregates web information for research purposes using Brave Search. | -| `04-TripPlanner_With_Weather_And_WikiInfo.ipynb` | [Colab Link](https://colab.research.google.com/github/julep-ai/julep/blob/dev/cookbooks/04-TripPlanner_With_Weather_And_WikiInfo.ipynb) | Plans trips using weather data and Wikipedia information. | +## Potential Cookbooks for Contributors + +We welcome contributions to expand our cookbook collection. Here are some ideas for new cookbooks that showcase various Julep features and use cases: + +| **Potential Cookbook Name** | **Description** | **Key Features** | +|---------------------------- |----------------- |------------------| +| Automated Research Assistant | Conducts research on given topics using web search and summarization | Web search, Tool integration, Multi-step tasks | +| Customer Support Chatbot | Interacts with users, analyzes sentiment, and routes complex issues | Chat functionality, Sentiment analysis, Conditional logic | +| Daily News Aggregator | Collects and summarizes news articles, emails summaries to subscribers | Scheduled tasks, Email integration, Content summarization | +| Social Media Monitoring System | Monitors social platforms for keywords and sends alerts | API integration, Real-time monitoring, Alert system | +| Weather-Based Notification Service | Checks weather forecasts and notifies users of severe conditions | Weather API integration, Conditional alerts, Scheduling | +| Automated Financial Report Generator | Gathers financial data and generates reports for stakeholders | Data aggregation, Report generation, Scheduling | +| Task Management and Reminder System | Manages user tasks, sets reminders, and sends notifications | User management, Scheduling, Notifications | +| Interactive Story Generator | Creates stories based on user input with corresponding images | Natural language processing, Image generation, User interaction | +| Automated Meeting Scheduler | Finds optimal meeting times and manages calendar entries | Calendar integration, Conflict resolution, Invitations | +| Email Categorization and Response | Categorizes incoming emails and sends automated responses | Email processing, Content categorization, Automated responses | +| E-commerce Order Processing | Handles order placements, inventory, and shipment tracking | Workflow automation, Inventory management, Notifications | +| Content Moderation System | Reviews and classifies user-generated content | Content analysis, Classification, Moderation actions | +| Personalized Learning Assistant | Provides tailored learning materials and tracks progress | Personalization, Progress tracking, Content recommendation | +| Automated Backup and Recovery | Regularly backs up data and initiates recovery procedures | Scheduled tasks, Error handling, Data management | +| Smart Home Automation Workflow | Manages smart home devices based on user commands and conditions | IoT integration, Conditional logic, User interaction | +| Inventory Management System | Tracks inventory levels and automates reordering | Stock management, Predictive analysis, Automated ordering | +| Event-Driven Notification System | Triggers notifications based on specific events or thresholds | Event monitoring, Conditional alerts, Multi-channel notifications | +| Data Cleaning and Transformation | Cleans and transforms raw data for analysis | Data processing, ETL operations, Quality assurance | +| Project Management Assistant | Breaks down projects into tasks and tracks progress | Task decomposition, Progress monitoring, Reporting | +| Parallel Data Processing Pipeline | Processes large datasets in parallel and aggregates results | Parallel execution, Data aggregation, Scalable processing | +| Dynamic Content Recommendation | Analyzes user behavior and recommends personalized content | User profiling, Content analysis, Personalized recommendations | +| Compliance Monitoring System | Monitors activities for regulatory compliance and generates reports | Rule-based monitoring, Violation detection, Compliance reporting | +| Intelligent Resume Screening | Evaluates resumes based on criteria and forwards qualified candidates | Document analysis, Candidate scoring, Automated screening | +| Automated Code Review Pipeline | Reviews code commits, runs tests, and manages deployments | Code analysis, Automated testing, Deployment management | +| Personal Finance Tracker | Tracks expenses, analyzes patterns, and provides financial advice | Financial data analysis, Pattern recognition, Personalized advice | +| Automated Content Publishing | Schedules and publishes content across various platforms | Content management, Multi-platform publishing, Scheduling | +| AI-Powered Personal Assistant | Manages personal tasks, schedules, and provides information | Task management, Scheduling, Information retrieval | +| Bug Tracking and Reporting | Monitors repositories, categorizes issues, and assigns to developers | Issue tracking, Categorization, Automated assignment | +| Multi-Stage Data Validation | Validates data through multiple stages with different rules | Data validation, Multi-step processing, Error handling | +| Document Summarization and Archiving | Summarizes documents and archives them for easy retrieval | Text summarization, Document classification, Archiving | +| Real-Time Stock Market Analyzer | Analyzes market data and alerts users about significant changes | Real-time data processing, Financial analysis, Alert system | +| Webinar Management System | Schedules webinars, manages participants, and handles follow-ups | Event scheduling, Participant management, Automated follow-ups | +| Smart Content Filtering | Filters and recommends content based on user preferences | Content analysis, User profiling, Recommendation system | +| Automated Translation Workflow | Translates content into multiple languages and localizes it | Language translation, Localization, Content management | +| AI-Driven Survey Analysis | Analyzes survey responses and generates insight reports | Survey processing, Sentiment analysis, Report generation | +| Compliance Documentation Generator | Creates compliance documents based on regulatory standards | Document generation, Compliance checking, Template management | +| Task Prioritization and Allocation | Prioritizes tasks and allocates them to team members | Task analysis, Resource allocation, Team management | +| Webinar Feedback Analyzer | Collects and analyzes feedback from webinar participants | Feedback collection, Sentiment analysis, Improvement suggestions | +| Health and Fitness Tracker | Tracks health metrics and provides personalized fitness recommendations | Health data analysis, Personalized recommendations, Progress tracking | +| Incident Response System | Detects incidents, initiates response workflows, and notifies personnel | Incident detection, Workflow automation, Alert system | +| Content Optimization Workflow | Analyzes content performance and optimizes for better engagement | Performance analysis, Content optimization, A/B testing | +| Legal Document Processor | Extracts key information from legal documents and ensures compliance | Document analysis, Information extraction, Compliance checking | +| Job Application Tracker | Tracks job applications and provides application improvement suggestions | Application tracking, Status updates, Improvement recommendations | +| Content Rescheduling System | Monitors content performance and reschedules for better visibility | Performance monitoring, Content scheduling, Optimization | +| AI-Powered Investment Advisor | Analyzes financial data and suggests investment opportunities | Financial analysis, Risk assessment, Investment recommendations | +| Intelligent Document Version Control | Manages document versions and notifies users about updates | Version control, Change tracking, Notification system | +| Marketing Campaign Manager | Creates, schedules, and optimizes marketing campaigns | Campaign planning, Performance tracking, Optimization strategies | +| Competitive Analysis Workflow | Gathers data on competitors and generates analysis reports | Data collection, Comparative analysis, Report generation | +| Health Monitoring and Alerting | Monitors health metrics and alerts users and healthcare providers | Health data analysis, Anomaly detection, Alert system | +| Travel Itinerary Planner | Plans travel itineraries based on preferences and conditions | Trip planning, Preference matching, Dynamic scheduling | +| AI-Powered Personal Diary | Helps maintain a diary and provides insights into emotions and growth | Natural language processing, Sentiment analysis, Personal growth tracking | +| Language Learning Tutor | Provides exercises and personalized feedback for language learners | Language processing, Progress tracking, Personalized lessons | +| Knowledge Base Maintenance | Updates and maintains a knowledge base with new information | Information extraction, Knowledge management, Consistency checking | +| Feedback Loop for Improvement | Collects user feedback, analyzes it, and implements improvements | Feedback analysis, Improvement tracking, Stakeholder notifications | +| Grant Application Processor | Reviews grant applications, evaluates eligibility, and notifies applicants | Application processing, Eligibility checking, Automated notifications | +| AI-Powered Resume Builder | Assists in building resumes and provides improvement suggestions | Resume analysis, Content generation, Personalized recommendations | +| Vendor Management System | Manages vendor information, monitors performance, and handles communications | Vendor tracking, Performance monitoring, Communication automation | +| Meeting Minutes Recorder | Records meetings, transcribes audio, and distributes summaries | Audio transcription, Summary generation, Automated distribution | +| Personal Shopping Assistant | Finds products based on preferences and notifies about deals | Product matching, Price comparison, Deal notifications | +| Environmental Monitoring Reporter | Monitors environmental data and generates reports for stakeholders | Data monitoring, Anomaly detection, Report generation | +| Data Sync and Integration Workflow | Syncs data between platforms and handles conflicts | Data synchronization, Conflict resolution, Integration management | +| Competitive Pricing Strategy | Analyzes competitor pricing and adjusts prices dynamically | Price analysis, Dynamic pricing, Market monitoring | +| User Onboarding Workflow | Manages the user onboarding process and sets up accounts | User registration, Account setup, Welcome communications | +| Content Curation and Distribution | Curates content based on interests and tracks engagement | Content curation, Distribution scheduling, Engagement tracking | + +We encourage contributors to choose from these ideas or propose their own to showcase Julep's capabilities in solving real-world problems. + +## Julep Features Demonstrated + +These notebooks showcase various features of Julep. Here's an overview of the key features you can explore: + +1. **Agent Management** + - Creating and updating agents + - Configuring agent settings (name, model, about) + +2. **Task Definition and Execution** + - Creating multi-step tasks + - Executing tasks with specific inputs + - Various step types (Prompt, Tool Call, Evaluate, Conditional Logic, Loops, etc.) + +3. **Tool Integration** + - Adding custom tools to agents + - Integrating external APIs (e.g., web search, image generation) + +4. **Session Management** + - Creating and managing persistent sessions + - Handling context overflow + +5. **User Management** + - Creating and managing users + - Associating users with sessions + +6. **Document Management** + - Uploading and managing documents + - Document search functionality + +7. **Chat Functionality** + - Interacting with agents through chat sessions + +8. **Execution Monitoring** + - Streaming execution progress + - Monitoring task lifecycle + +9. **API Versioning** + - Support for different API versions + +10. **Authentication** + - API Key authentication + +11. **Server Configuration** + - Configurable server environments + +We encourage contributors to create new notebooks that demonstrate these features in various combinations and use cases. ### Additional Information -For more details about the task or if you have any questions, please don't hesitate to contact the author: +For more details about the tasks or if you have any questions, please don't hesitate to contact the author: **Author:** Julep AI **Contact:** [hey@julep.ai](mailto:hey@julep.ai) or Discord --- -If you have feedback or would like to contribute to the notebooks, feel free to open an issue(s) in the [repository](https://github.com/julep-ai/julep). +If you have feedback or would like to contribute to the notebooks, feel free to open an issue(s) in the [repository](https://github.com/julep-ai/julep). \ No newline at end of file From 0abe269b00ccbd74bbeed09c05925a0518a525a3 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 17:21:27 -0400 Subject: [PATCH 03/16] doc: Update README.md to add a callout for hacktoberfest people Signed-off-by: Diwank Singh Tomer --- README-CN.md | 29 +++++++++++- README.md | 124 +++++++++++---------------------------------------- 2 files changed, 54 insertions(+), 99 deletions(-) diff --git a/README-CN.md b/README-CN.md index 22bd8cb81..8dca6dcbb 100644 --- a/README-CN.md +++ b/README-CN.md @@ -26,6 +26,30 @@ GitHub 许可证

+***** + +## 🌟 诚邀贡献者! + +我们很高兴欢迎新的贡献者加入 Julep 项目!我们创建了几个"适合新手的问题"来帮助您入门。以下是您可以贡献的方式: + +1. 查看我们的 [CONTRIBUTING.md](CONTRIBUTING.md) 文件,了解如何贡献的指南。 +2. 浏览我们的[适合新手的问题](https://github.com/julep-ai/julep/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22),找到一个您感兴趣的任务。 +3. 如果您有任何问题或需要帮助,请随时在我们的 [Discord](https://discord.com/invite/JTSBGRZrzj) 频道上联系我们。 + +您的贡献,无论大小,对我们都很宝贵。让我们一起创造令人惊叹的东西吧!🚀 + +### 🎉 DevFest.AI 2024年10月 + +激动人心的消息!我们将在整个2024年10月参与 DevFest.AI 活动!🗓️ + +- 在此活动期间为 Julep 做出贡献,有机会赢得超棒的 Julep 周边和礼品!🎁 +- 加入来自世界各地的开发者,为 AI 仓库做出贡献并参与精彩的活动。 +- 非常感谢 DevFest.AI 组织这个fantastic的活动! + +> [!TIP] +> 准备好加入这场盛会了吗?**[发推文开始参与](https://twitter.com/intent/tweet?text=Pumped%20to%20be%20participating%20in%20%40devfestai%20with%20%40julep_ai%20building%20%23ai%20%23agents%20%23workflows%20Let's%20gooo!%20https%3A%2F%2Fgit.new%2Fjulep)**,让我们开始编码吧!🖥️ + +![Julep DevFest.AI](https://media.giphy.com/media/YjyUeyotft6epaMHtU/giphy.gif) ***** @@ -50,6 +74,9 @@ 请继续关注我们即将发布的稳定版本的更多更新!📢 + +***** + ## 简介 Julep 是一个开源平台,用于创建具有可定制工作流的持久 AI 代理。它提供了开发、管理和部署 AI 驱动应用程序的工具,注重灵活性和易用性。 @@ -634,4 +661,4 @@ results = client.documents.search( ## 致谢 -我们要感谢所有贡献者和开源社区为他们宝贵的资源和贡献。 +我们要感谢所有贡献者和开源社区为他们宝贵的资源和贡献。 \ No newline at end of file diff --git a/README.md b/README.md index 37a3651be..af87426b1 100644 --- a/README.md +++ b/README.md @@ -7,104 +7,6 @@ The **Quick Start Guide Focused README** is the most promising for optimizing the time to first workflow. It allows developers to get hands-on experience quickly, which is essential for engagement and understanding. -* * * - -**Outline for the README:** - -1. **Title and Badges** - * Julep Logo or Title - * Build status, npm version, license badges -2. **Introduction** - * _Briefly explain what Julep is and its purpose._ - * Emphasize how it simplifies building persistent AI agents with workflows. -3. **Features** - * _Highlight key features with a focus on "tasks" (AI workflows)._ - * Mention support for persistent sessions, tool integration, and document management. -4. **Installation** - * _Provide npm installation command:_ - - bash - - Copy code - - `npm install julep` - -5. **Quick Start Guide** - * **Step 1: Import Julep** - * _Show how to import Julep into a project._ - - javascript - - Copy code - - `const Julep = require('julep');` - - * **Step 2: Initialize the Agent** - * _Guide on creating a new agent with basic settings._ - - javascript - - Copy code - - `const agent = new Julep.Agent({  name: 'MyAgent',  model: 'gpt-4-turbo', });` - - * **Step 3: Chat with the Agent** - * _Provide a simple example of a chat with the agent._ - - javascript - - Copy code - - `const response = await client.sessions.chat({  session_id: session.id,  message: 'Hello, how are you?' });` - - * **Step 4: Define a Task (Workflow)** - * _Provide a simple example of a task definition._ - - javascript - - Copy code - - `const task = {  name: 'GreetingTask',  main: [    {      prompt: 'Say hello to the user.',    },  ], }; agent.addTask(task);` - - * **Step 5: Execute the Task** - * _Show how to run the task and handle the output._ - - javascript - - Copy code - - `agent.executeTask('GreetingTask').then((output) => {  console.log(output); });` - -6. **Understanding Tasks** - * _Explain what tasks are and how they function within Julep._ - * Describe different types of workflow steps. - * Prompt, Tool Call, Evaluate, etc. - * _Note:_ Link to detailed documentation for each step type. -7. **Advanced Features** - * _Briefly mention other capabilities:_ - * Adding tools to agents. - * Managing sessions and users. - * Document integration and search. -8. **API Reference** - * _Link to full API documentation._ - * Mention key endpoints for agents, tasks, and executions. -9. **Examples and Tutorials** - * _Provide links to example projects or further tutorials._ - * Encourage users to explore and build upon provided examples. -10. **Contributing** - * _Instructions for contributing to the project._ - * Link to contribution guidelines and code of conduct. -11. **Support and Community** - * _Information on how to get help._ - * Links to community forums, chat groups, or issue trackers. -12. **License** - * _State the project's license._ - * Provide a link to the LICENSE file. -13. **Acknowledgements** - * _Credit to contributors and used resources._ - -* * * - **Notes:** * **Code Examples:** Ensure all code snippets are easy to understand and copy-paste ready. @@ -144,6 +46,31 @@ The **Quick Start Guide Focused README** is the most promising for optimizing th ***** +## 🌟 Call for Contributors! + +We're excited to welcome new contributors to the Julep project! We've created several "good first issues" to help you get started. Here's how you can contribute: + +1. Check out our [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute. +2. Browse our [good first issues](https://github.com/julep-ai/julep/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to find a task that interests you. +3. If you have any questions or need help, don't hesitate to reach out on our [Discord](https://discord.com/invite/JTSBGRZrzj) channel. + +Your contributions, big or small, are valuable to us. Let's build something amazing together! 🚀 + +### 🎉 DevFest.AI October 2024 + +Exciting news! We're participating in DevFest.AI throughout October 2024! 🗓️ + +- Contribute to Julep during this event and get a chance to win awesome Julep merch and swag! 🎁 +- Join developers from around the world in contributing to AI repositories and participating in amazing events. +- A big thank you to DevFest.AI for organizing this fantastic initiative! + +> [!TIP] +> Ready to join the fun? **[Tweet to start participating](https://twitter.com/intent/tweet?text=Pumped%20to%20be%20participating%20in%20%40devfestai%20with%20%40julep_ai%20building%20%23ai%20%23agents%20%23workflows%20Let's%20gooo!%20https%3A%2F%2Fgit.new%2Fjulep)** and let's get coding! 🖥️ + +![Julep DevFest.AI](https://media.giphy.com/media/YjyUeyotft6epaMHtU/giphy.gif) + +***** + ## 🎉🚀 **Exciting News: Julep 1.0 Alpha Release!** 🚀🎉 We're thrilled to announce the **alpha** release of Julep 1.0! 🥳 @@ -165,6 +92,7 @@ We're thrilled to announce the **alpha** release of Julep 1.0! 🥳 Stay tuned for more updates as we approach our stable release! 📢 +***** ## Introduction From 46ed8facb35c1b17978bbb21bdf20246c19d3bf0 Mon Sep 17 00:00:00 2001 From: Hamada Salhab Date: Thu, 3 Oct 2024 00:47:50 +0300 Subject: [PATCH 04/16] feat(agents-api): Add static checking for Jinja templates & Python expressions in task creation | Add validation for subworkflows (#570) Closes #535 > [!IMPORTANT] > Add static validation for Python expressions and Jinja templates in task creation and validate subworkflows in `openapi_model.py` and `steps.tsp`. > > - **Validation**: > - Add `validate_python_expression()` and `validate_jinja_template()` in `openapi_model.py`. > - Integrate validation into `EvaluateStep`, `ToolCallStep`, `PromptStep`, `SetStep`, `LogStep`, `ReturnStep`, `YieldStep`, `IfElseWorkflowStep`, and `MapReduceStep` in `openapi_model.py`. > - **Models**: > - Update `CreateTaskRequest` in `openapi_model.py` to validate subworkflows using `WorkflowType`. > - Add `YieldStep` to `MappableWorkflowStep` and `NonConditionalWorkflowStep` in `steps.tsp`. > - **Misc**: > - Reorder `YieldStep` in `Tasks.py` to maintain consistency. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 9952ad5700812126c0aa7f1bfa26467e88b60aab. It will automatically update as commits are pushed. --------- Co-authored-by: Diwank Singh Tomer --- agents-api/agents_api/autogen/Tasks.py | 26 ++- .../agents_api/autogen/openapi_model.py | 216 +++++++++++++++++- typespec/tasks/steps.tsp | 3 +- 3 files changed, 233 insertions(+), 12 deletions(-) diff --git a/agents-api/agents_api/autogen/Tasks.py b/agents-api/agents_api/autogen/Tasks.py index 48dba4ad7..9dd531c47 100644 --- a/agents-api/agents_api/autogen/Tasks.py +++ b/agents-api/agents_api/autogen/Tasks.py @@ -35,10 +35,10 @@ class CaseThen(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep ) """ @@ -63,10 +63,10 @@ class CaseThenUpdateItem(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep ) """ @@ -130,10 +130,10 @@ class CreateTaskRequest(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | IfElseWorkflowStep | SwitchStep @@ -227,6 +227,7 @@ class ForeachDo(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ) """ The steps to run for each iteration @@ -251,6 +252,7 @@ class ForeachDoUpdateItem(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ) """ The steps to run for each iteration @@ -324,10 +326,10 @@ class IfElseWorkflowStep(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep ) """ @@ -342,10 +344,10 @@ class IfElseWorkflowStep(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | None, Field(None, alias="else"), @@ -376,10 +378,10 @@ class IfElseWorkflowStepUpdateItem(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep ) """ @@ -394,10 +396,10 @@ class IfElseWorkflowStepUpdateItem(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | None, Field(None, alias="else"), @@ -462,6 +464,7 @@ class Main(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ) """ The steps to run for each iteration @@ -503,6 +506,7 @@ class MainModel(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ) """ The steps to run for each iteration @@ -543,6 +547,7 @@ class ParallelStep(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ], Field(max_length=100), ] @@ -569,6 +574,7 @@ class ParallelStepUpdateItem(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep ], Field(max_length=100), ] @@ -596,10 +602,10 @@ class PatchTaskRequest(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | IfElseWorkflowStepUpdateItem | SwitchStepUpdateItem @@ -874,10 +880,10 @@ class Task(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | IfElseWorkflowStep | SwitchStep @@ -1009,10 +1015,10 @@ class UpdateTaskRequest(BaseModel): | LogStep | EmbedStep | SearchStep + | YieldStep | ReturnStep | SleepStep | ErrorWorkflowStep - | YieldStep | WaitForInputStep | IfElseWorkflowStep | SwitchStep diff --git a/agents-api/agents_api/autogen/openapi_model.py b/agents-api/agents_api/autogen/openapi_model.py index 5c5a8c86f..48811eb20 100644 --- a/agents-api/agents_api/autogen/openapi_model.py +++ b/agents-api/agents_api/autogen/openapi_model.py @@ -1,10 +1,12 @@ # ruff: noqa: F401, F403, F405 +import ast from typing import Annotated, Any, Generic, Literal, Self, Type, TypeVar, get_args from uuid import UUID +import jinja2 from litellm.utils import _select_tokenizer as select_tokenizer from litellm.utils import token_counter -from pydantic import AwareDatetime, Field +from pydantic import AwareDatetime, Field, field_validator, model_validator, validator from ..common.utils.datetime import utcnow from .Agents import * @@ -152,6 +154,179 @@ def from_model_input( ) +# Patch Task Workflow Steps +# -------------------------------------- + + +def validate_python_expression(expr: str) -> tuple[bool, str]: + try: + ast.parse(expr) + return True, "" + except SyntaxError as e: + return False, f"SyntaxError in '{expr}': {str(e)}" + + +def validate_jinja_template(template: str) -> tuple[bool, str]: + env = jinja2.Environment() + try: + parsed_template = env.parse(template) + for node in parsed_template.body: + if isinstance(node, jinja2.nodes.Output): + for child in node.nodes: + if isinstance(child, jinja2.nodes.Name): + # Check if the variable is a valid Python expression + is_valid, error = validate_python_expression(child.name) + if not is_valid: + return ( + False, + f"Invalid Python expression in Jinja template '{template}': {error}", + ) + return True, "" + except jinja2.exceptions.TemplateSyntaxError as e: + return False, f"TemplateSyntaxError in '{template}': {str(e)}" + + +_EvaluateStep = EvaluateStep + + +class EvaluateStep(_EvaluateStep): + @field_validator("evaluate") + def validate_evaluate_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError(f"Invalid Python expression in key '{key}': {error}") + return v + + +_ToolCallStep = ToolCallStep + + +class ToolCallStep(_ToolCallStep): + @field_validator("arguments") + def validate_arguments(cls, v): + if isinstance(v, dict): + for key, expr in v.items(): + if isinstance(expr, str): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError( + f"Invalid Python expression in arguments key '{key}': {error}" + ) + return v + + +_PromptStep = PromptStep + + +class PromptStep(_PromptStep): + @field_validator("prompt") + def validate_prompt(cls, v): + if isinstance(v, str): + is_valid, error = validate_jinja_template(v) + if not is_valid: + raise ValueError(f"Invalid Jinja template in prompt: {error}") + elif isinstance(v, list): + for item in v: + if "content" in item: + is_valid, error = validate_jinja_template(item["content"]) + if not is_valid: + raise ValueError( + f"Invalid Jinja template in prompt content: {error}" + ) + return v + + +_SetStep = SetStep + + +class SetStep(_SetStep): + @field_validator("set") + def validate_set_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError( + f"Invalid Python expression in set key '{key}': {error}" + ) + return v + + +_LogStep = LogStep + + +class LogStep(_LogStep): + @field_validator("log") + def validate_log_template(cls, v): + is_valid, error = validate_jinja_template(v) + if not is_valid: + raise ValueError(f"Invalid Jinja template in log: {error}") + return v + + +_ReturnStep = ReturnStep + + +class ReturnStep(_ReturnStep): + @field_validator("return_") + def validate_return_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError( + f"Invalid Python expression in return key '{key}': {error}" + ) + return v + + +_YieldStep = YieldStep + + +class YieldStep(_YieldStep): + @field_validator("arguments") + def validate_yield_arguments(cls, v): + if isinstance(v, dict): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError( + f"Invalid Python expression in yield arguments key '{key}': {error}" + ) + return v + + +_IfElseWorkflowStep = IfElseWorkflowStep + + +class IfElseWorkflowStep(_IfElseWorkflowStep): + @field_validator("if_") + def validate_if_expression(cls, v): + is_valid, error = validate_python_expression(v) + if not is_valid: + raise ValueError(f"Invalid Python expression in if condition: {error}") + return v + + +_MapReduceStep = MapReduceStep + + +class MapReduceStep(_MapReduceStep): + @field_validator("over") + def validate_over_expression(cls, v): + is_valid, error = validate_python_expression(v) + if not is_valid: + raise ValueError(f"Invalid Python expression in over: {error}") + return v + + @field_validator("reduce") + def validate_reduce_expression(cls, v): + if v is not None: + is_valid, error = validate_python_expression(v) + if not is_valid: + raise ValueError(f"Invalid Python expression in reduce: {error}") + return v + + # Workflow related models # ----------------------- @@ -228,6 +403,29 @@ class Task(_Task): # Patch some models to allow extra fields # -------------------------------------- +WorkflowType = RootModel[ + list[ + EvaluateStep + | ToolCallStep + | PromptStep + | GetStep + | SetStep + | LogStep + | EmbedStep + | SearchStep + | ReturnStep + | SleepStep + | ErrorWorkflowStep + | YieldStep + | WaitForInputStep + | IfElseWorkflowStep + | SwitchStep + | ForeachStep + | ParallelStep + | MapReduceStep + ] +] + _CreateTaskRequest = CreateTaskRequest @@ -240,6 +438,22 @@ class CreateTaskRequest(_CreateTaskRequest): } ) + @model_validator(mode="after") + def validate_subworkflows(self) -> Self: + subworkflows = { + k: v + for k, v in self.model_dump().items() + if k not in _CreateTaskRequest.model_fields + } + + for workflow_name, workflow_definition in subworkflows.items(): + try: + WorkflowType.model_validate(workflow_definition) + setattr(self, workflow_name, WorkflowType(workflow_definition)) + except Exception as e: + raise ValueError(f"Invalid subworkflow '{workflow_name}': {str(e)}") + return self + CreateOrUpdateTaskRequest = CreateTaskRequest diff --git a/typespec/tasks/steps.tsp b/typespec/tasks/steps.tsp index 3495def1b..2267ae320 100644 --- a/typespec/tasks/steps.tsp +++ b/typespec/tasks/steps.tsp @@ -49,7 +49,8 @@ alias MappableWorkflowStep = | SetStep | LogStep | EmbedStep - | SearchStep; + | SearchStep + | YieldStep; alias NonConditionalWorkflowStep = | MappableWorkflowStep From 866a4eb6c1f2ee85954f6efed6ba0a746ea67058 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 18:11:00 -0400 Subject: [PATCH 05/16] doc: Add code reading instructions to CONTRIBUTING.md (#556) Signed-off-by: Diwank Singh Tomer ---- > [!IMPORTANT] > Adds detailed code reading and contributing instructions to `CONTRIBUTING.md`, covering project architecture, setup, and contribution guidelines. > > - **Documentation**: > - Adds detailed code reading instructions to `CONTRIBUTING.md`. > - Includes sections on project overview, system architecture, API specifications, core API implementation, database and storage, workflow management, testing, and additional services. > - Provides a step-by-step guide for setting up the development environment and contributing to the project. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 4bb3e8ce3e613a87541d88734368762251a012e4. It will automatically update as commits are pushed. --------- Signed-off-by: Diwank Singh Tomer --- CONTRIBUTING.md | 114 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e60c31973..a7cda8b06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,115 @@ To contribute code changes: Please ensure your code follows the existing style and passes all tests. +## Project Overview and Architecture + +### Key Components + +1. **agents-api**: The core API service for Julep. +2. **typespec**: API specifications and contracts. +3. **integrations-service**: Handles external integrations. +4. **embedding-service**: Manages text embeddings. +5. **memory-store**: Handles persistent storage. +6. **llm-proxy**: Proxy for language model interactions. +7. **scheduler**: Manages task scheduling. +8. **gateway**: API gateway and routing. +9. **monitoring**: System monitoring and metrics. + +### Technology Stack + +- **FastAPI**: Web framework for building APIs +- **TypeSpec**: API specification language +- **Cozo**: Database system +- **Temporal**: Workflow engine +- **Docker**: Containerization + +### Relationships Between Components + +The `agents-api` serves as the central component, interacting with most other services: +- It uses `typespec` definitions for API contracts. +- Communicates with `integrations-service` for external tool interactions. +- Utilizes `embedding-service` for text processing. +- Stores data in `memory-store`. +- Interacts with language models through `llm-proxy`. +- Uses `scheduler` for task management. +- All API requests pass through the `gateway`. +- `monitoring` observes the entire system. + +## Understanding the Codebase + +To get a comprehensive understanding of Julep, we recommend exploring the codebase in the following order: + +1. **Project Overview** + - Read `README.md` in the root directory + - Explore `docs/` for detailed documentation + +2. **System Architecture** + - Examine `docker-compose.yml` in the root directory + - Review `deploy/` directory for different deployment configurations + +3. **API Specifications** + - Learn about TypeSpec: https://typespec.io/docs/ + - Explore `typespec/` directory: + - Start with `common/` folder + - Review `main.tsp` + - Examine each module sequentially + +4. **Core API Implementation** + - Learn about FastAPI: https://fastapi.tiangolo.com/ + - Explore `agents-api/` directory: + - Review `README.md` for an overview + - Examine `routers/` for API endpoints + - Look into `models/` for data models + +5. **Database and Storage** + - Learn about Cozo: https://docs.cozodb.org/en/latest/tutorial.html + - Review `agents-api/README.md` for database schema + - Explore `agents-api/models/` for database queries + +6. **Workflow Management** + - Learn about Temporal: https://docs.temporal.io/develop/python + - Explore `agents-api/activities/` for individual workflow steps + - Review `agents-api/workflows/task_execution/` for main workflow logic + +7. **Testing** + - Examine `agents-api/tests/` for test cases + +8. **Additional Services** + - Explore other service directories (`integrations-service/`, `embedding-service/`, etc.) to understand their specific roles and implementations + +## Contributing Guidelines + +1. **Set Up Development Environment** + - Clone the repository + - Install Docker and Docker Compose + - Set up necessary API keys and environment variables + +2. **Choose an Area to Contribute** + - Check the issue tracker for open issues + - Look for "good first issue" labels for newcomers + +3. **Make Changes** + - Create a new branch for your changes + - Write clean, well-documented code + - Ensure your changes adhere to the project's coding standards + +4. **Test Your Changes** + - Run existing tests + - Add new tests for new functionality + - Ensure all tests pass before submitting your changes + +5. **Submit a Pull Request** + - Provide a clear description of your changes + - Reference any related issues + - Be prepared to respond to feedback and make adjustments + +6. **Code Review** + - Address any comments or suggestions from reviewers + - Make necessary changes and push updates to your branch + +7. **Merge** + - Once approved, your changes will be merged into the main branch + ### Documentation Improvements Improvements to documentation are always appreciated! If you see areas that could be clarified or expanded, feel free to make the changes and submit a pull request. @@ -98,4 +207,7 @@ This command generates a JWT token that will be valid for 10 days. ##### Troubleshooting - Ensure that all required Docker images are available. - Check for missing environment variables in the `.env` file. -- Use the `docker compose logs` command to view detailed logs for debugging. \ No newline at end of file +- Use the `docker compose logs` command to view detailed logs for debugging. + + +Remember, contributions aren't limited to code. Documentation improvements, bug reports, and feature suggestions are also valuable contributions to the project. From 2d62857458a254c48252993693cf04973d1e58d5 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 21:58:49 -0400 Subject: [PATCH 06/16] fix(agents-api): Switch to monkeypatching because everything is shit (#573) Signed-off-by: Diwank Singh Tomer ---- > [!IMPORTANT] > Refactor validation logic using monkeypatching and add new models and custom types in `openapi_model.py`. > > - **Validation Refactor**: > - Switch from subclassing to monkeypatching for validation functions in `EvaluateStep`, `ToolCallStep`, `PromptStep`, `SetStep`, `LogStep`, `ReturnStep`, `YieldStep`, `IfElseWorkflowStep`, and `MapReduceStep`. > - Add validators for Python expressions and Jinja templates. > - **Model Changes**: > - Add `CreateTransitionRequest` and `CreateEntryRequest` classes. > - Define custom types `ChatMLContent`, `ChatMLRole`, `ChatMLSource`, `ExecutionStatus`, and `TransitionType`. > - **Misc**: > - Allow extra fields in `CreateTaskRequest`, `PatchTaskRequest`, and `UpdateTaskRequest` using `ConfigDict`. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 8c03d93701a454327d6b458177e0626ae165d2a0. It will automatically update as commits are pushed. Signed-off-by: Diwank Singh Tomer --- .../agents_api/autogen/openapi_model.py | 339 +++++++++++------- 1 file changed, 214 insertions(+), 125 deletions(-) diff --git a/agents-api/agents_api/autogen/openapi_model.py b/agents-api/agents_api/autogen/openapi_model.py index 48811eb20..bff2221eb 100644 --- a/agents-api/agents_api/autogen/openapi_model.py +++ b/agents-api/agents_api/autogen/openapi_model.py @@ -6,7 +6,14 @@ import jinja2 from litellm.utils import _select_tokenizer as select_tokenizer from litellm.utils import token_counter -from pydantic import AwareDatetime, Field, field_validator, model_validator, validator +from pydantic import ( + AwareDatetime, + Field, + computed_field, + field_validator, + model_validator, + validator, +) from ..common.utils.datetime import utcnow from .Agents import * @@ -155,7 +162,7 @@ def from_model_input( # Patch Task Workflow Steps -# -------------------------------------- +# ------------------------- def validate_python_expression(expr: str) -> tuple[bool, str]: @@ -186,145 +193,255 @@ def validate_jinja_template(template: str) -> tuple[bool, str]: return False, f"TemplateSyntaxError in '{template}': {str(e)}" -_EvaluateStep = EvaluateStep +@field_validator("evaluate") +def validate_evaluate_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError(f"Invalid Python expression in key '{key}': {error}") + return v + + +EvaluateStep.validate_evaluate_expressions = validate_evaluate_expressions -class EvaluateStep(_EvaluateStep): - @field_validator("evaluate") - def validate_evaluate_expressions(cls, v): +@field_validator("arguments") +def validate_arguments(cls, v): + if isinstance(v, dict): for key, expr in v.items(): - is_valid, error = validate_python_expression(expr) - if not is_valid: - raise ValueError(f"Invalid Python expression in key '{key}': {error}") - return v + if isinstance(expr, str): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError( + f"Invalid Python expression in arguments key '{key}': {error}" + ) + return v -_ToolCallStep = ToolCallStep +ToolCallStep.validate_arguments = validate_arguments -class ToolCallStep(_ToolCallStep): - @field_validator("arguments") - def validate_arguments(cls, v): - if isinstance(v, dict): - for key, expr in v.items(): - if isinstance(expr, str): - is_valid, error = validate_python_expression(expr) - if not is_valid: - raise ValueError( - f"Invalid Python expression in arguments key '{key}': {error}" - ) - return v +# Add the new validator function +@field_validator("prompt") +def validate_prompt(cls, v): + if isinstance(v, str): + is_valid, error = validate_jinja_template(v) + if not is_valid: + raise ValueError(f"Invalid Jinja template in prompt: {error}") + elif isinstance(v, list): + for item in v: + if "content" in item: + is_valid, error = validate_jinja_template(item["content"]) + if not is_valid: + raise ValueError( + f"Invalid Jinja template in prompt content: {error}" + ) + return v -_PromptStep = PromptStep +# Patch the original PromptStep class to add the new validator +PromptStep.validate_prompt = validate_prompt -class PromptStep(_PromptStep): - @field_validator("prompt") - def validate_prompt(cls, v): - if isinstance(v, str): - is_valid, error = validate_jinja_template(v) - if not is_valid: - raise ValueError(f"Invalid Jinja template in prompt: {error}") - elif isinstance(v, list): - for item in v: - if "content" in item: - is_valid, error = validate_jinja_template(item["content"]) - if not is_valid: - raise ValueError( - f"Invalid Jinja template in prompt content: {error}" - ) - return v +@field_validator("set") +def validate_set_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) + if not is_valid: + raise ValueError(f"Invalid Python expression in set key '{key}': {error}") + return v -_SetStep = SetStep +SetStep.validate_set_expressions = validate_set_expressions -class SetStep(_SetStep): - @field_validator("set") - def validate_set_expressions(cls, v): - for key, expr in v.items(): - is_valid, error = validate_python_expression(expr) - if not is_valid: - raise ValueError( - f"Invalid Python expression in set key '{key}': {error}" - ) - return v +@field_validator("log") +def validate_log_template(cls, v): + is_valid, error = validate_jinja_template(v) + if not is_valid: + raise ValueError(f"Invalid Jinja template in log: {error}") + return v -_LogStep = LogStep +LogStep.validate_log_template = validate_log_template -class LogStep(_LogStep): - @field_validator("log") - def validate_log_template(cls, v): - is_valid, error = validate_jinja_template(v) +@field_validator("return_") +def validate_return_expressions(cls, v): + for key, expr in v.items(): + is_valid, error = validate_python_expression(expr) if not is_valid: - raise ValueError(f"Invalid Jinja template in log: {error}") - return v + raise ValueError( + f"Invalid Python expression in return key '{key}': {error}" + ) + return v -_ReturnStep = ReturnStep +ReturnStep.validate_return_expressions = validate_return_expressions -class ReturnStep(_ReturnStep): - @field_validator("return_") - def validate_return_expressions(cls, v): +@field_validator("arguments") +def validate_yield_arguments(cls, v): + if isinstance(v, dict): for key, expr in v.items(): is_valid, error = validate_python_expression(expr) if not is_valid: raise ValueError( - f"Invalid Python expression in return key '{key}': {error}" + f"Invalid Python expression in yield arguments key '{key}': {error}" ) - return v + return v -_YieldStep = YieldStep +YieldStep.validate_yield_arguments = validate_yield_arguments -class YieldStep(_YieldStep): - @field_validator("arguments") - def validate_yield_arguments(cls, v): - if isinstance(v, dict): - for key, expr in v.items(): - is_valid, error = validate_python_expression(expr) - if not is_valid: - raise ValueError( - f"Invalid Python expression in yield arguments key '{key}': {error}" - ) - return v +@field_validator("if_") +def validate_if_expression(cls, v): + is_valid, error = validate_python_expression(v) + if not is_valid: + raise ValueError(f"Invalid Python expression in if condition: {error}") + return v + +IfElseWorkflowStep.validate_if_expression = validate_if_expression -_IfElseWorkflowStep = IfElseWorkflowStep +@field_validator("over") +def validate_over_expression(cls, v): + is_valid, error = validate_python_expression(v) + if not is_valid: + raise ValueError(f"Invalid Python expression in over: {error}") + return v -class IfElseWorkflowStep(_IfElseWorkflowStep): - @field_validator("if_") - def validate_if_expression(cls, v): + +@field_validator("reduce") +def validate_reduce_expression(cls, v): + if v is not None: is_valid, error = validate_python_expression(v) if not is_valid: - raise ValueError(f"Invalid Python expression in if condition: {error}") - return v + raise ValueError(f"Invalid Python expression in reduce: {error}") + return v -_MapReduceStep = MapReduceStep +MapReduceStep.validate_over_expression = validate_over_expression +MapReduceStep.validate_reduce_expression = validate_reduce_expression -class MapReduceStep(_MapReduceStep): - @field_validator("over") - def validate_over_expression(cls, v): - is_valid, error = validate_python_expression(v) - if not is_valid: - raise ValueError(f"Invalid Python expression in over: {error}") - return v +# Patch workflow +# -------------- - @field_validator("reduce") - def validate_reduce_expression(cls, v): - if v is not None: - is_valid, error = validate_python_expression(v) - if not is_valid: - raise ValueError(f"Invalid Python expression in reduce: {error}") - return v +_CreateTaskRequest = CreateTaskRequest + +CreateTaskRequest.model_config = ConfigDict( + **{ + **_CreateTaskRequest.model_config, + "extra": "allow", + } +) + + +@model_validator(mode="after") +def validate_subworkflows(self): + subworkflows = { + k: v + for k, v in self.model_dump().items() + if k not in _CreateTaskRequest.model_fields + } + + for workflow_name, workflow_definition in subworkflows.items(): + try: + WorkflowType.model_validate(workflow_definition) + setattr(self, workflow_name, WorkflowType(workflow_definition)) + except Exception as e: + raise ValueError(f"Invalid subworkflow '{workflow_name}': {str(e)}") + return self + + +CreateTaskRequest.validate_subworkflows = validate_subworkflows + + +# Custom types (not generated correctly) +# -------------------------------------- + +ChatMLContent = ( + list[ChatMLTextContentPart | ChatMLImageContentPart] + | Tool + | ChosenToolCall + | str + | ToolResponse + | list[ + list[ChatMLTextContentPart | ChatMLImageContentPart] + | Tool + | ChosenToolCall + | str + | ToolResponse + ] +) + +# Extract ChatMLRole +ChatMLRole = BaseEntry.model_fields["role"].annotation + +# Extract ChatMLSource +ChatMLSource = BaseEntry.model_fields["source"].annotation + +# Extract ExecutionStatus +ExecutionStatus = Execution.model_fields["status"].annotation + +# Extract TransitionType +TransitionType = Transition.model_fields["type"].annotation + +# Assertions to ensure consistency (optional, but recommended for runtime checks) +assert ChatMLRole == BaseEntry.model_fields["role"].annotation +assert ChatMLSource == BaseEntry.model_fields["source"].annotation +assert ExecutionStatus == Execution.model_fields["status"].annotation +assert TransitionType == Transition.model_fields["type"].annotation + + +# Create models +# ------------- + + +class CreateTransitionRequest(Transition): + # The following fields are optional in this + + id: UUID | None = None + execution_id: UUID | None = None + created_at: AwareDatetime | None = None + updated_at: AwareDatetime | None = None + metadata: dict[str, Any] | None = None + task_token: str | None = None + + +class CreateEntryRequest(BaseEntry): + timestamp: Annotated[ + float, Field(ge=0.0, default_factory=lambda: utcnow().timestamp()) + ] + + @classmethod + def from_model_input( + cls: Type[Self], + model: str, + *, + role: ChatMLRole, + content: ChatMLContent, + name: str | None = None, + source: ChatMLSource, + **kwargs: dict, + ) -> Self: + tokenizer: dict = select_tokenizer(model=model) + token_count = token_counter( + model=model, messages=[{"role": role, "content": content, "name": name}] + ) + + return cls( + role=role, + content=content, + name=name, + source=source, + tokenizer=tokenizer["type"], + token_count=token_count, + **kwargs, + ) # Workflow related models @@ -427,34 +544,6 @@ class Task(_Task): ] -_CreateTaskRequest = CreateTaskRequest - - -class CreateTaskRequest(_CreateTaskRequest): - model_config = ConfigDict( - **{ - **_CreateTaskRequest.model_config, - "extra": "allow", - } - ) - - @model_validator(mode="after") - def validate_subworkflows(self) -> Self: - subworkflows = { - k: v - for k, v in self.model_dump().items() - if k not in _CreateTaskRequest.model_fields - } - - for workflow_name, workflow_definition in subworkflows.items(): - try: - WorkflowType.model_validate(workflow_definition) - setattr(self, workflow_name, WorkflowType(workflow_definition)) - except Exception as e: - raise ValueError(f"Invalid subworkflow '{workflow_name}': {str(e)}") - return self - - CreateOrUpdateTaskRequest = CreateTaskRequest _PatchTaskRequest = PatchTaskRequest From 85e992990636123ace3788323f182c53e58c4efd Mon Sep 17 00:00:00 2001 From: Hamada Salhab Date: Thu, 3 Oct 2024 17:21:50 +0300 Subject: [PATCH 07/16] feat(agents-api): Add embeddings to doc get/list response (#578) --- agents-api/agents_api/autogen/Docs.py | 7 +++++++ agents-api/agents_api/models/docs/get_doc.py | 4 +++- agents-api/agents_api/models/docs/list_docs.py | 4 +++- cozo.db | Bin 0 -> 12288 bytes typespec/docs/models.tsp | 4 ++++ 5 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 cozo.db diff --git a/agents-api/agents_api/autogen/Docs.py b/agents-api/agents_api/autogen/Docs.py index a7023ddfc..0c1524e48 100644 --- a/agents-api/agents_api/autogen/Docs.py +++ b/agents-api/agents_api/autogen/Docs.py @@ -57,6 +57,13 @@ class Doc(BaseModel): """ Contents of the document """ + embeddings: Annotated[ + list[float] | list[list[float]] | None, + Field(None, json_schema_extra={"readOnly": True}), + ] + """ + Embeddings for the document + """ class DocOwner(BaseModel): diff --git a/agents-api/agents_api/models/docs/get_doc.py b/agents-api/agents_api/models/docs/get_doc.py index 84cd181ec..4b3996c27 100644 --- a/agents-api/agents_api/models/docs/get_doc.py +++ b/agents-api/agents_api/models/docs/get_doc.py @@ -37,6 +37,7 @@ one=True, transform=lambda d: { "content": [s[1] for s in sorted(d["snippet_data"], key=lambda x: x[0])], + "embeddings": [s[2] for s in sorted(d["snippet_data"], key=lambda x: x[0])], **d, }, ) @@ -68,8 +69,9 @@ def get_doc( doc_id, index, content, + embedding, }, - snippet_data = [index, content] + snippet_data = [index, content, embedding] ?[ id, diff --git a/agents-api/agents_api/models/docs/list_docs.py b/agents-api/agents_api/models/docs/list_docs.py index afdf06c2d..3c095c2db 100644 --- a/agents-api/agents_api/models/docs/list_docs.py +++ b/agents-api/agents_api/models/docs/list_docs.py @@ -34,6 +34,7 @@ Doc, transform=lambda d: { "content": [s[1] for s in sorted(d["snippet_data"], key=lambda x: x[0])], + "embeddings": [s[2] for s in sorted(d["snippet_data"], key=lambda x: x[0])], **d, }, ) @@ -67,8 +68,9 @@ def list_docs( doc_id: id, index, content, + embedding, }}, - snippet_data = [index, content] + snippet_data = [index, content, embedding] ?[ owner_type, diff --git a/cozo.db b/cozo.db new file mode 100644 index 0000000000000000000000000000000000000000..b1bc4a7a55dbc3c8ce20447660fa024c727354b6 GIT binary patch literal 12288 zcmeI1&ubGw6vt(OKmZ5; z0U!VbfB+Bx0zd!=00AHX1pY??u5x5-bW~|v;p8@>mVeKeBQ;gZWz3vzX0nBxEf00e*l5C8%|00;m9AOHmZfWX5gb;x`)o@5Ni zZI|m*wnHM?F_(DTq(Va}e|_BYh)Z855lMj5R~=jFx|9=}aMEmv)-PIl5Qo1Mza=AW zOgMIy&JyO>4zG8;Dr2(k-0azOo>Upf73wwCGeN-W%~e0>7}s$j zUp8ALtVB=t2wfq}6bz#jD=T}HwotC!Ec}om{YB$e>|buIPx)TN8*4Sf8f(R>+gQtc z{GIxFpU}$sKHKVgzK3OTPj`wFWgjf4UFM-Ea8SFkA-NDJOH_t^)eW}Nyh24!!BP(2Z2iJj5>WRxozbqF95y+TBv2x literal 0 HcmV?d00001 diff --git a/typespec/docs/models.tsp b/typespec/docs/models.tsp index ee283fe02..f01b379c6 100644 --- a/typespec/docs/models.tsp +++ b/typespec/docs/models.tsp @@ -23,6 +23,10 @@ model Doc { /** Contents of the document */ content: string | string[]; + + /** Embeddings for the document */ + @visibility("read") + embeddings?: float32[] | float32[][]; } /** Payload for creating a doc */ From 3ad19260b4bb8da6b839243d3393030dcba405e3 Mon Sep 17 00:00:00 2001 From: Hamada Salhab Date: Thu, 3 Oct 2024 21:01:59 +0300 Subject: [PATCH 08/16] Delete cozo.db This was uploaded by mistake --- cozo.db | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cozo.db diff --git a/cozo.db b/cozo.db deleted file mode 100644 index b1bc4a7a55dbc3c8ce20447660fa024c727354b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI1&ubGw6vt(OKmZ5; z0U!VbfB+Bx0zd!=00AHX1pY??u5x5-bW~|v;p8@>mVeKeBQ;gZWz3vzX0nBxEf00e*l5C8%|00;m9AOHmZfWX5gb;x`)o@5Ni zZI|m*wnHM?F_(DTq(Va}e|_BYh)Z855lMj5R~=jFx|9=}aMEmv)-PIl5Qo1Mza=AW zOgMIy&JyO>4zG8;Dr2(k-0azOo>Upf73wwCGeN-W%~e0>7}s$j zUp8ALtVB=t2wfq}6bz#jD=T}HwotC!Ec}om{YB$e>|buIPx)TN8*4Sf8f(R>+gQtc z{GIxFpU}$sKHKVgzK3OTPj`wFWgjf4UFM-Ea8SFkA-NDJOH_t^)eW}Nyh24!!BP(2Z2iJj5>WRxozbqF95y+TBv2x From 4992615da5d702956fc9dd8f29d90cf1f4bad96f Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Fri, 4 Oct 2024 05:31:42 +0530 Subject: [PATCH 09/16] Update lint-and-format.yml --- .github/workflows/lint-and-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-format.yml b/.github/workflows/lint-and-format.yml index 65e4983c4..ab74c7e9b 100644 --- a/.github/workflows/lint-and-format.yml +++ b/.github/workflows/lint-and-format.yml @@ -37,7 +37,7 @@ jobs: uses: actions/cache@v4 with: path: agents-api/.pytype - key: ${{ runner.os }}-agents-api-pytype-${{ hashFiles('agents-api/**/*.py') }} + key: ${{ runner.os }}-agents-api-pytype- restore-keys: | ${{ runner.os }}-agents-api-pytype- From 9c38da1a42c29da7218dac9696b1d67d9ced2538 Mon Sep 17 00:00:00 2001 From: Vivek Gurudutt K <127002789+VivekGuruduttK28@users.noreply.github.com> Date: Fri, 4 Oct 2024 05:40:54 +0530 Subject: [PATCH 10/16] Enhanced the error messages (#575) This PR is to fix the issue mentioned in #572 I have made the required changes in the files create_agent.py, create_or_update_agent.py and delete_agent.py. I have added descriptions to QueryException, ValidationError and TypeError. ---- > [!IMPORTANT] > Enhanced error messages for exceptions in agent-related files to provide detailed guidance on potential issues. > > - **Error Messages**: > - Enhanced error messages for `QueryException`, `ValidationError`, and `TypeError` in `create_agent.py`, `create_or_update_agent.py`, and `delete_agent.py`. > - `QueryException`: Now includes a detailed message about potential causes related to database query failures. > - `ValidationError`: Provides guidance on checking input data for missing or incorrect fields. > - `TypeError`: Describes type mismatch issues and suggests reviewing input data types. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 049d7eea196b74158e4fc4d83049656c7e7fa12e. It will automatically update as commits are pushed. Co-authored-by: Diwank Singh Tomer --- agents-api/agents_api/models/agent/create_agent.py | 6 +++--- .../agents_api/models/agent/create_or_update_agent.py | 6 +++--- agents-api/agents_api/models/agent/delete_agent.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/agents-api/agents_api/models/agent/create_agent.py b/agents-api/agents_api/models/agent/create_agent.py index 73be4ec77..546d0d441 100644 --- a/agents-api/agents_api/models/agent/create_agent.py +++ b/agents-api/agents_api/models/agent/create_agent.py @@ -32,9 +32,9 @@ in str(e): lambda *_: HTTPException( detail="developer not found", status_code=403 ), - QueryException: partialclass(HTTPException, status_code=400), - ValidationError: partialclass(HTTPException, status_code=400), - TypeError: partialclass(HTTPException, status_code=400), + QueryException: partialclass(HTTPException, status_code=400, detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), + ValidationError: partialclass(HTTPException, status_code=400, detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), + TypeError: partialclass(HTTPException, status_code=400, detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), } ) @wrap_in_class( diff --git a/agents-api/agents_api/models/agent/create_or_update_agent.py b/agents-api/agents_api/models/agent/create_or_update_agent.py index 156c8ae61..17e01fccb 100644 --- a/agents-api/agents_api/models/agent/create_or_update_agent.py +++ b/agents-api/agents_api/models/agent/create_or_update_agent.py @@ -27,9 +27,9 @@ @rewrap_exceptions( { - QueryException: partialclass(HTTPException, status_code=400), - ValidationError: partialclass(HTTPException, status_code=400), - TypeError: partialclass(HTTPException, status_code=400), + QueryException: partialclass(HTTPException, status_code=400,detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), + ValidationError: partialclass(HTTPException, status_code=400,detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), + TypeError: partialclass(HTTPException, status_code=400,detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), } ) @wrap_in_class( diff --git a/agents-api/agents_api/models/agent/delete_agent.py b/agents-api/agents_api/models/agent/delete_agent.py index 926007bdf..cb6b16718 100644 --- a/agents-api/agents_api/models/agent/delete_agent.py +++ b/agents-api/agents_api/models/agent/delete_agent.py @@ -32,9 +32,9 @@ in e.resp["display"]: lambda *_: HTTPException( detail="developer not found or doesnt own resource", status_code=404 ), - QueryException: partialclass(HTTPException, status_code=400), - ValidationError: partialclass(HTTPException, status_code=400), - TypeError: partialclass(HTTPException, status_code=400), + QueryException: partialclass(HTTPException, status_code=400,detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), + ValidationError: partialclass(HTTPException, status_code=400,detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), + TypeError: partialclass(HTTPException, status_code=400,detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), } ) @wrap_in_class( From 51f5e65cf7095c09219dbe60080898b530f36dac Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Thu, 3 Oct 2024 20:11:31 -0400 Subject: [PATCH 11/16] fix(agents-api): Remove unnecessary 'type' property from tool type definition (#574) Signed-off-by: Diwank Singh Tomer ---- > [!IMPORTANT] > Removed 'type' property from tool classes and added computed 'type' property using a function in `Tools.py`, `openapi_model.py`, and `tasks.py`. > > - **Behavior**: > - Removed `type` property from `CreateToolRequest`, `NamedToolChoice`, `PatchToolRequest`, `Tool`, and `UpdateToolRequest` in `Tools.py`. > - Added computed `type` property to `TaskTool`, `Tool`, `UpdateToolRequest`, and `PatchToolRequest` in `openapi_model.py`. > - Updated `task_to_spec()` in `tasks.py` to use computed `type` property. > - **Misc**: > - Removed `type` property from `Tool` and `NamedToolChoice` in `models.tsp`. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 289e87eff9a220b2c4430959f989cca471e36cf9. It will automatically update as commits are pushed. Signed-off-by: Diwank Singh Tomer --- agents-api/agents_api/autogen/Tools.py | 31 ------ .../agents_api/autogen/openapi_model.py | 97 +++++-------------- .../agents_api/common/protocol/tasks.py | 27 ++++-- typespec/tools/models.tsp | 14 --- 4 files changed, 40 insertions(+), 129 deletions(-) diff --git a/agents-api/agents_api/autogen/Tools.py b/agents-api/agents_api/autogen/Tools.py index c2d4199a2..8227e5759 100644 --- a/agents-api/agents_api/autogen/Tools.py +++ b/agents-api/agents_api/autogen/Tools.py @@ -33,10 +33,6 @@ class CreateToolRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Literal["function", "integration", "system", "api_call"] = "function" - """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) - """ name: Annotated[str, Field(max_length=40, pattern="^[^\\W0-9]\\w*$")] """ Name of the tool (must be unique for this agent and a valid python identifier string ) @@ -168,10 +164,6 @@ class NamedToolChoice(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Literal["function", "integration", "system", "api_call"] - """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) - """ function: FunctionCallOption | None = None @@ -183,10 +175,6 @@ class PatchToolRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Literal["function", "integration", "system", "api_call"] = "function" - """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) - """ name: Annotated[str | None, Field(None, max_length=40, pattern="^[^\\W0-9]\\w*$")] """ Name of the tool (must be unique for this agent and a valid python identifier string ) @@ -247,10 +235,6 @@ class Tool(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Literal["function", "integration", "system", "api_call"] = "function" - """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) - """ name: Annotated[str, Field(max_length=40, pattern="^[^\\W0-9]\\w*$")] """ Name of the tool (must be unique for this agent and a valid python identifier string ) @@ -291,10 +275,6 @@ class UpdateToolRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Literal["function", "integration", "system", "api_call"] = "function" - """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) - """ name: Annotated[str, Field(max_length=40, pattern="^[^\\W0-9]\\w*$")] """ Name of the tool (must be unique for this agent and a valid python identifier string ) @@ -316,14 +296,3 @@ class ChosenFunctionCall(ChosenToolCall): """ The function to call """ - - -class NamedFunctionChoice(NamedToolChoice): - model_config = ConfigDict( - populate_by_name=True, - ) - type: Literal["function"] = "function" - function: FunctionCallOption - """ - The function to call - """ diff --git a/agents-api/agents_api/autogen/openapi_model.py b/agents-api/agents_api/autogen/openapi_model.py index bff2221eb..0d9390816 100644 --- a/agents-api/agents_api/autogen/openapi_model.py +++ b/agents-api/agents_api/autogen/openapi_model.py @@ -77,88 +77,35 @@ class InputChatMLMessage(Message): pass -# Custom types (not generated correctly) -# -------------------------------------- - -ChatMLContent = ( - list[ChatMLTextContentPart | ChatMLImageContentPart] - | Tool - | ChosenToolCall - | str - | ToolResponse - | list[ - list[ChatMLTextContentPart | ChatMLImageContentPart] - | Tool - | ChosenToolCall - | str - | ToolResponse - ] -) - -# Extract ChatMLRole -ChatMLRole = BaseEntry.model_fields["role"].annotation - -# Extract ChatMLSource -ChatMLSource = BaseEntry.model_fields["source"].annotation - -# Extract ExecutionStatus -ExecutionStatus = Execution.model_fields["status"].annotation - -# Extract TransitionType -TransitionType = Transition.model_fields["type"].annotation - -# Assertions to ensure consistency (optional, but recommended for runtime checks) -assert ChatMLRole == BaseEntry.model_fields["role"].annotation -assert ChatMLSource == BaseEntry.model_fields["source"].annotation -assert ExecutionStatus == Execution.model_fields["status"].annotation -assert TransitionType == Transition.model_fields["type"].annotation - - -# Create models -# ------------- +# Patches +# ------- -class CreateTransitionRequest(Transition): - # The following fields are optional in this +def type_property(self: BaseModel) -> str: + return ( + "function" + if self.function + else "integration" + if self.integration + else "system" + if self.system + else "api_call" + if self.api_call + else None + ) - id: UUID | None = None - execution_id: UUID | None = None - created_at: AwareDatetime | None = None - updated_at: AwareDatetime | None = None - metadata: dict[str, Any] | None = None - task_token: str | None = None +# Patch original Tool class to add 'type' property +TaskTool.type = computed_field(property(type_property)) -class CreateEntryRequest(BaseEntry): - timestamp: Annotated[ - float, Field(ge=0.0, default_factory=lambda: utcnow().timestamp()) - ] +# Patch original Tool class to add 'type' property +Tool.type = computed_field(property(type_property)) - @classmethod - def from_model_input( - cls: Type[Self], - model: str, - *, - role: ChatMLRole, - content: ChatMLContent, - name: str | None = None, - source: ChatMLSource, - **kwargs: dict, - ) -> Self: - tokenizer: dict = select_tokenizer(model=model) - token_count = token_counter( - model=model, messages=[{"role": role, "content": content, "name": name}] - ) +# Patch original UpdateToolRequest class to add 'type' property +UpdateToolRequest.type = computed_field(property(type_property)) - return cls( - role=role, - content=content, - name=name, - source=source, - tokenizer=tokenizer["type"], - token_count=token_count, - **kwargs, - ) +# Patch original PatchToolRequest class to add 'type' property +PatchToolRequest.type = computed_field(property(type_property)) # Patch Task Workflow Steps diff --git a/agents-api/agents_api/common/protocol/tasks.py b/agents-api/agents_api/common/protocol/tasks.py index 6892d7098..bbb5c28d3 100644 --- a/agents-api/agents_api/common/protocol/tasks.py +++ b/agents-api/agents_api/common/protocol/tasks.py @@ -218,19 +218,28 @@ def task_to_spec( task: Task | CreateTaskRequest | UpdateTaskRequest | PatchTaskRequest, **model_opts ) -> TaskSpecDef | PartialTaskSpecDef: task_data = task.model_dump(**model_opts) - main = task_data.pop("main") - workflows = [Workflow(name="main", steps=main)] + if "tools" in task_data: + del task_data["tools"] - for k in list(task_data.keys()): - if k in TaskSpec.model_fields.keys(): - continue + tools = [] + for tool in task.tools: + tool_spec = getattr(tool, tool.type) - steps = task_data.pop(k) - workflows.append(Workflow(name=k, steps=steps)) + tools.append( + TaskToolDef( + type=tool.type, + spec=tool_spec.model_dump(), + **tool.model_dump(exclude={"type"}), + ) + ) - tools = task_data.pop("tools", []) - tools = [TaskToolDef(spec=tool.pop(tool["type"]), **tool) for tool in tools] + workflows = [Workflow(name="main", steps=task_data.pop("main"))] + + for key, steps in list(task_data.items()): + if key not in TaskSpec.model_fields: + workflows.append(Workflow(name=key, steps=steps)) + del task_data[key] cls = PartialTaskSpecDef if isinstance(task, PatchTaskRequest) else TaskSpecDef diff --git a/typespec/tools/models.tsp b/typespec/tools/models.tsp index be0fb4f68..8a8cead44 100644 --- a/typespec/tools/models.tsp +++ b/typespec/tools/models.tsp @@ -74,9 +74,6 @@ model SystemDef { // TODO: We should use this model for all tools, not just functions and discriminate on the type model Tool { - /** Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) */ - type: ToolType = ToolType.function; - /** Name of the tool (must be unique for this agent and a valid python identifier string )*/ name: validPythonIdentifier; @@ -95,24 +92,13 @@ model FunctionCallOption { name: string; } -@discriminator("type") model NamedToolChoice { - /** Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) */ - type: ToolType; - function?: FunctionCallOption; integration?: never; // TODO: Implement system?: never; // TODO: Implement api_call?: never; // TODO: Implement } -model NamedFunctionChoice extends NamedToolChoice { - type: ToolType.function; - - /** The function to call */ - function: FunctionCallOption; -} - model ToolResponse { @key id: uuid; From 06813fbe4afde299420d6d285fc4ee3b4d9a6dbd Mon Sep 17 00:00:00 2001 From: JeevaRamanathan <64531160+JeevaRamanathan@users.noreply.github.com> Date: Fri, 4 Oct 2024 05:42:58 +0530 Subject: [PATCH 12/16] Enhanced error message in create, delete agent (#572) Related to #568 Enhanced HTTPException in `create_agent.py` and `delete_agent.py`. As this issue states, we aim to improve error messages throughout the agents-api. I believe this issue can accommodate multiple pull requests. Your suggestions are highly appreciated. ---- > [!IMPORTANT] > Enhanced error messages in `create_agent.py` and `delete_agent.py` for better clarity in `HTTPException` details. > > - **Error Messages**: > - In `create_agent.py`, updated `HTTPException` detail to "Developer not found. Please ensure the provided auth token (which refers to your developer_id) is valid and the developer has the necessary permissions to create an agent." > - In `delete_agent.py`, updated `HTTPException` detail to "The specified developer does not own the requested resource. Please verify the ownership or check if the developer ID is correct." > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for a085d4193ec0c36ba407f340c77e81834419dd69. It will automatically update as commits are pushed. Co-authored-by: Diwank Singh Tomer --- agents-api/agents_api/models/agent/create_agent.py | 3 ++- agents-api/agents_api/models/agent/delete_agent.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/agents-api/agents_api/models/agent/create_agent.py b/agents-api/agents_api/models/agent/create_agent.py index 546d0d441..c1451bb30 100644 --- a/agents-api/agents_api/models/agent/create_agent.py +++ b/agents-api/agents_api/models/agent/create_agent.py @@ -30,7 +30,8 @@ lambda e: isinstance(e, QueryException) and "asserted to return some results, but returned none" in str(e): lambda *_: HTTPException( - detail="developer not found", status_code=403 + detail="Developer not found. Please ensure the provided auth token (which refers to your developer_id) is valid and the developer has the necessary permissions to create an agent.", + status_code=403 ), QueryException: partialclass(HTTPException, status_code=400, detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), ValidationError: partialclass(HTTPException, status_code=400, detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), diff --git a/agents-api/agents_api/models/agent/delete_agent.py b/agents-api/agents_api/models/agent/delete_agent.py index cb6b16718..d8f710481 100644 --- a/agents-api/agents_api/models/agent/delete_agent.py +++ b/agents-api/agents_api/models/agent/delete_agent.py @@ -30,7 +30,8 @@ lambda e: isinstance(e, QueryException) and "Developer does not own resource" in e.resp["display"]: lambda *_: HTTPException( - detail="developer not found or doesnt own resource", status_code=404 + detail="The specified developer does not own the requested resource. Please verify the ownership or check if the developer ID is correct.", + status_code=404 ), QueryException: partialclass(HTTPException, status_code=400,detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), ValidationError: partialclass(HTTPException, status_code=400,detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), From c5ea3ba75e9e1ef86efee81c093f46565e98b00b Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Thu, 3 Oct 2024 20:38:48 -0400 Subject: [PATCH 13/16] feat(agents-api): Naive speed improvement to cozo queries by adding limit=1 to all relevant queries (#580) Signed-off-by: Diwank Singh Tomer ---- > [!IMPORTANT] > Improve CozoDB query performance by adding `:limit 1` to relevant queries and restructure CI/CD workflows for agents-api. > > - **Performance Improvement**: > - Add `:limit 1` to CozoDB queries in `get_agent.py`, `get_cached_response.py`, and `prepare_chat_context.py` among others to improve query performance. > - **CI/CD Workflow**: > - Rename `lint-and-format.yml` to `lint-agents-api-pr.yml` and remove typecheck and test steps. > - Add `test-agents-api-pr.yml` for running tests on pull requests. > - Add `typecheck-agents-api-pr.yml` for type-checking on pull requests. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for 4cd6bb0379e5afe3fb9941a338a1d7ab89f8ca0d. It will automatically update as commits are pushed. --------- Signed-off-by: Diwank Singh Tomer --- ...-and-format.yml => lint-agents-api-pr.yml} | 18 ------ .github/workflows/test-agents-api-pr.yml | 48 ++++++++++++++++ .github/workflows/typecheck-agents-api-pr.yml | 56 +++++++++++++++++++ .../agents_api/models/agent/get_agent.py | 2 + .../models/chat/get_cached_response.py | 1 + .../models/chat/prepare_chat_context.py | 2 + .../models/developer/get_developer.py | 2 + .../agents_api/models/docs/embed_snippets.py | 1 + agents-api/agents_api/models/docs/get_doc.py | 2 + .../agents_api/models/entry/get_history.py | 4 +- .../execution/create_execution_transition.py | 2 + .../execution/get_execution_transition.py | 4 +- .../execution/get_paused_execution_token.py | 1 + .../execution/get_temporal_workflow_data.py | 2 + .../models/execution/lookup_temporal_data.py | 2 + .../execution/prepare_execution_input.py | 2 + .../models/execution/update_execution.py | 2 + .../agents_api/models/session/get_session.py | 5 +- .../models/session/prepare_session_data.py | 2 + .../agents_api/models/tools/create_tools.py | 1 + .../agents_api/models/tools/get_tool.py | 2 + .../tools/get_tool_args_from_metadata.py | 4 ++ agents-api/agents_api/models/user/get_user.py | 5 +- agents-api/agents_api/models/utils.py | 4 ++ 24 files changed, 152 insertions(+), 22 deletions(-) rename .github/workflows/{lint-and-format.yml => lint-agents-api-pr.yml} (76%) create mode 100644 .github/workflows/test-agents-api-pr.yml create mode 100644 .github/workflows/typecheck-agents-api-pr.yml diff --git a/.github/workflows/lint-and-format.yml b/.github/workflows/lint-agents-api-pr.yml similarity index 76% rename from .github/workflows/lint-and-format.yml rename to .github/workflows/lint-agents-api-pr.yml index ab74c7e9b..90fdd0a4b 100644 --- a/.github/workflows/lint-and-format.yml +++ b/.github/workflows/lint-agents-api-pr.yml @@ -33,35 +33,17 @@ jobs: restore-keys: | ${{ runner.os }}-agents-api-poetry- - - name: Cache pytype - uses: actions/cache@v4 - with: - path: agents-api/.pytype - key: ${{ runner.os }}-agents-api-pytype- - restore-keys: | - ${{ runner.os }}-agents-api-pytype- - - name: Install dependencies run: | cd agents-api poetry install - - name: Typecheck - run: | - cd agents-api - poetry run poe typecheck - - name: Lint and format run: | cd agents-api poetry run poe format poetry run poe lint - - name: Run tests - run: | - cd agents-api - poetry run poe test - - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: "refactor: Lint agents-api (CI)" diff --git a/.github/workflows/test-agents-api-pr.yml b/.github/workflows/test-agents-api-pr.yml new file mode 100644 index 000000000..b0f815634 --- /dev/null +++ b/.github/workflows/test-agents-api-pr.yml @@ -0,0 +1,48 @@ +name: Test agents-api +run-name: ${{ github.actor }} is testing the code + +# TODO: Fix CI github actions +# SCRUM-26 + +on: [pull_request] + +jobs: + Test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install and configure Poetry + uses: snok/install-poetry@v1 + + - name: Configure Poetry to use .venv + run: | + cd agents-api + poetry config virtualenvs.in-project true + + - name: Cache Poetry virtualenv + uses: actions/cache@v4 + with: + path: agents-api/.venv + key: ${{ runner.os }}-agents-api-poetry-${{ hashFiles('agents-api/poetry.lock') }} + restore-keys: | + ${{ runner.os }}-agents-api-poetry- + + - name: Install dependencies + run: | + cd agents-api + poetry install + + - name: Run tests + run: | + cd agents-api + poetry run poe test --fail-limit 1 + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} diff --git a/.github/workflows/typecheck-agents-api-pr.yml b/.github/workflows/typecheck-agents-api-pr.yml new file mode 100644 index 000000000..513390883 --- /dev/null +++ b/.github/workflows/typecheck-agents-api-pr.yml @@ -0,0 +1,56 @@ +name: Typecheck agents-api +run-name: ${{ github.actor }} is typechecking the code + +# TODO: Fix CI github actions +# SCRUM-26 + +on: [pull_request] + +jobs: + Typecheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install and configure Poetry + uses: snok/install-poetry@v1 + + - name: Configure Poetry to use .venv + run: | + cd agents-api + poetry config virtualenvs.in-project true + + - name: Cache Poetry virtualenv + uses: actions/cache@v4 + with: + path: agents-api/.venv + key: ${{ runner.os }}-agents-api-poetry-${{ hashFiles('agents-api/poetry.lock') }} + restore-keys: | + ${{ runner.os }}-agents-api-poetry- + + - name: Cache pytype + uses: actions/cache@v4 + with: + path: agents-api/.pytype + key: ${{ runner.os }}-agents-api-pytype-${{ github.base_ref }} + restore-keys: | + ${{ runner.os }}-agents-api-pytype- + + - name: Install dependencies + run: | + cd agents-api + poetry install + + - name: Typecheck + run: | + cd agents-api + poetry run poe typecheck + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} diff --git a/agents-api/agents_api/models/agent/get_agent.py b/agents-api/agents_api/models/agent/get_agent.py index 956fa46a5..f8127751a 100644 --- a/agents-api/agents_api/models/agent/get_agent.py +++ b/agents-api/agents_api/models/agent/get_agent.py @@ -101,6 +101,8 @@ def get_agent(*, developer_id: UUID, agent_id: UUID) -> tuple[list[str], dict]: "min_p": min_p, "preset": preset, } + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/chat/get_cached_response.py b/agents-api/agents_api/models/chat/get_cached_response.py index 5440a6703..368c88567 100644 --- a/agents-api/agents_api/models/chat/get_cached_response.py +++ b/agents-api/agents_api/models/chat/get_cached_response.py @@ -9,6 +9,7 @@ def get_cached_response(key: str) -> tuple[str, dict]: query = """ input[key] <- [[$key]] ?[key, value] := input[key], *session_cache{key, value} + :limit 1 """ return (query, {"key": key}) diff --git a/agents-api/agents_api/models/chat/prepare_chat_context.py b/agents-api/agents_api/models/chat/prepare_chat_context.py index 4d521acb0..9be2d64aa 100644 --- a/agents-api/agents_api/models/chat/prepare_chat_context.py +++ b/agents-api/agents_api/models/chat/prepare_chat_context.py @@ -119,6 +119,8 @@ def prepare_chat_context( ?[{', '.join(session_data_fields)}, toolsets] := *_session_data_json {{ {', '.join(session_data_fields)} }}, *_toolsets_json {{ toolsets }} + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/developer/get_developer.py b/agents-api/agents_api/models/developer/get_developer.py index 31ade5334..0ae5421aa 100644 --- a/agents-api/agents_api/models/developer/get_developer.py +++ b/agents-api/agents_api/models/developer/get_developer.py @@ -67,6 +67,8 @@ def get_developer( created_at, updated_at, } + + :limit 1 """ return (query, {"developer_id": developer_id}) diff --git a/agents-api/agents_api/models/docs/embed_snippets.py b/agents-api/agents_api/models/docs/embed_snippets.py index e810d0379..993e76396 100644 --- a/agents-api/agents_api/models/docs/embed_snippets.py +++ b/agents-api/agents_api/models/docs/embed_snippets.py @@ -81,6 +81,7 @@ def embed_snippets( }}, index > {max(snippet_indices)} + :limit 1 :assert none """ diff --git a/agents-api/agents_api/models/docs/get_doc.py b/agents-api/agents_api/models/docs/get_doc.py index 4b3996c27..e81084985 100644 --- a/agents-api/agents_api/models/docs/get_doc.py +++ b/agents-api/agents_api/models/docs/get_doc.py @@ -87,6 +87,8 @@ def get_doc( metadata, }, snippets[snippet_data] + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/entry/get_history.py b/agents-api/agents_api/models/entry/get_history.py index 8918d357f..bd3c0397a 100644 --- a/agents-api/agents_api/models/entry/get_history.py +++ b/agents-api/agents_api/models/entry/get_history.py @@ -131,7 +131,9 @@ def get_history( session_relations[relations], session_id = to_uuid($session_id), created_at = now() - """ + + :limit 1 + """ queries = [ verify_developer_id_query(developer_id), diff --git a/agents-api/agents_api/models/execution/create_execution_transition.py b/agents-api/agents_api/models/execution/create_execution_transition.py index 42c6f1c22..f40395126 100644 --- a/agents-api/agents_api/models/execution/create_execution_transition.py +++ b/agents-api/agents_api/models/execution/create_execution_transition.py @@ -141,6 +141,8 @@ def create_execution_transition( found = length(prev_transitions), valid = if($next_type == "init", found == 0, found > 0), assert(valid, "Invalid transition"), + + :limit 1 """ # Prepare the insert query diff --git a/agents-api/agents_api/models/execution/get_execution_transition.py b/agents-api/agents_api/models/execution/get_execution_transition.py index d3ebf3783..e2b38789a 100644 --- a/agents-api/agents_api/models/execution/get_execution_transition.py +++ b/agents-api/agents_api/models/execution/get_execution_transition.py @@ -65,7 +65,9 @@ def get_execution_transition( is_null(next_tuple), null, {"workflow": next_tuple->0, "step": next_tuple->1}, - ), + ) + + :limit 1 """ get_query += filter diff --git a/agents-api/agents_api/models/execution/get_paused_execution_token.py b/agents-api/agents_api/models/execution/get_paused_execution_token.py index b4c9f9081..44eb8a4da 100644 --- a/agents-api/agents_api/models/execution/get_paused_execution_token.py +++ b/agents-api/agents_api/models/execution/get_paused_execution_token.py @@ -45,6 +45,7 @@ def get_paused_execution_token( execution_id = to_uuid($execution_id), status = "awaiting_input" + :limit 1 :assert some """ diff --git a/agents-api/agents_api/models/execution/get_temporal_workflow_data.py b/agents-api/agents_api/models/execution/get_temporal_workflow_data.py index bb0a462ef..8b1bf4604 100644 --- a/agents-api/agents_api/models/execution/get_temporal_workflow_data.py +++ b/agents-api/agents_api/models/execution/get_temporal_workflow_data.py @@ -45,6 +45,8 @@ def get_temporal_workflow_data( result_run_id, first_execution_run_id, } + + :limit 1 """ return ( diff --git a/agents-api/agents_api/models/execution/lookup_temporal_data.py b/agents-api/agents_api/models/execution/lookup_temporal_data.py index e3c369b94..35f09129b 100644 --- a/agents-api/agents_api/models/execution/lookup_temporal_data.py +++ b/agents-api/agents_api/models/execution/lookup_temporal_data.py @@ -43,6 +43,8 @@ def lookup_temporal_data( *temporal_executions_lookup { id, execution_id, run_id, first_execution_run_id, result_run_id } + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/execution/prepare_execution_input.py b/agents-api/agents_api/models/execution/prepare_execution_input.py index b763a7508..5f30e7f83 100644 --- a/agents-api/agents_api/models/execution/prepare_execution_input.py +++ b/agents-api/agents_api/models/execution/prepare_execution_input.py @@ -187,6 +187,8 @@ def prepare_execution_input( user = null, session = null, arguments = execution->"input" + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/execution/update_execution.py b/agents-api/agents_api/models/execution/update_execution.py index c2f40c7ff..4d0367ae4 100644 --- a/agents-api/agents_api/models/execution/update_execution.py +++ b/agents-api/agents_api/models/execution/update_execution.py @@ -82,6 +82,8 @@ def update_execution( ?[num] := valid_status[num], assert(num > 0, 'Invalid status') + + :limit 1 """ update_query = f""" diff --git a/agents-api/agents_api/models/session/get_session.py b/agents-api/agents_api/models/session/get_session.py index 2d8956eb7..45d971c3f 100644 --- a/agents-api/agents_api/models/session/get_session.py +++ b/agents-api/agents_api/models/session/get_session.py @@ -95,7 +95,10 @@ def get_session( token_budget, context_overflow, @ "END" - }, updated_at = to_int(validity) + }, + updated_at = to_int(validity) + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/session/prepare_session_data.py b/agents-api/agents_api/models/session/prepare_session_data.py index e8cfb7fc7..bbbd9c4cd 100644 --- a/agents-api/agents_api/models/session/prepare_session_data.py +++ b/agents-api/agents_api/models/session/prepare_session_data.py @@ -209,6 +209,8 @@ def prepare_session_data( session_data[session], user_data[users], agent_data[agents] + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index dd8397797..87ea3a9cf 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -80,6 +80,7 @@ def create_tools( name, } + :limit 1 :assert none """ diff --git a/agents-api/agents_api/models/tools/get_tool.py b/agents-api/agents_api/models/tools/get_tool.py index 5ea009064..465fd2efe 100644 --- a/agents-api/agents_api/models/tools/get_tool.py +++ b/agents-api/agents_api/models/tools/get_tool.py @@ -68,6 +68,8 @@ def get_tool( updated_at, created_at, } + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/tools/get_tool_args_from_metadata.py b/agents-api/agents_api/models/tools/get_tool_args_from_metadata.py index ade296a29..2cdb92cb9 100644 --- a/agents-api/agents_api/models/tools/get_tool_args_from_metadata.py +++ b/agents-api/agents_api/models/tools/get_tool_args_from_metadata.py @@ -46,6 +46,8 @@ def tool_args_for_task( # Right values overwrite left values # See: https://docs.cozodb.org/en/latest/functions.html#Func.Vector.concat values = concat(agent_{arg_type}, task_{arg_type}), + + :limit 1 """ queries = [ @@ -88,6 +90,8 @@ def tool_args_for_session( # Right values overwrite left values # See: https://docs.cozodb.org/en/latest/functions.html#Func.Vector.concat values = concat(agent_{arg_type}, session_{arg_type}), + + :limit 1 """ queries = [ diff --git a/agents-api/agents_api/models/user/get_user.py b/agents-api/agents_api/models/user/get_user.py index cc7c6f970..2b4f59c83 100644 --- a/agents-api/agents_api/models/user/get_user.py +++ b/agents-api/agents_api/models/user/get_user.py @@ -67,7 +67,10 @@ def get_user( created_at, updated_at, metadata, - }""" + } + + :limit 1 + """ queries = [ verify_developer_id_query(developer_id), diff --git a/agents-api/agents_api/models/utils.py b/agents-api/agents_api/models/utils.py index c97d92451..c163642c0 100644 --- a/agents-api/agents_api/models/utils.py +++ b/agents-api/agents_api/models/utils.py @@ -127,6 +127,8 @@ def verify_developer_id_query(developer_id: UUID | str) -> str: matched[num], exists = num > 0, assert(exists, "Developer does not exist") + + :limit 1 """ @@ -162,6 +164,8 @@ def verify_developer_owns_resource_query( found[num], exists = num > 0, assert(exists, "Developer does not own resource {resource} with {resource_id_key} {resource_id_value}") + + :limit 1 """ rule = rule_head + rule_body + assertion From 3f7979123396be3c05b913af24524a21f17f72c8 Mon Sep 17 00:00:00 2001 From: creatorrr Date: Fri, 4 Oct 2024 00:39:34 +0000 Subject: [PATCH 14/16] refactor: Lint agents-api (CI) --- .../agents_api/models/agent/create_agent.py | 20 +++++++++++++++---- .../models/agent/create_or_update_agent.py | 18 ++++++++++++++--- .../agents_api/models/agent/delete_agent.py | 20 +++++++++++++++---- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/agents-api/agents_api/models/agent/create_agent.py b/agents-api/agents_api/models/agent/create_agent.py index c1451bb30..a52a7b771 100644 --- a/agents-api/agents_api/models/agent/create_agent.py +++ b/agents-api/agents_api/models/agent/create_agent.py @@ -31,11 +31,23 @@ and "asserted to return some results, but returned none" in str(e): lambda *_: HTTPException( detail="Developer not found. Please ensure the provided auth token (which refers to your developer_id) is valid and the developer has the necessary permissions to create an agent.", - status_code=403 + status_code=403, + ), + QueryException: partialclass( + HTTPException, + status_code=400, + detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.", + ), + ValidationError: partialclass( + HTTPException, + status_code=400, + detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.", + ), + TypeError: partialclass( + HTTPException, + status_code=400, + detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.", ), - QueryException: partialclass(HTTPException, status_code=400, detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), - ValidationError: partialclass(HTTPException, status_code=400, detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), - TypeError: partialclass(HTTPException, status_code=400, detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), } ) @wrap_in_class( diff --git a/agents-api/agents_api/models/agent/create_or_update_agent.py b/agents-api/agents_api/models/agent/create_or_update_agent.py index 17e01fccb..835245787 100644 --- a/agents-api/agents_api/models/agent/create_or_update_agent.py +++ b/agents-api/agents_api/models/agent/create_or_update_agent.py @@ -27,9 +27,21 @@ @rewrap_exceptions( { - QueryException: partialclass(HTTPException, status_code=400,detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), - ValidationError: partialclass(HTTPException, status_code=400,detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), - TypeError: partialclass(HTTPException, status_code=400,detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), + QueryException: partialclass( + HTTPException, + status_code=400, + detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.", + ), + ValidationError: partialclass( + HTTPException, + status_code=400, + detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.", + ), + TypeError: partialclass( + HTTPException, + status_code=400, + detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.", + ), } ) @wrap_in_class( diff --git a/agents-api/agents_api/models/agent/delete_agent.py b/agents-api/agents_api/models/agent/delete_agent.py index d8f710481..c8bdc2106 100644 --- a/agents-api/agents_api/models/agent/delete_agent.py +++ b/agents-api/agents_api/models/agent/delete_agent.py @@ -31,11 +31,23 @@ and "Developer does not own resource" in e.resp["display"]: lambda *_: HTTPException( detail="The specified developer does not own the requested resource. Please verify the ownership or check if the developer ID is correct.", - status_code=404 + status_code=404, + ), + QueryException: partialclass( + HTTPException, + status_code=400, + detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.", + ), + ValidationError: partialclass( + HTTPException, + status_code=400, + detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.", + ), + TypeError: partialclass( + HTTPException, + status_code=400, + detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.", ), - QueryException: partialclass(HTTPException, status_code=400,detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect."), - ValidationError: partialclass(HTTPException, status_code=400,detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format."), - TypeError: partialclass(HTTPException, status_code=400,detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again."), } ) @wrap_in_class( From fe8a8c9d9653b1023a398619f322832a772842b2 Mon Sep 17 00:00:00 2001 From: Ho Yin <88828097+lhy-hoyin@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:39:50 +0800 Subject: [PATCH 15/16] Improve docstrings + minor code refactor (#545) This PR includes: - Adding, formatting and improving of docstring comments - Updating absolute imports to relative imports (similar to other files) ---- > [!IMPORTANT] > Improved docstrings, switched to relative imports, and used a constant for `EMBEDDING_SIZE` for better code clarity and consistency. > > - **Docstrings**: > - Improved and formatted docstrings across multiple files for clarity and consistency. > - Added detailed attribute descriptions in exception classes like `AgentNotFoundError` and `UserNotFoundError`. > - **Imports**: > - Updated absolute imports to relative imports in files like `truncation.py`, `worker.py`, and `messages.py` for consistency. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=julep-ai%2Fjulep&utm_source=github&utm_medium=referral) for c27aebf2cdfb27a2f94306001140974ad2bb3659. It will automatically update as commits are pushed. --------- Co-authored-by: Diwank Singh Tomer --- .../agents_api/activities/truncation.py | 2 +- .../agents_api/clients/worker/worker.py | 2 +- .../agents_api/common/exceptions/__init__.py | 6 +++-- .../agents_api/common/exceptions/agents.py | 25 ++++++++++++++++--- .../agents_api/common/exceptions/sessions.py | 24 +++++++----------- .../agents_api/common/exceptions/users.py | 12 ++++++--- .../agents_api/common/protocol/agents.py | 20 +++++++++------ agents-api/agents_api/common/utils/json.py | 22 +++++++++++----- .../agents_api/common/utils/messages.py | 2 +- agents-api/agents_api/exceptions.py | 6 +++++ .../agents_api/models/agent/create_agent.py | 8 +++--- .../models/agent/create_or_update_agent.py | 20 +++++++-------- .../agents_api/models/agent/delete_agent.py | 8 +++--- .../agents_api/models/agent/get_agent.py | 8 +++--- .../agents_api/models/agent/patch_agent.py | 10 ++++---- .../agents_api/models/agent/update_agent.py | 10 ++++---- .../agents_api/models/chat/gather_messages.py | 3 +-- .../agents_api/models/docs/create_doc.py | 8 +++--- .../agents_api/models/docs/embed_snippets.py | 6 ++--- .../models/docs/search_docs_by_embedding.py | 12 ++++----- .../models/docs/search_docs_by_text.py | 6 ++--- .../agents_api/models/entry/delete_entries.py | 2 +- .../models/session/delete_session.py | 6 ++--- .../models/session/list_sessions.py | 3 ++- .../models/session/patch_session.py | 9 ++++--- .../agents_api/models/tools/create_tools.py | 6 ++--- .../agents_api/models/tools/patch_tool.py | 10 ++++---- .../models/user/create_or_update_user.py | 14 +++++------ .../agents_api/models/user/delete_user.py | 8 +++--- .../agents_api/models/user/list_users.py | 10 ++++---- .../agents_api/models/user/patch_user.py | 8 +++--- .../agents_api/models/user/update_user.py | 3 ++- agents-api/agents_api/routers/jobs/routers.py | 4 +-- .../routers/tasks/create_or_update_task.py | 7 +++--- .../routers/tasks/get_execution_details.py | 5 ++-- .../tasks/list_execution_transitions.py | 5 ++-- .../routers/tasks/list_task_executions.py | 7 +++--- .../agents_api/routers/tasks/list_tasks.py | 7 +++--- .../routers/tasks/patch_execution.py | 7 +++--- .../routers/tasks/update_execution.py | 11 ++++---- agents-api/tests/fixtures.py | 2 +- agents-api/tests/test_activities.py | 9 ++----- agents-api/tests/test_docs_routes.py | 4 +-- agents-api/tests/test_execution_queries.py | 2 +- agents-api/tests/test_execution_workflow.py | 4 +-- agents-api/tests/test_task_queries.py | 2 +- agents-api/tests/test_task_routes.py | 4 +-- agents-api/tests/test_workflow_routes.py | 4 +-- agents-api/tests/utils.py | 1 + 49 files changed, 209 insertions(+), 175 deletions(-) diff --git a/agents-api/agents_api/activities/truncation.py b/agents-api/agents_api/activities/truncation.py index 4742ee6d4..afdb43da4 100644 --- a/agents-api/agents_api/activities/truncation.py +++ b/agents-api/agents_api/activities/truncation.py @@ -3,7 +3,7 @@ from beartype import beartype from temporalio import activity -from agents_api.autogen.openapi_model import Entry +from ..autogen.openapi_model import Entry # from agents_api.models.entry.entries_summarization import get_toplevel_entries_query diff --git a/agents-api/agents_api/clients/worker/worker.py b/agents-api/agents_api/clients/worker/worker.py index 1deb8d1c3..55b810c3e 100644 --- a/agents-api/agents_api/clients/worker/worker.py +++ b/agents-api/agents_api/clients/worker/worker.py @@ -1,6 +1,6 @@ import httpx -from agents_api.env import temporal_worker_url +from ...env import temporal_worker_url from .types import ( MemoryManagementTask, diff --git a/agents-api/agents_api/common/exceptions/__init__.py b/agents-api/agents_api/common/exceptions/__init__.py index a38a546a2..571691082 100644 --- a/agents-api/agents_api/common/exceptions/__init__.py +++ b/agents-api/agents_api/common/exceptions/__init__.py @@ -1,12 +1,14 @@ """ -This module defines a structured hierarchy of custom exceptions for the agents API, aimed at handling specific error scenarios encountered across various operations. These exceptions are designed to provide clear, actionable error messages and appropriate HTTP status codes, enhancing the API's robustness and usability. +This module defines a structured hierarchy of custom exceptions for the agents API, aimed at handling specific error scenarios encountered across various operations. +These exceptions are designed to provide clear, actionable error messages and appropriate HTTP status codes, enhancing the API's robustness and usability. Exceptions are organized into categories based on the domain of operation, including: - Agent-related operations (agents.py): Exceptions such as `AgentNotFoundError` and `AgentToolNotFoundError` cater to errors specific to agent management. - Session management (sessions.py): Defines exceptions like `SessionNotFoundError` for handling errors related to session operations. - User interactions (users.py): Includes exceptions such as `UserNotFoundError` for addressing issues encountered during user-related operations. -All custom exceptions extend from `BaseCommonException`, which encapsulates common attributes and behavior, including the error message and HTTP status code. This structured approach to exception handling facilitates precise and meaningful error feedback to API consumers, thereby improving the overall developer experience. +All custom exceptions extend from `BaseCommonException`, which encapsulates common attributes and behavior, including the error message and HTTP status code. +This structured approach to exception handling facilitates precise and meaningful error feedback to API consumers, thereby improving the overall developer experience. """ diff --git a/agents-api/agents_api/common/exceptions/agents.py b/agents-api/agents_api/common/exceptions/agents.py index c412eba35..e58f25104 100644 --- a/agents-api/agents_api/common/exceptions/agents.py +++ b/agents-api/agents_api/common/exceptions/agents.py @@ -12,7 +12,12 @@ class BaseAgentException(BaseCommonException): class AgentNotFoundError(BaseAgentException): - """Exception raised when a requested agent cannot be found.""" + """ + Exception raised when a requested agent cannot be found. + Attributes: + developer_id (UUID | str): The ID of the developer attempting the operation. + agent_id (UUID | str): The ID of the agent that was not found. + """ def __init__(self, developer_id: UUID | str, agent_id: UUID | str): # Initialize the exception with a message indicating the missing agent and developer ID. @@ -23,7 +28,12 @@ def __init__(self, developer_id: UUID | str, agent_id: UUID | str): class AgentToolNotFoundError(BaseAgentException): - """Exception raised when a requested tool associated with an agent cannot be found.""" + """ + Exception raised when a requested tool associated with an agent cannot be found. + Attributes: + agent_id (UUID | str): The ID of the agent that was not found. + tool_id (UUID | str): The ID of the tool that was not found. + """ def __init__(self, agent_id: UUID | str, tool_id: UUID | str): # Initialize the exception with a message indicating the missing tool and agent ID. @@ -33,7 +43,12 @@ def __init__(self, agent_id: UUID | str, tool_id: UUID | str): class AgentDocNotFoundError(BaseAgentException): - """Exception raised when a requested document associated with an agent cannot be found.""" + """ + Exception raised when a requested document associated with an agent cannot be found. + Attributes: + agent_id (UUID | str): The ID of the agent that was not found. + doc_id (UUID | str): The ID of the document that was not found. + """ def __init__(self, agent_id: UUID | str, doc_id: UUID | str): # Initialize the exception with a message indicating the missing document and agent ID. @@ -43,6 +58,8 @@ def __init__(self, agent_id: UUID | str, doc_id: UUID | str): class AgentModelNotValid(BaseAgentException): + """Exception raised when requested model is not recognized.""" + def __init__(self, model: str, all_models: list[str]): super().__init__( f"Unknown model: {model}. Please provide a valid model name." @@ -52,6 +69,8 @@ def __init__(self, model: str, all_models: list[str]): class MissingAgentModelAPIKeyError(BaseAgentException): + """Exception raised when API key for requested model is missing.""" + def __init__(self, model: str): super().__init__( f"API key missing for model: {model}. Please provide a valid API key in the configuration", diff --git a/agents-api/agents_api/common/exceptions/sessions.py b/agents-api/agents_api/common/exceptions/sessions.py index d6c04aff5..14d6ff4e7 100644 --- a/agents-api/agents_api/common/exceptions/sessions.py +++ b/agents-api/agents_api/common/exceptions/sessions.py @@ -8,29 +8,23 @@ from . import BaseCommonException -""" -Base exception class for session-related errors. - -This class serves as a base for all session-related exceptions, allowing for a structured exception handling approach specific to session operations. -""" - - class BaseSessionException(BaseCommonException): - pass - + """ + Base exception class for session-related errors. -""" -Exception raised when a session cannot be found. + This class serves as a base for all session-related exceptions, allowing for a structured exception handling approach specific to session operations. + """ -This exception is used to indicate that a specific session, identified by its session ID, does not exist or is not accessible for the given developer. -""" + pass class SessionNotFoundError(BaseSessionException): """ - Initializes a new instance of the SessionNotFoundError. + Exception raised when a session cannot be found. + + This exception is used to indicate that a specific session, identified by its session ID, does not exist or is not accessible for the given developer. - Args: + Attributes: developer_id (UUID | str): The unique identifier of the developer attempting to access the session. session_id (UUID | str): The unique identifier of the session that was not found. """ diff --git a/agents-api/agents_api/common/exceptions/users.py b/agents-api/agents_api/common/exceptions/users.py index 2f7f58ed6..cf4e995ad 100644 --- a/agents-api/agents_api/common/exceptions/users.py +++ b/agents-api/agents_api/common/exceptions/users.py @@ -6,13 +6,18 @@ class BaseUserException(BaseCommonException): - """Base exception class for user-related errors. This class serves as a parent for all user-related exceptions to facilitate catching errors specific to user operations.""" + """ + Base exception class for user-related errors. + + This class serves as a parent for all user-related exceptions to facilitate catching errors specific to user operations. + """ pass class UserNotFoundError(BaseUserException): - """Exception raised when a requested user cannot be found. + """ + Exception raised when a requested user cannot be found. Attributes: developer_id (UUID | str): The ID of the developer attempting the operation. user_id (UUID | str): The ID of the user that was not found. @@ -27,7 +32,8 @@ def __init__(self, developer_id: UUID | str, user_id: UUID | str): class UserDocNotFoundError(BaseUserException): - """Exception raised when a specific document related to a user cannot be found. + """ + Exception raised when a specific document related to a user cannot be found. Attributes: user_id (UUID | str): The ID of the user associated with the document. doc_id (UUID | str): The ID of the document that was not found. diff --git a/agents-api/agents_api/common/protocol/agents.py b/agents-api/agents_api/common/protocol/agents.py index 222f91f01..fb8b4f063 100644 --- a/agents-api/agents_api/common/protocol/agents.py +++ b/agents-api/agents_api/common/protocol/agents.py @@ -4,17 +4,23 @@ class AgentDefaultSettings(BaseModel): """Defines default settings for an agent. These settings control various aspects of the agent's behavior during operation.""" - """Temperature setting influencing the randomness of the agent's responses. Higher values lead to more random responses.""" temperature: float = 0.0 - """Top-p sampling setting controlling the nucleus of the probability distribution to sample from.""" + """Temperature setting influencing the randomness of the agent's responses. Higher values lead to more random responses.""" + top_p: float = 1.0 - """Penalty applied to discourage repetition in the agent's responses.""" + """Top-p sampling setting controlling the nucleus of the probability distribution to sample from.""" + repetition_penalty: float = 1.0 - """Penalty for longer responses, encouraging more concise outputs.""" + """Penalty applied to discourage repetition in the agent's responses.""" + length_penalty: float = 1.0 - """Penalty applied based on the presence of certain words, influencing content generation.""" + """Penalty for longer responses, encouraging more concise outputs.""" + presence_penalty: float = 0.0 - """Penalty that decreases the likelihood of frequently used words in the agent's responses.""" + """Penalty applied based on the presence of certain words, influencing content generation.""" + frequency_penalty: float = 0.0 - """Minimum probability threshold for including a word in the agent's response.""" + """Penalty that decreases the likelihood of frequently used words in the agent's responses.""" + min_p: float = 0.01 + """Minimum probability threshold for including a word in the agent's response.""" diff --git a/agents-api/agents_api/common/utils/json.py b/agents-api/agents_api/common/utils/json.py index 3157af9c8..ec53ecb27 100644 --- a/agents-api/agents_api/common/utils/json.py +++ b/agents-api/agents_api/common/utils/json.py @@ -11,28 +11,35 @@ class CustomJSONEncoder(json.JSONEncoder): """A custom JSON encoder subclass that handles None values and UUIDs for JSON serialization. It allows specifying a default value for None objects during initialization.""" def __init__(self, *args, **kwargs) -> None: - """Initializes the custom JSON encoder. + """ + Initializes the custom JSON encoder. Parameters: *args: Variable length argument list. **kwargs: Arbitrary keyword arguments. The 'default_empty_value' keyword argument specifies the default value to use for None objects during serialization. """ + self._default_empty_value = kwargs.pop("default_empty_value") super().__init__(*args, **kwargs) def encode(self, o) -> str: - """Encodes the given object into a JSON formatted string. + """ + Encodes the given object into a JSON formatted string. Parameters: o: The object to encode. - Returns: A JSON formatted string representing 'o'.""" + Returns: A JSON formatted string representing 'o'. + """ + # Use the overridden default method for serialization before encoding return super().encode(self.default(o)) def default(self, obj) -> Any: - """Provides a default serialization for objects that the standard JSON encoder cannot serialize. + """ + Provides a default serialization for objects that the standard JSON encoder cannot serialize. Parameters: obj: The object to serialize. Returns: A serializable object or raises a TypeError if the object is not serializable. """ + if obj is None: return self._default_empty_value @@ -46,12 +53,15 @@ def default(self, obj) -> Any: def dumps(obj: Any, default_empty_value="", cls=None) -> str: - """Serializes an object to a JSON formatted string using the custom JSON encoder. + """ + Serializes an object to a JSON formatted string using the custom JSON encoder. Parameters: obj: The object to serialize. default_empty_value: The default value to use for None objects. cls: The custom encoder class to use, defaults to CustomJSONEncoder. - Returns: A JSON formatted string.""" + Returns: A JSON formatted string. + """ + return json.dumps( obj, cls=cls or CustomJSONEncoder, default_empty_value=default_empty_value ) diff --git a/agents-api/agents_api/common/utils/messages.py b/agents-api/agents_api/common/utils/messages.py index fd971296c..c94808324 100644 --- a/agents-api/agents_api/common/utils/messages.py +++ b/agents-api/agents_api/common/utils/messages.py @@ -1,7 +1,7 @@ import json from typing import cast -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( ChatMLImageContentPart, ChatMLTextContentPart, ) diff --git a/agents-api/agents_api/exceptions.py b/agents-api/agents_api/exceptions.py index fbb8f00f8..4fbf8a2b9 100644 --- a/agents-api/agents_api/exceptions.py +++ b/agents-api/agents_api/exceptions.py @@ -3,11 +3,15 @@ class AgentsBaseException(Exception): class ModelNotSupportedError(AgentsBaseException): + """Exception raised when model is not supported.""" + def __init__(self, model_name) -> None: super().__init__(f"model {model_name} is not supported") class PromptTooBigError(AgentsBaseException): + """Exception raised when prompt is too big.""" + def __init__(self, token_count, max_tokens) -> None: super().__init__( f"prompt is too big, {token_count} tokens provided, exceeds maximum of {max_tokens}" @@ -15,5 +19,7 @@ def __init__(self, token_count, max_tokens) -> None: class UnknownTokenizerError(AgentsBaseException): + """Exception raised when tokenizer is unknown.""" + def __init__(self) -> None: super().__init__("unknown tokenizer") diff --git a/agents-api/agents_api/models/agent/create_agent.py b/agents-api/agents_api/models/agent/create_agent.py index a52a7b771..98daab540 100644 --- a/agents-api/agents_api/models/agent/create_agent.py +++ b/agents-api/agents_api/models/agent/create_agent.py @@ -68,12 +68,12 @@ def create_agent( Constructs and executes a datalog query to create a new agent in the database. Parameters: - - agent_id (UUID | None): The unique identifier for the agent. - - developer_id (UUID): The unique identifier for the developer creating the agent. - - data (CreateAgentRequest): The data for the new agent. + agent_id (UUID | None): The unique identifier for the agent. + developer_id (UUID): The unique identifier for the developer creating the agent. + data (CreateAgentRequest): The data for the new agent. Returns: - - Agent: The newly created agent record. + Agent: The newly created agent record. """ agent_id = agent_id or uuid4() diff --git a/agents-api/agents_api/models/agent/create_or_update_agent.py b/agents-api/agents_api/models/agent/create_or_update_agent.py index 835245787..3902c1bb5 100644 --- a/agents-api/agents_api/models/agent/create_or_update_agent.py +++ b/agents-api/agents_api/models/agent/create_or_update_agent.py @@ -59,18 +59,18 @@ def create_or_update_agent( Constructs and executes a datalog query to create a new agent in the database. Parameters: - - agent_id (UUID): The unique identifier for the agent. - - developer_id (UUID): The unique identifier for the developer creating the agent. - - name (str): The name of the agent. - - about (str): A description of the agent. - - instructions (list[str], optional): A list of instructions for using the agent. Defaults to an empty list. - - model (str, optional): The model identifier for the agent. Defaults to "gpt-4o". - - metadata (dict, optional): A dictionary of metadata for the agent. Defaults to an empty dict. - - default_settings (dict, optional): A dictionary of default settings for the agent. Defaults to an empty dict. - - client (CozoClient, optional): The CozoDB client instance to use for the query. Defaults to a preconfigured client instance. + agent_id (UUID): The unique identifier for the agent. + developer_id (UUID): The unique identifier for the developer creating the agent. + name (str): The name of the agent. + about (str): A description of the agent. + instructions (list[str], optional): A list of instructions for using the agent. Defaults to an empty list. + model (str, optional): The model identifier for the agent. Defaults to "gpt-4o". + metadata (dict, optional): A dictionary of metadata for the agent. Defaults to an empty dict. + default_settings (dict, optional): A dictionary of default settings for the agent. Defaults to an empty dict. + client (CozoClient, optional): The CozoDB client instance to use for the query. Defaults to a preconfigured client instance. Returns: - Agent: The newly created agent record. + Agent: The newly created agent record. """ # Extract the agent data from the payload diff --git a/agents-api/agents_api/models/agent/delete_agent.py b/agents-api/agents_api/models/agent/delete_agent.py index c8bdc2106..60de66292 100644 --- a/agents-api/agents_api/models/agent/delete_agent.py +++ b/agents-api/agents_api/models/agent/delete_agent.py @@ -67,12 +67,12 @@ def delete_agent(*, developer_id: UUID, agent_id: UUID) -> tuple[list[str], dict Constructs and returns a datalog query for deleting an agent and its default settings from the database. Parameters: - - developer_id (UUID): The UUID of the developer owning the agent. - - agent_id (UUID): The UUID of the agent to be deleted. - - client (CozoClient, optional): An instance of the CozoClient to execute the query. + developer_id (UUID): The UUID of the developer owning the agent. + agent_id (UUID): The UUID of the agent to be deleted. + client (CozoClient, optional): An instance of the CozoClient to execute the query. Returns: - - ResourceDeletedResponse: The response indicating the deletion of the agent. + ResourceDeletedResponse: The response indicating the deletion of the agent. """ queries = [ diff --git a/agents-api/agents_api/models/agent/get_agent.py b/agents-api/agents_api/models/agent/get_agent.py index f8127751a..bdae85fcb 100644 --- a/agents-api/agents_api/models/agent/get_agent.py +++ b/agents-api/agents_api/models/agent/get_agent.py @@ -46,12 +46,12 @@ def get_agent(*, developer_id: UUID, agent_id: UUID) -> tuple[list[str], dict]: This function constructs and executes a datalog query to retrieve information about a specific agent, including its default settings, based on the provided agent_id and developer_id. Parameters: - - developer_id (UUID): The unique identifier for the developer. - - agent_id (UUID): The unique identifier for the agent. - - client (CozoClient, optional): The database client used to execute the query. + developer_id (UUID): The unique identifier for the developer. + agent_id (UUID): The unique identifier for the agent. + client (CozoClient, optional): The database client used to execute the query. Returns: - - Agent + Agent """ # Constructing a datalog query to retrieve agent details and default settings. # The query uses input parameters for agent_id and developer_id to filter the results. diff --git a/agents-api/agents_api/models/agent/patch_agent.py b/agents-api/agents_api/models/agent/patch_agent.py index 72fdc7811..364d1a974 100644 --- a/agents-api/agents_api/models/agent/patch_agent.py +++ b/agents-api/agents_api/models/agent/patch_agent.py @@ -46,13 +46,13 @@ def patch_agent( """Patches agent data based on provided updates. Parameters: - agent_id (UUID): The unique identifier for the agent. - developer_id (UUID): The unique identifier for the developer. - default_settings (dict, optional): Default settings to apply to the agent. - **update_data: Arbitrary keyword arguments representing data to update. + agent_id (UUID): The unique identifier for the agent. + developer_id (UUID): The unique identifier for the developer. + default_settings (dict, optional): Default settings to apply to the agent. + **update_data: Arbitrary keyword arguments representing data to update. Returns: - ResourceUpdatedResponse: The updated agent data. + ResourceUpdatedResponse: The updated agent data. """ update_data = data.model_dump(exclude_unset=True) diff --git a/agents-api/agents_api/models/agent/update_agent.py b/agents-api/agents_api/models/agent/update_agent.py index be7e9ea21..992bb9796 100644 --- a/agents-api/agents_api/models/agent/update_agent.py +++ b/agents-api/agents_api/models/agent/update_agent.py @@ -46,13 +46,13 @@ def update_agent( Constructs and executes a datalog query to update an agent and its default settings in the 'cozodb' database. Parameters: - - agent_id (UUID): The unique identifier of the agent to be updated. - - developer_id (UUID): The unique identifier of the developer associated with the agent. - - data (UpdateAgentRequest): The request payload containing the updated agent data. - - client (CozoClient, optional): The database client used to execute the query. Defaults to a pre-configured client instance. + agent_id (UUID): The unique identifier of the agent to be updated. + developer_id (UUID): The unique identifier of the developer associated with the agent. + data (UpdateAgentRequest): The request payload containing the updated agent data. + client (CozoClient, optional): The database client used to execute the query. Defaults to a pre-configured client instance. Returns: - ResourceUpdatedResponse: The updated agent data. + ResourceUpdatedResponse: The updated agent data. """ default_settings = ( data.default_settings.model_dump(exclude_none=True) diff --git a/agents-api/agents_api/models/chat/gather_messages.py b/agents-api/agents_api/models/chat/gather_messages.py index c1683653f..b6bfdc217 100644 --- a/agents-api/agents_api/models/chat/gather_messages.py +++ b/agents-api/agents_api/models/chat/gather_messages.py @@ -6,8 +6,7 @@ from pycozo.client import QueryException from pydantic import ValidationError -from agents_api.autogen.Chat import ChatInput - +from ...autogen.Chat import ChatInput from ...autogen.openapi_model import DocReference, History from ...clients import litellm from ...common.protocol.developers import Developer diff --git a/agents-api/agents_api/models/docs/create_doc.py b/agents-api/agents_api/models/docs/create_doc.py index ee26df484..1c667bd51 100644 --- a/agents-api/agents_api/models/docs/create_doc.py +++ b/agents-api/agents_api/models/docs/create_doc.py @@ -50,10 +50,10 @@ def create_doc( Constructs and executes a datalog query to create a new document and its associated snippets in the 'cozodb' database. Parameters: - - owner_type (Literal["user", "agent"]): The type of the owner of the document. - - owner_id (UUID): The UUID of the document owner. - - id (UUID): The UUID of the document to be created. - - data (CreateDocRequest): The content of the document. + owner_type (Literal["user", "agent"]): The type of the owner of the document. + owner_id (UUID): The UUID of the document owner. + id (UUID): The UUID of the document to be created. + data (CreateDocRequest): The content of the document. """ doc_id = str(doc_id or uuid4()) diff --git a/agents-api/agents_api/models/docs/embed_snippets.py b/agents-api/agents_api/models/docs/embed_snippets.py index 993e76396..8d8ae1e62 100644 --- a/agents-api/agents_api/models/docs/embed_snippets.py +++ b/agents-api/agents_api/models/docs/embed_snippets.py @@ -49,9 +49,9 @@ def embed_snippets( """Embeds document snippets in the cozodb database. Parameters: - doc_id (UUID): The unique identifier for the document. - snippet_indices (list[int]): Indices of the snippets in the document. - embeddings (list[list[float]]): Embedding vectors for the snippets. + doc_id (UUID): The unique identifier for the document. + snippet_indices (list[int]): Indices of the snippets in the document. + embeddings (list[list[float]]): Embedding vectors for the snippets. """ doc_id = str(doc_id) diff --git a/agents-api/agents_api/models/docs/search_docs_by_embedding.py b/agents-api/agents_api/models/docs/search_docs_by_embedding.py index d6bed97fc..83418aa21 100644 --- a/agents-api/agents_api/models/docs/search_docs_by_embedding.py +++ b/agents-api/agents_api/models/docs/search_docs_by_embedding.py @@ -56,12 +56,12 @@ def search_docs_by_embedding( Searches for document snippets in CozoDB by embedding query. Parameters: - - owner_type (Literal["user", "agent"]): The type of the owner of the documents. - - owner_id (UUID): The unique identifier of the owner. - - query_embedding (list[float]): The embedding vector of the query. - - k (int, optional): The number of nearest neighbors to retrieve. Defaults to 3. - - confidence (float, optional): The confidence threshold for filtering results. Defaults to 0.8. - - mmr_lambda (float, optional): The lambda parameter for MMR. Defaults to 0.25. + owner_type (Literal["user", "agent"]): The type of the owner of the documents. + owner_id (UUID): The unique identifier of the owner. + query_embedding (list[float]): The embedding vector of the query. + k (int, optional): The number of nearest neighbors to retrieve. Defaults to 3. + confidence (float, optional): The confidence threshold for filtering results. Defaults to 0.8. + mmr_lambda (float, optional): The lambda parameter for MMR. Defaults to 0.25. """ assert len(query_embedding) == embedding_size diff --git a/agents-api/agents_api/models/docs/search_docs_by_text.py b/agents-api/agents_api/models/docs/search_docs_by_text.py index eeae8362c..bb700a494 100644 --- a/agents-api/agents_api/models/docs/search_docs_by_text.py +++ b/agents-api/agents_api/models/docs/search_docs_by_text.py @@ -53,9 +53,9 @@ def search_docs_by_text( Searches for document snippets in CozoDB by embedding query. Parameters: - - owners (list[tuple[Literal["user", "agent"], UUID]]): The type of the owner of the documents. - - query (str): The query string. - - k (int, optional): The number of nearest neighbors to retrieve. Defaults to 3. + owners (list[tuple[Literal["user", "agent"], UUID]]): The type of the owner of the documents. + query (str): The query string. + k (int, optional): The number of nearest neighbors to retrieve. Defaults to 3. """ owners: list[list[str]] = [ diff --git a/agents-api/agents_api/models/entry/delete_entries.py b/agents-api/agents_api/models/entry/delete_entries.py index 48c37cd25..c98b6c7d2 100644 --- a/agents-api/agents_api/models/entry/delete_entries.py +++ b/agents-api/agents_api/models/entry/delete_entries.py @@ -49,7 +49,7 @@ def delete_entries_for_session( Constructs and returns a datalog query for deleting entries associated with a given session ID from the 'cozodb' database. Parameters: - - session_id (UUID): The unique identifier of the session whose entries are to be deleted. + session_id (UUID): The unique identifier of the session whose entries are to be deleted. """ delete_query = """ diff --git a/agents-api/agents_api/models/session/delete_session.py b/agents-api/agents_api/models/session/delete_session.py index af9e331c7..81f8e1f7c 100644 --- a/agents-api/agents_api/models/session/delete_session.py +++ b/agents-api/agents_api/models/session/delete_session.py @@ -51,11 +51,11 @@ def delete_session( Deletes a session and its related data from the 'cozodb' database. Parameters: - - developer_id (UUID): The unique identifier for the developer. - - session_id (UUID): The unique identifier for the session to be deleted. + developer_id (UUID): The unique identifier for the developer. + session_id (UUID): The unique identifier for the session to be deleted. Returns: - - ResourceDeletedResponse: The response indicating the deletion of the session. + ResourceDeletedResponse: The response indicating the deletion of the session. """ session_id = str(session_id) developer_id = str(developer_id) diff --git a/agents-api/agents_api/models/session/list_sessions.py b/agents-api/agents_api/models/session/list_sessions.py index 14f4cad0d..b7d5c0049 100644 --- a/agents-api/agents_api/models/session/list_sessions.py +++ b/agents-api/agents_api/models/session/list_sessions.py @@ -41,7 +41,8 @@ def list_sessions( direction: Literal["asc", "desc"] = "desc", metadata_filter: dict[str, Any] = {}, ) -> tuple[list[str], dict]: - """Lists sessions from the 'cozodb' database based on the provided filters. + """ + Lists sessions from the 'cozodb' database based on the provided filters. Parameters: developer_id (UUID): The developer's ID to filter sessions by. diff --git a/agents-api/agents_api/models/session/patch_session.py b/agents-api/agents_api/models/session/patch_session.py index a9f3121b9..4a119a684 100644 --- a/agents-api/agents_api/models/session/patch_session.py +++ b/agents-api/agents_api/models/session/patch_session.py @@ -60,12 +60,13 @@ def patch_session( developer_id: UUID, data: PatchSessionRequest, ) -> tuple[list[str], dict]: - """Patch session data in the 'cozodb' database. + """ + Patch session data in the 'cozodb' database. Parameters: - - session_id (UUID): The unique identifier for the session to be updated. - - developer_id (UUID): The unique identifier for the developer making the update. - - data (PatchSessionRequest): The request payload containing the updates to apply. + session_id (UUID): The unique identifier for the session to be updated. + developer_id (UUID): The unique identifier for the developer making the update. + data (PatchSessionRequest): The request payload containing the updates to apply. """ update_data = data.model_dump(exclude_unset=True) diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index 87ea3a9cf..fe7e28228 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -51,11 +51,11 @@ def create_tools( Constructs a datalog query for inserting tool records into the 'agent_functions' relation in the CozoDB. Parameters: - - agent_id (UUID): The unique identifier for the agent. - - data (list[CreateToolRequest]): A list of function definitions to be inserted. + agent_id (UUID): The unique identifier for the agent. + data (list[CreateToolRequest]): A list of function definitions to be inserted. Returns: - list[Tool] + list[Tool] """ tools_data = [ diff --git a/agents-api/agents_api/models/tools/patch_tool.py b/agents-api/agents_api/models/tools/patch_tool.py index 5bbfe1c91..0d8304d7d 100644 --- a/agents-api/agents_api/models/tools/patch_tool.py +++ b/agents-api/agents_api/models/tools/patch_tool.py @@ -40,16 +40,16 @@ def patch_tool( *, developer_id: UUID, agent_id: UUID, tool_id: UUID, data: PatchToolRequest ) -> tuple[list[str], dict]: """ - # Execute the datalog query and return the results as a DataFrame + Execute the datalog query and return the results as a DataFrame Updates the tool information for a given agent and tool ID in the 'cozodb' database. Parameters: - - agent_id (UUID): The unique identifier of the agent. - - tool_id (UUID): The unique identifier of the tool to be updated. - - data (PatchToolRequest): The request payload containing the updated tool information. + agent_id (UUID): The unique identifier of the agent. + tool_id (UUID): The unique identifier of the tool to be updated. + data (PatchToolRequest): The request payload containing the updated tool information. Returns: - - ResourceUpdatedResponse: The updated tool data. + ResourceUpdatedResponse: The updated tool data. """ agent_id = str(agent_id) diff --git a/agents-api/agents_api/models/user/create_or_update_user.py b/agents-api/agents_api/models/user/create_or_update_user.py index 9e9045e74..97db913c5 100644 --- a/agents-api/agents_api/models/user/create_or_update_user.py +++ b/agents-api/agents_api/models/user/create_or_update_user.py @@ -44,15 +44,15 @@ def create_or_update_user( Constructs and executes a datalog query to create a new user in the database. Parameters: - - user_id (UUID): The unique identifier for the user. - - developer_id (UUID): The unique identifier for the developer creating the user. - - name (str): The name of the user. - - about (str): A description of the user. - - metadata (dict, optional): A dictionary of metadata for the user. Defaults to an empty dict. - - client (CozoClient, optional): The CozoDB client instance to use for the query. Defaults to a preconfigured client instance. + user_id (UUID): The unique identifier for the user. + developer_id (UUID): The unique identifier for the developer creating the user. + name (str): The name of the user. + about (str): A description of the user. + metadata (dict, optional): A dictionary of metadata for the user. Defaults to an empty dict. + client (CozoClient, optional): The CozoDB client instance to use for the query. Defaults to a preconfigured client instance. Returns: - User: The newly created user record. + User: The newly created user record. """ # Extract the user data from the payload diff --git a/agents-api/agents_api/models/user/delete_user.py b/agents-api/agents_api/models/user/delete_user.py index b5fcb8424..0532f5cfa 100644 --- a/agents-api/agents_api/models/user/delete_user.py +++ b/agents-api/agents_api/models/user/delete_user.py @@ -49,12 +49,12 @@ def delete_user(*, developer_id: UUID, user_id: UUID) -> tuple[list[str], dict]: Constructs and returns a datalog query for deleting an user and its default settings from the database. Parameters: - - developer_id (UUID): The UUID of the developer owning the user. - - user_id (UUID): The UUID of the user to be deleted. - - client (CozoClient, optional): An instance of the CozoClient to execute the query. + developer_id (UUID): The UUID of the developer owning the user. + user_id (UUID): The UUID of the user to be deleted. + client (CozoClient, optional): An instance of the CozoClient to execute the query. Returns: - - ResourceDeletedResponse: The response indicating the deletion of the user. + ResourceDeletedResponse: The response indicating the deletion of the user. """ queries = [ diff --git a/agents-api/agents_api/models/user/list_users.py b/agents-api/agents_api/models/user/list_users.py index 57dc9b8c8..2a810b8e0 100644 --- a/agents-api/agents_api/models/user/list_users.py +++ b/agents-api/agents_api/models/user/list_users.py @@ -43,13 +43,13 @@ def list_users( Queries the 'cozodb' database to list users associated with a specific developer. Parameters: - - developer_id (UUID): The unique identifier of the developer. - - limit (int): The maximum number of users to return. Defaults to 100. - - offset (int): The number of users to skip before starting to collect the result set. Defaults to 0. - - metadata_filter (dict[str, Any]): A dictionary representing filters to apply on user metadata. + developer_id (UUID): The unique identifier of the developer. + limit (int): The maximum number of users to return. Defaults to 100. + offset (int): The number of users to skip before starting to collect the result set. Defaults to 0. + metadata_filter (dict[str, Any]): A dictionary representing filters to apply on user metadata. Returns: - - pd.DataFrame: A DataFrame containing the queried user data. + pd.DataFrame: A DataFrame containing the queried user data. """ # Construct a filter string for the metadata based on the provided dictionary. metadata_filter_str = ", ".join( diff --git a/agents-api/agents_api/models/user/patch_user.py b/agents-api/agents_api/models/user/patch_user.py index faf38298c..4498c6ded 100644 --- a/agents-api/agents_api/models/user/patch_user.py +++ b/agents-api/agents_api/models/user/patch_user.py @@ -49,12 +49,12 @@ def patch_user( Generates a datalog query for updating a user's information. Parameters: - - developer_id (UUID): The UUID of the developer. - - user_id (UUID): The UUID of the user to be updated. - - **update_data: Arbitrary keyword arguments representing the data to be updated. + developer_id (UUID): The UUID of the developer. + user_id (UUID): The UUID of the user to be updated. + **update_data: Arbitrary keyword arguments representing the data to be updated. Returns: - - tuple[str, dict]: A pandas DataFrame containing the results of the query execution. + tuple[str, dict]: A pandas DataFrame containing the results of the query execution. """ update_data = data.model_dump(exclude_unset=True) diff --git a/agents-api/agents_api/models/user/update_user.py b/agents-api/agents_api/models/user/update_user.py index 9a13d9369..fd8e7e2c8 100644 --- a/agents-api/agents_api/models/user/update_user.py +++ b/agents-api/agents_api/models/user/update_user.py @@ -39,7 +39,8 @@ def update_user( *, developer_id: UUID, user_id: UUID, data: UpdateUserRequest ) -> tuple[list[str], dict]: - """Updates user information in the 'cozodb' database. + """ + Updates user information in the 'cozodb' database. Parameters: developer_id (UUID): The developer's unique identifier. diff --git a/agents-api/agents_api/routers/jobs/routers.py b/agents-api/agents_api/routers/jobs/routers.py index 8bff6c7cc..dff4bed7b 100644 --- a/agents-api/agents_api/routers/jobs/routers.py +++ b/agents-api/agents_api/routers/jobs/routers.py @@ -4,8 +4,8 @@ from fastapi import APIRouter from temporalio.client import WorkflowExecutionStatus -from agents_api.autogen.openapi_model import JobStatus -from agents_api.clients.temporal import get_client +from ...autogen.openapi_model import JobStatus +from ...clients.temporal import get_client router: APIRouter = APIRouter() diff --git a/agents-api/agents_api/routers/tasks/create_or_update_task.py b/agents-api/agents_api/routers/tasks/create_or_update_task.py index e5245670a..50dbf19d9 100644 --- a/agents-api/agents_api/routers/tasks/create_or_update_task.py +++ b/agents-api/agents_api/routers/tasks/create_or_update_task.py @@ -6,15 +6,14 @@ from jsonschema.exceptions import SchemaError, ValidationError from starlette.status import HTTP_201_CREATED -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( CreateOrUpdateTaskRequest, ResourceUpdatedResponse, ) -from agents_api.dependencies.developer_id import get_developer_id -from agents_api.models.task.create_or_update_task import ( +from ...dependencies.developer_id import get_developer_id +from ...models.task.create_or_update_task import ( create_or_update_task as create_or_update_task_query, ) - from .router import router diff --git a/agents-api/agents_api/routers/tasks/get_execution_details.py b/agents-api/agents_api/routers/tasks/get_execution_details.py index 8da7b98c8..95bccbc07 100644 --- a/agents-api/agents_api/routers/tasks/get_execution_details.py +++ b/agents-api/agents_api/routers/tasks/get_execution_details.py @@ -1,12 +1,11 @@ from uuid import UUID -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( Execution, ) -from agents_api.models.execution.get_execution import ( +from ...models.execution.get_execution import ( get_execution as get_execution_query, ) - from .router import router diff --git a/agents-api/agents_api/routers/tasks/list_execution_transitions.py b/agents-api/agents_api/routers/tasks/list_execution_transitions.py index fd7be992a..9ce169509 100644 --- a/agents-api/agents_api/routers/tasks/list_execution_transitions.py +++ b/agents-api/agents_api/routers/tasks/list_execution_transitions.py @@ -1,14 +1,13 @@ from typing import Literal from uuid import UUID -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( ListResponse, Transition, ) -from agents_api.models.execution.list_execution_transitions import ( +from ...models.execution.list_execution_transitions import ( list_execution_transitions as list_execution_transitions_query, ) - from .router import router diff --git a/agents-api/agents_api/routers/tasks/list_task_executions.py b/agents-api/agents_api/routers/tasks/list_task_executions.py index f2961e54a..72cbd9b40 100644 --- a/agents-api/agents_api/routers/tasks/list_task_executions.py +++ b/agents-api/agents_api/routers/tasks/list_task_executions.py @@ -3,15 +3,14 @@ from fastapi import Depends -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( Execution, ListResponse, ) -from agents_api.dependencies.developer_id import get_developer_id -from agents_api.models.execution.list_executions import ( +from ...dependencies.developer_id import get_developer_id +from ...models.execution.list_executions import ( list_executions as list_task_executions_query, ) - from .router import router diff --git a/agents-api/agents_api/routers/tasks/list_tasks.py b/agents-api/agents_api/routers/tasks/list_tasks.py index 43a7e9158..a53983006 100644 --- a/agents-api/agents_api/routers/tasks/list_tasks.py +++ b/agents-api/agents_api/routers/tasks/list_tasks.py @@ -3,13 +3,12 @@ from fastapi import Depends -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( ListResponse, Task, ) -from agents_api.dependencies.developer_id import get_developer_id -from agents_api.models.task.list_tasks import list_tasks as list_tasks_query - +from ...dependencies.developer_id import get_developer_id +from ...models.task.list_tasks import list_tasks as list_tasks_query from .router import router diff --git a/agents-api/agents_api/routers/tasks/patch_execution.py b/agents-api/agents_api/routers/tasks/patch_execution.py index 0eb159c83..3cc45ee37 100644 --- a/agents-api/agents_api/routers/tasks/patch_execution.py +++ b/agents-api/agents_api/routers/tasks/patch_execution.py @@ -3,15 +3,14 @@ from fastapi import Depends -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( ResourceUpdatedResponse, UpdateExecutionRequest, ) -from agents_api.dependencies.developer_id import get_developer_id -from agents_api.models.execution.update_execution import ( +from ...dependencies.developer_id import get_developer_id +from ...models.execution.update_execution import ( update_execution as update_execution_query, ) - from .router import router diff --git a/agents-api/agents_api/routers/tasks/update_execution.py b/agents-api/agents_api/routers/tasks/update_execution.py index 968b6bdfb..d887c455d 100644 --- a/agents-api/agents_api/routers/tasks/update_execution.py +++ b/agents-api/agents_api/routers/tasks/update_execution.py @@ -4,19 +4,18 @@ from fastapi import Depends, HTTPException -from agents_api.autogen.openapi_model import ( +from ...autogen.openapi_model import ( ResumeExecutionRequest, StopExecutionRequest, ) -from agents_api.clients.temporal import get_client -from agents_api.dependencies.developer_id import get_developer_id -from agents_api.models.execution.get_paused_execution_token import ( +from ...clients.temporal import get_client +from ...dependencies.developer_id import get_developer_id +from ...models.execution.get_paused_execution_token import ( get_paused_execution_token, ) -from agents_api.models.execution.get_temporal_workflow_data import ( +from ...models.execution.get_temporal_workflow_data import ( get_temporal_workflow_data, ) - from .router import router diff --git a/agents-api/tests/fixtures.py b/agents-api/tests/fixtures.py index d5b032311..b732e750c 100644 --- a/agents-api/tests/fixtures.py +++ b/agents-api/tests/fixtures.py @@ -37,7 +37,7 @@ from agents_api.models.user.delete_user import delete_user from agents_api.web import app -from .utils import patch_embed_acompletion as patch_embed_acompletion_ctx +from tests.utils import patch_embed_acompletion as patch_embed_acompletion_ctx EMBEDDING_SIZE: int = 1024 diff --git a/agents-api/tests/test_activities.py b/agents-api/tests/test_activities.py index 98dfc97b5..a2f15d179 100644 --- a/agents-api/tests/test_activities.py +++ b/agents-api/tests/test_activities.py @@ -7,13 +7,8 @@ from agents_api.clients import temporal from agents_api.env import temporal_task_queue from agents_api.workflows.demo import DemoWorkflow - -from .fixtures import ( - cozo_client, - test_developer_id, - test_doc, -) -from .utils import patch_testing_temporal +from tests.fixtures import cozo_client, test_developer_id, test_doc +from tests.utils import patch_testing_temporal @test("activity: call direct embed_docs") diff --git a/agents-api/tests/test_docs_routes.py b/agents-api/tests/test_docs_routes.py index d4b677d05..d61bfbcb7 100644 --- a/agents-api/tests/test_docs_routes.py +++ b/agents-api/tests/test_docs_routes.py @@ -1,6 +1,6 @@ from ward import test -from .fixtures import ( +from tests.fixtures import ( make_request, patch_embed_acompletion, test_agent, @@ -8,7 +8,7 @@ test_user, test_user_doc, ) -from .utils import patch_testing_temporal +from tests.utils import patch_testing_temporal @test("route: create user doc") diff --git a/agents-api/tests/test_execution_queries.py b/agents-api/tests/test_execution_queries.py index 29ddcbd86..7af9f9512 100644 --- a/agents-api/tests/test_execution_queries.py +++ b/agents-api/tests/test_execution_queries.py @@ -16,7 +16,7 @@ from agents_api.models.execution.list_executions import list_executions from agents_api.models.execution.lookup_temporal_data import lookup_temporal_data -from .fixtures import ( +from tests.fixtures import ( cozo_client, test_developer_id, test_execution, diff --git a/agents-api/tests/test_execution_workflow.py b/agents-api/tests/test_execution_workflow.py index b6394f1bc..ecebf34c3 100644 --- a/agents-api/tests/test_execution_workflow.py +++ b/agents-api/tests/test_execution_workflow.py @@ -15,8 +15,8 @@ from agents_api.models.task.create_task import create_task from agents_api.routers.tasks.create_task_execution import start_execution -from .fixtures import cozo_client, test_agent, test_developer_id -from .utils import patch_integration_service, patch_testing_temporal +from tests.fixtures import cozo_client, test_agent, test_developer_id +from tests.utils import patch_integration_service, patch_testing_temporal EMBEDDING_SIZE: int = 1024 diff --git a/agents-api/tests/test_task_queries.py b/agents-api/tests/test_task_queries.py index 2399416db..f14c431f8 100644 --- a/agents-api/tests/test_task_queries.py +++ b/agents-api/tests/test_task_queries.py @@ -16,7 +16,7 @@ from agents_api.models.task.list_tasks import list_tasks from agents_api.models.task.update_task import update_task -from .fixtures import cozo_client, test_agent, test_developer_id, test_task +from tests.fixtures import cozo_client, test_agent, test_developer_id, test_task @test("model: create task") diff --git a/agents-api/tests/test_task_routes.py b/agents-api/tests/test_task_routes.py index 4ab708560..5d3c2f998 100644 --- a/agents-api/tests/test_task_routes.py +++ b/agents-api/tests/test_task_routes.py @@ -4,14 +4,14 @@ from ward import test -from .fixtures import ( +from tests.fixtures import ( client, make_request, test_agent, test_execution, test_task, ) -from .utils import patch_testing_temporal +from tests.utils import patch_testing_temporal @test("route: unauthorized should fail") diff --git a/agents-api/tests/test_workflow_routes.py b/agents-api/tests/test_workflow_routes.py index 34aa0101c..d1538535d 100644 --- a/agents-api/tests/test_workflow_routes.py +++ b/agents-api/tests/test_workflow_routes.py @@ -4,8 +4,8 @@ from ward import test -from .fixtures import cozo_client, test_agent, test_developer_id -from .utils import patch_http_client_with_temporal +from tests.fixtures import cozo_client, test_agent, test_developer_id +from tests.utils import patch_http_client_with_temporal @test("workflow route: evaluate step single") diff --git a/agents-api/tests/utils.py b/agents-api/tests/utils.py index 3f0f1f94a..dc1007d13 100644 --- a/agents-api/tests/utils.py +++ b/agents-api/tests/utils.py @@ -10,6 +10,7 @@ from agents_api.worker.codec import pydantic_data_converter from agents_api.worker.worker import create_worker +# Replicated here to prevent circular import EMBEDDING_SIZE: int = 1024 From a6bcbbe91202d37f063f5a74f10178f283bfdb26 Mon Sep 17 00:00:00 2001 From: creatorrr Date: Fri, 4 Oct 2024 00:40:27 +0000 Subject: [PATCH 16/16] refactor: Lint agents-api (CI) --- agents-api/agents_api/clients/worker/worker.py | 1 - agents-api/agents_api/common/exceptions/sessions.py | 1 + agents-api/agents_api/common/protocol/agents.py | 2 +- agents-api/agents_api/common/utils/json.py | 2 +- agents-api/tests/fixtures.py | 1 - agents-api/tests/test_execution_queries.py | 1 - agents-api/tests/test_execution_workflow.py | 1 - agents-api/tests/test_task_queries.py | 1 - 8 files changed, 3 insertions(+), 7 deletions(-) diff --git a/agents-api/agents_api/clients/worker/worker.py b/agents-api/agents_api/clients/worker/worker.py index 55b810c3e..8befa3080 100644 --- a/agents-api/agents_api/clients/worker/worker.py +++ b/agents-api/agents_api/clients/worker/worker.py @@ -1,7 +1,6 @@ import httpx from ...env import temporal_worker_url - from .types import ( MemoryManagementTask, MemoryManagementTaskArgs, diff --git a/agents-api/agents_api/common/exceptions/sessions.py b/agents-api/agents_api/common/exceptions/sessions.py index 14d6ff4e7..6e9941d43 100644 --- a/agents-api/agents_api/common/exceptions/sessions.py +++ b/agents-api/agents_api/common/exceptions/sessions.py @@ -8,6 +8,7 @@ from . import BaseCommonException + class BaseSessionException(BaseCommonException): """ Base exception class for session-related errors. diff --git a/agents-api/agents_api/common/protocol/agents.py b/agents-api/agents_api/common/protocol/agents.py index fb8b4f063..89f7f4a2d 100644 --- a/agents-api/agents_api/common/protocol/agents.py +++ b/agents-api/agents_api/common/protocol/agents.py @@ -9,7 +9,7 @@ class AgentDefaultSettings(BaseModel): top_p: float = 1.0 """Top-p sampling setting controlling the nucleus of the probability distribution to sample from.""" - + repetition_penalty: float = 1.0 """Penalty applied to discourage repetition in the agent's responses.""" diff --git a/agents-api/agents_api/common/utils/json.py b/agents-api/agents_api/common/utils/json.py index ec53ecb27..f1b82742a 100644 --- a/agents-api/agents_api/common/utils/json.py +++ b/agents-api/agents_api/common/utils/json.py @@ -39,7 +39,7 @@ def default(self, obj) -> Any: obj: The object to serialize. Returns: A serializable object or raises a TypeError if the object is not serializable. """ - + if obj is None: return self._default_empty_value diff --git a/agents-api/tests/fixtures.py b/agents-api/tests/fixtures.py index b732e750c..9ae198c78 100644 --- a/agents-api/tests/fixtures.py +++ b/agents-api/tests/fixtures.py @@ -36,7 +36,6 @@ from agents_api.models.user.create_user import create_user from agents_api.models.user.delete_user import delete_user from agents_api.web import app - from tests.utils import patch_embed_acompletion as patch_embed_acompletion_ctx EMBEDDING_SIZE: int = 1024 diff --git a/agents-api/tests/test_execution_queries.py b/agents-api/tests/test_execution_queries.py index 7af9f9512..42904776d 100644 --- a/agents-api/tests/test_execution_queries.py +++ b/agents-api/tests/test_execution_queries.py @@ -15,7 +15,6 @@ from agents_api.models.execution.get_execution import get_execution from agents_api.models.execution.list_executions import list_executions from agents_api.models.execution.lookup_temporal_data import lookup_temporal_data - from tests.fixtures import ( cozo_client, test_developer_id, diff --git a/agents-api/tests/test_execution_workflow.py b/agents-api/tests/test_execution_workflow.py index ecebf34c3..3df23e5cd 100644 --- a/agents-api/tests/test_execution_workflow.py +++ b/agents-api/tests/test_execution_workflow.py @@ -14,7 +14,6 @@ ) from agents_api.models.task.create_task import create_task from agents_api.routers.tasks.create_task_execution import start_execution - from tests.fixtures import cozo_client, test_agent, test_developer_id from tests.utils import patch_integration_service, patch_testing_temporal diff --git a/agents-api/tests/test_task_queries.py b/agents-api/tests/test_task_queries.py index f14c431f8..e61489df8 100644 --- a/agents-api/tests/test_task_queries.py +++ b/agents-api/tests/test_task_queries.py @@ -15,7 +15,6 @@ from agents_api.models.task.get_task import get_task from agents_api.models.task.list_tasks import list_tasks from agents_api.models.task.update_task import update_task - from tests.fixtures import cozo_client, test_agent, test_developer_id, test_task