Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(agents-api): Miscellaneous fixes related to sessions & entries #1000

Merged
merged 10 commits into from
Dec 31, 2024

Conversation

HamadaSalhab
Copy link
Contributor

@HamadaSalhab HamadaSalhab commented Dec 28, 2024

PR Type

Enhancement, Tests


Description

  • Major database migration from Cozo to PostgreSQL across multiple components:
    • Updated test fixtures and test cases
    • Migrated queries for tasks, sessions, entries, agents and files
    • Added new PostgreSQL utility functions and helpers
  • Enhanced session and agent models:
    • Added forward_tool_calls field to sessions
    • Split situation field into situation and system_template
    • Added canonical_name support for agents
  • Improved error handling and blob store integration:
    • Added blob store support for large payloads
    • Enhanced error handling in executions and transitions
    • Implemented generic error handling patterns
  • Added new functionality:
    • Maximal marginal relevance search implementation
    • Task creation and updates with version control
    • Document listing with filtering and pagination
    • Cascading deletion for agents and entries

Changes walkthrough 📝

Relevant files
Tests
11 files
test_execution_workflow.py
Migrate execution workflow tests from Cozo to PostgreSQL 

agents-api/tests/test_execution_workflow.py

  • Replaced Cozo DB client with PostgreSQL pool in test fixtures and
    database operations
  • Updated test function signatures to be async
  • Added S3 client fixture for potential blob store usage
  • Removed unused EMBEDDING_SIZE constant
  • +188/-138
    fixtures.py
    Replace Cozo fixtures with PostgreSQL test fixtures           

    agents-api/tests/fixtures.py

  • Replaced Cozo DB fixtures with PostgreSQL fixtures
  • Added new fixtures for database pool, S3 client, and email generation
  • Updated test fixtures to use async/await pattern
  • Added new developer and session test fixtures
  • +228/-284
    test_task_queries.py
    Migrate task query tests to PostgreSQL database                   

    agents-api/tests/test_task_queries.py

  • Migrated task query tests from Cozo to PostgreSQL
  • Added new test cases for CRUD operations
  • Improved error handling tests
  • Added type checking and validation
  • +269/-88
    test_session_queries.py
    Migrate session query tests to PostgreSQL                               

    agents-api/tests/test_session_queries.py

  • Migrated session tests from Cozo to PostgreSQL
  • Added new test cases for CRUD operations
  • Improved error handling and validation
  • Added async/await pattern support
  • +194/-99
    test_chat_routes.py
    Comment out chat route tests and update import paths         

    agents-api/tests/test_chat_routes.py

  • Commented out all test cases related to chat routes
  • Updated import paths from 'models' to 'queries' namespace
  • Fixed path references for gather_messages and prepare_chat_context
  • +177/-177
    test_docs_routes.py
    Simplify and comment out document route tests                       

    agents-api/tests/test_docs_routes.py

  • Commented out most test cases for document routes
  • Removed unused imports and simplified remaining tests
  • Updated test structure and assertions
  • +145/-150
    test_files_queries.py
    Add PostgreSQL-based file operation tests                               

    agents-api/tests/test_files_queries.py

  • Added new test cases for file operations with PostgreSQL
  • Updated imports to use new queries namespace
  • Added tests for user and agent file operations
  • +225/-31
    test_agent_queries.py
    Migrate agent tests to PostgreSQL database                             

    agents-api/tests/test_agent_queries.py

  • Migrated tests to use PostgreSQL database
  • Added new test cases for agent operations
  • Updated imports to use queries namespace
  • +100/-92
    test_entry_queries.py
    Migrate entry tests to PostgreSQL database                             

    agents-api/tests/test_entry_queries.py

  • Migrated entry tests to use PostgreSQL
  • Added new test cases for entry operations
  • Updated assertions and error handling
  • +75/-91 
    test_workflow_routes.py
    Comment out workflow route tests and update UUIDs               

    agents-api/tests/test_workflow_routes.py

  • Commented out workflow route tests
  • Updated UUID generation to use uuid7
  • Fixed import paths
  • +135/-136
    test_task_routes.py
    Update task route tests with transition coverage                 

    agents-api/tests/test_task_routes.py

  • Updated test cases for task routes
  • Added new tests for transitions
  • Fixed test data handling
  • Updated UUID generation
  • +49/-25 
    Enhancement
    20 files
    Sessions.py
    Add tool calls forwarding and template improvements to Sessions

    agents-api/agents_api/autogen/Sessions.py

  • Added new field forward_tool_calls to session models
  • Split situation field into separate situation and system_template
    fields
  • Updated template string to include situation in system prompt
  • +50/-10 
    utils.py
    Add PostgreSQL query utilities and helpers                             

    agents-api/agents_api/queries/utils.py

  • Added new utility functions for PostgreSQL queries
  • Implemented query preparation and execution helpers
  • Added exception handling and rewrapping
  • Added concurrent execution utilities
  • +335/-0 
    set_value_step.py
    Remove blob store auto-decoration from set value step       

    agents-api/agents_api/activities/task_steps/set_value_step.py

    • Removed @auto_blob_store decorator
    • Cleaned up imports
    +2/-3     
    interceptors.py
    Add blob store support and enhance error handling               

    agents-api/agents_api/common/interceptors.py

  • Added blob store integration for large payloads
  • Implemented generic error handling for executions
  • Added type hints and documentation
  • +115/-74
    create_or_update_task.py
    Implement task creation with version control                         

    agents-api/agents_api/queries/tasks/create_or_update_task.py

  • Implemented task creation and update functionality
  • Added version control for tasks
  • Added support for tools and workflows
  • +247/-0 
    create_task.py
    Implement task creation with tools and workflows                 

    agents-api/agents_api/queries/tasks/create_task.py

  • Implemented task creation functionality
  • Added support for tools and workflows
  • Added error handling and validation
  • +211/-0 
    list_docs.py
    Implement document listing with filtering and pagination 

    agents-api/agents_api/queries/docs/list_docs.py

  • Implemented document listing functionality
  • Added support for pagination and sorting
  • Added metadata filtering
  • +160/-0 
    transition_step.py
    Update transition step with new query system                         

    agents-api/agents_api/activities/task_steps/transition_step.py

  • Updated to use new queries namespace
  • Added container lifespan management
  • Simplified transition creation logic
  • +7/-11   
    update_task.py
    Add task update functionality with version control             

    agents-api/agents_api/queries/tasks/update_task.py

  • Added new query file for updating tasks with version control
  • Implemented SQL queries for tasks and workflows updates
  • Added error handling and response transformation
  • Added type hints and documentation
  • +172/-0 
    Agents.py
    Update agent models with canonical name support                   

    agents-api/agents_api/autogen/Agents.py

  • Updated agent model fields and validation rules
  • Added canonical_name field to agent models
  • Modified name field constraints
  • Updated field patterns and length limits
  • +40/-35 
    async_s3.py
    Refactor S3 client implementation for better efficiency   

    agents-api/agents_api/clients/async_s3.py

  • Simplified S3 client initialization and management
  • Removed redundant session creation
  • Added caching for bucket listing
  • Improved error handling
  • +46/-74 
    delete_entries.py
    Add entry deletion functionality with cascading support   

    agents-api/agents_api/queries/entries/delete_entries.py

  • Added new query file for deleting entries
  • Implemented cascading deletion for entry relations
  • Added session existence validation
  • Added error handling and response transformation
  • +159/-0 
    create_task_execution.py
    Enhance task execution creation with better error handling

    agents-api/agents_api/routers/tasks/create_task_execution.py

  • Updated task execution creation logic
  • Added transition handling for errors
  • Improved error handling and validation
  • Updated UUID generation to use uuid7
  • +49/-32 
    app.py
    Add FastAPI application setup with lifecycle management   

    agents-api/agents_api/app.py

  • Added new FastAPI application setup
  • Implemented database and S3 client lifecycle management
  • Added metrics instrumentation
  • Added Scalar API documentation support
  • +118/-0 
    tasks.py
    Update task protocol with simplified remote handling         

    agents-api/agents_api/common/protocol/tasks.py

  • Updated task protocol definitions
  • Modified execution input handling
  • Simplified remote object handling
  • Updated type hints
  • +16/-19 
    create_doc.py
    Simplify document creation without embedding workflow       

    agents-api/agents_api/routers/docs/create_doc.py

  • Simplified document creation logic
  • Removed embedding workflow integration
  • Updated response handling
  • Improved error handling
  • +6/-79   
    mmr.py
    Add maximal marginal relevance search implementation         

    agents-api/agents_api/queries/docs/mmr.py

  • Added maximal marginal relevance implementation
  • Added cosine similarity calculation
  • Added numpy and simsimd optimizations
  • Added type hints and documentation
  • +110/-1 
    remote.py
    Simplify remote object protocol with generic types             

    agents-api/agents_api/common/protocol/remote.py

  • Simplified remote object implementation
  • Added generic type support
  • Updated serialization handling
  • Removed complex caching logic
  • +20/-77 
    delete_agent.py
    Add agent deletion with cascading resource cleanup             

    agents-api/agents_api/queries/agents/delete_agent.py

  • Added cascading deletion for agent resources
  • Added cleanup for files, docs and tools
  • Added error handling
  • Added response transformation
  • +114/-0 
    get_value_step.py
    Simplify get value step implementation                                     

    agents-api/agents_api/activities/task_steps/get_value_step.py

    • Removed auto blob store decorator
    • Simplified step implementation
    +2/-3     
    Miscellaneous
    1 files
    utils.py
    Update activity utilities with new module paths                   

    agents-api/agents_api/activities/utils.py

  • Updated import paths for query modules
  • Reorganized module structure
  • Updated handler function imports
  • +22/-22 
    Additional files (token-limit)
    101 files
    search_docs_hybrid.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/search_docs_hybrid.py

    ...

    +102/-0 
    list_executions.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/list_executions.py

    ...

    +97/-0   
    get_history.py
    ...                                                                                                           

    agents-api/agents_api/queries/entries/get_history.py

    ...

    +122/-0 
    utils.py
    ...                                                                                                           

    agents-api/tests/utils.py

    ...

    +17/-61 
    list_agents.py
    ...                                                                                                           

    agents-api/agents_api/queries/agents/list_agents.py

    ...

    +110/-0 
    patch_agent.py
    ...                                                                                                           

    agents-api/agents_api/queries/agents/patch_agent.py

    ...

    +110/-0 
    get_task.py
    ...                                                                                                           

    agents-api/agents_api/queries/tasks/get_task.py

    ...

    +97/-0   
    prepare_execution_input.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/prepare_execution_input.py

    ...

    +112/-0 
    patch_tool.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/patch_tool.py

    ...

    +98/-0   
    list_users.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/list_users.py

    ...

    +91/-0   
    patch_session.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/patch_session.py

    ...

    +94/-0   
    create_execution.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/create_execution.py

    ...

    +117/-0 
    Tasks.py
    ...                                                                                                           

    agents-api/agents_api/autogen/Tasks.py

    ...

    +56/-2   
    test_activities.py
    ...                                                                                                           

    agents-api/tests/test_activities.py

    ...

    +56/-57 
    create_tools.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/create_tools.py

    ...

    +114/-0 
    list_files.py
    ...                                                                                                           

    agents-api/agents_api/queries/files/list_files.py

    ...

    +91/-0   
    test_messages_truncation.py
    ...                                                                                                           

    agents-api/tests/test_messages_truncation.py

    ...

    +9/-9     
    update_session.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/update_session.py

    ...

    +94/-0   
    update_tool.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/update_tool.py

    ...

    +97/-0   
    search_docs_by_embedding.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/search_docs_by_embedding.py

    ...

    +88/-0   
    update_agent.py
    ...                                                                                                           

    agents-api/agents_api/queries/agents/update_agent.py

    ...

    +95/-0   
    Tasks.py
    ...                                                                                                           

    integrations-service/integrations/autogen/Tasks.py

    ...

    +56/-2   
    list_execution_transitions.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/list_execution_transitions.py

    ...

    +88/-0   
    delete_file.py
    ...                                                                                                           

    agents-api/agents_api/queries/files/delete_file.py

    ...

    +92/-0   
    delete_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/delete_user.py

    ...

    +94/-0   
    patch_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/patch_user.py

    ...

    +85/-0   
    web.py
    ...                                                                                                           

    agents-api/agents_api/web.py

    ...

    +7/-43   
    get_file.py
    ...                                                                                                           

    agents-api/agents_api/queries/files/get_file.py

    ...

    +87/-0   
    gather_messages.py
    ...                                                                                                           

    agents-api/agents_api/queries/chat/gather_messages.py

    ...

    +10/-12 
    search_docs_by_text.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/search_docs_by_text.py

    ...

    +83/-0   
    create_or_update_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/create_or_update_user.py

    ...

    +89/-0   
    chat.py
    ...                                                                                                           

    agents-api/agents_api/routers/sessions/chat.py

    ...

    +11/-11 
    get_execution_transition.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/get_execution_transition.py

    ...

    +87/-0   
    get_doc.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/get_doc.py

    ...

    +86/-0   
    get_session.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/get_session.py

    ...

    +83/-0   
    create_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/create_user.py

    ...

    +89/-0   
    delete_task.py
    ...                                                                                                           

    agents-api/agents_api/queries/tasks/delete_task.py

    ...

    +78/-0   
    delete_doc.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/delete_doc.py

    ...

    +79/-0   
    execute_system.py
    ...                                                                                                           

    agents-api/agents_api/activities/execute_system.py

    ...

    +8/-8     
    get_agent.py
    ...                                                                                                           

    agents-api/agents_api/queries/agents/get_agent.py

    ...

    +83/-0   
    list_tools.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/list_tools.py

    ...

    +72/-0   
    env.py
    ...                                                                                                           

    agents-api/agents_api/env.py

    ...

    +13/-11 
    update_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/update_user.py

    ...

    +73/-0   
    delete_session.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/delete_session.py

    ...

    +69/-0   
    create_temporal_lookup.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/create_temporal_lookup.py

    ...

    +80/-0   
    get_user.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/get_user.py

    ...

    +64/-0   
    execute_integration.py
    ...                                                                                                           

    agents-api/agents_api/activities/execute_integration.py

    ...

    +16/-7   
    create_developer.py
    ...                                                                                                           

    agents-api/agents_api/queries/developers/create_developer.py

    ...

    +66/-0   
    get_execution.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/get_execution.py

    ...

    +65/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/workflows/task_execution/init.py

    ...

    +3/-16   
    test_sessions.py
    ...                                                                                                           

    agents-api/tests/test_sessions.py

    ...

    +27/-27 
    lookup_temporal_data.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/lookup_temporal_data.py

    ...

    +61/-0   
    patch_execution.py
    ...                                                                                                           

    agents-api/agents_api/routers/tasks/patch_execution.py

    ...

    +26/-25 
    temporal.py
    ...                                                                                                           

    agents-api/agents_api/clients/temporal.py

    ...

    +7/-5     
    count_executions.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/count_executions.py

    ...

    +60/-0   
    get_temporal_workflow_data.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/get_temporal_workflow_data.py

    ...

    +58/-0   
    update_developer.py
    ...                                                                                                           

    agents-api/agents_api/queries/developers/update_developer.py

    ...

    +55/-0   
    test_user_routes.py
    ...                                                                                                           

    agents-api/tests/test_user_routes.py

    ...

    +6/-6     
    delete_tool.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/delete_tool.py

    ...

    +58/-0   
    get_paused_execution_token.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/get_paused_execution_token.py

    ...

    +57/-0   
    get_tool.py
    ...                                                                                                           

    agents-api/agents_api/queries/tools/get_tool.py

    ...

    +59/-0   
    patch_developer.py
    ...                                                                                                           

    agents-api/agents_api/queries/developers/patch_developer.py

    ...

    +50/-0   
    developer_id.py
    ...                                                                                                           

    agents-api/agents_api/dependencies/developer_id.py

    ...

    +5/-5     
    count_sessions.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/count_sessions.py

    ...

    +55/-0   
    worker.py
    ...                                                                                                           

    agents-api/agents_api/worker/worker.py

    ...

    +1/-5     
    get_file.py
    ...                                                                                                           

    agents-api/agents_api/routers/files/get_file.py

    ...

    +9/-4     
    search_docs.py
    ...                                                                                                           

    agents-api/agents_api/routers/docs/search_docs.py

    ...

    +6/-6     
    get_developer.py
    ...                                                                                                           

    agents-api/agents_api/queries/developers/get_developer.py

    ...

    +54/-0   
    get_task_details.py
    ...                                                                                                           

    agents-api/agents_api/routers/tasks/get_task_details.py

    ...

    +4/-17   
    update_execution.py
    ...                                                                                                           

    agents-api/agents_api/routers/tasks/update_execution.py

    ...

    +4/-6     
    truncation.py
    ...                                                                                                           

    agents-api/agents_api/activities/truncation.py

    ...

    +5/-4     
    delete_file.py
    ...                                                                                                           

    agents-api/agents_api/routers/files/delete_file.py

    ...

    +7/-4     
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/init.py

    ...

    +20/-0   
    create_file.py
    ...                                                                                                           

    agents-api/agents_api/routers/files/create_file.py

    ...

    +9/-4     
    sync_items_remote.py
    ...                                                                                                           

    agents-api/agents_api/activities/sync_items_remote.py

    ...

    +4/-8     
    list_docs.py
    ...                                                                                                           

    agents-api/agents_api/routers/docs/list_docs.py

    ...

    +3/-3     
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/executions/init.py

    ...

    +33/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/init.py

    ...

    +14/-1   
    test_agent_routes.py
    ...                                                                                                           

    agents-api/tests/test_agent_routes.py

    ...

    +5/-5     
    pg_query_step.py
    ...                                                                                                           

    agents-api/agents_api/activities/task_steps/pg_query_step.py

    ...

    +32/-0   
    sessions.py
    ...                                                                                                           

    agents-api/agents_api/common/protocol/sessions.py

    ...

    +2/-1     
    openapi_model.py
    ...                                                                                                           

    agents-api/agents_api/autogen/openapi_model.py

    ...

    +2/-2     
    utils.py
    ...                                                                                                           

    agents-api/agents_api/queries/docs/utils.py

    ...

    +36/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/agents/init.py

    ...

    +31/-0   
    Docs.py
    ...                                                                                                           

    agents-api/agents_api/autogen/Docs.py

    ...

    +20/-0   
    delete_doc.py
    ...                                                                                                           

    agents-api/agents_api/routers/docs/delete_doc.py

    ...

    +3/-3     
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/sessions/init.py

    ...

    +30/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/tasks/init.py

    ...

    +28/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/queries/users/init.py

    ...

    +28/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/routers/agents/init.py

    ...

    +9/-5     
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/clients/init.py

    ...

    +1/-1     
    Docs.py
    ...                                                                                                           

    integrations-service/integrations/autogen/Docs.py

    ...

    +20/-0   
    create_or_update_agent.py
    ...                                                                                                           

    agents-api/agents_api/routers/agents/create_or_update_agent.py

    ...

    +4/-3     
    list_files.py
    ...                                                                                                           

    agents-api/agents_api/routers/files/list_files.py

    ...

    +24/-0   
    __init__.py
    ...                                                                                                           

    agents-api/agents_api/common/utils/init.py

    ...

    +1/-1     
    list_agents.py
    ...                                                                                                           

    agents-api/agents_api/routers/agents/list_agents.py

    ...

    +2/-2     
    check_health.py
    ...                                                                                                           

    agents-api/agents_api/routers/healthz/check_health.py

    ...

    +19/-0   
    list_sessions.py
    ...                                                                                                           

    agents-api/agents_api/routers/sessions/list_sessions.py

    ...

    +2/-2     
    create_agent_tool.py
    ...                                                                                                           

    agents-api/agents_api/routers/agents/create_agent_tool.py

    ...

    +2/-3     
    list_users.py
    ...                                                                                                           

    agents-api/agents_api/routers/users/list_users.py

    ...

    +2/-2     
    Additional 105 files not shown
    ...                                                                                                           

    Additional 105 files not shown

    ...

    Additional files (token-limit)extra_file_yaml =
    1 files
    list_task_executions.py
    ...                                                                                                           

    agents-api/agents_api/routers/tasks/list_task_executions.py

    ...

    +2/-2     

    💡 PR-Agent usage: Comment /help "your question" on any pull request to receive relevant information

    Copy link

    gitguardian bot commented Dec 28, 2024

    ️✅ There are no secrets present in this pull request anymore.

    If these secrets were true positive and are still valid, we highly recommend you to revoke them.
    While these secrets were previously flagged, we no longer have a reference to the
    specific commits where they were detected. Once a secret has been leaked into a git
    repository, you should consider it compromised, even if it was deleted immediately.
    Find here more information about risks.


    🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Breaking Change

    Major changes to session model with splitting of situation field into situation and system_template, and addition of forward_tool_calls. Ensure all existing code handles these model changes correctly.

    situation: str | None = None
    """
    Session situation
    """
    system_template: str = '{%- if agent.name -%}\nYou are {{agent.name}}.{{" "}}\n{%- endif -%}\n\n{%- if agent.about -%}\nAbout you: {{agent.about}}.{{" "}}\n{%- endif -%}\n\n{%- if user -%}\nYou are talking to a user\n  {%- if user.name -%}{{" "}} and their name is {{user.name}}\n    {%- if user.about -%}. About the user: {{user.about}}.{%- else -%}.{%- endif -%}\n  {%- endif -%}\n{%- endif -%}\n\n{{NEWLINE}}\n\n{%- if session.situation -%}\nSituation: {{session.situation}}\n{%- endif -%}\n\n{{NEWLINE+NEWLINE}}\n\n{%- if agent.instructions -%}\nInstructions:{{NEWLINE}}\n  {%- if agent.instructions is string -%}\n    {{agent.instructions}}{{NEWLINE}}\n  {%- else -%}\n    {%- for instruction in agent.instructions -%}\n      - {{instruction}}{{NEWLINE}}\n    {%- endfor -%}\n  {%- endif -%}\n  {{NEWLINE}}\n{%- endif -%}\n\n{%- if docs -%}\nRelevant documents:{{NEWLINE}}\n  {%- for doc in docs -%}\n    {{doc.title}}{{NEWLINE}}\n    {%- if doc.content is string -%}\n      {{doc.content}}{{NEWLINE}}\n    {%- else -%}\n      {%- for snippet in doc.content -%}\n        {{snippet}}{{NEWLINE}}\n      {%- endfor -%}\n    {%- endif -%}\n    {{"---"}}\n  {%- endfor -%}\n{%- endif -%}'
    """
    A specific system prompt template that sets the background for this session
    """
    Test Coverage

    New PostgreSQL task queries implementation needs comprehensive error case testing, particularly around transaction handling and concurrent access patterns.

    # Tests for task queries
    
    from fastapi import HTTPException
    from uuid_extensions import uuid7
    from ward import raises, test
    
    from agents_api.autogen.openapi_model import (
        CreateTaskRequest,
        PatchTaskRequest,
        ResourceUpdatedResponse,
        Task,
        UpdateTaskRequest,
    )
    from agents_api.clients.pg import create_db_pool
    from agents_api.queries.tasks.create_or_update_task import create_or_update_task
    from agents_api.queries.tasks.create_task import create_task
    from agents_api.queries.tasks.delete_task import delete_task
    from agents_api.queries.tasks.get_task import get_task
    from agents_api.queries.tasks.list_tasks import list_tasks
    from agents_api.queries.tasks.patch_task import patch_task
    from agents_api.queries.tasks.update_task import update_task
    from tests.fixtures import pg_dsn, test_agent, test_developer_id, test_task
    
    
    @test("query: create task sql")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that a task can be successfully created."""
    
        pool = await create_db_pool(dsn=dsn)
        await create_task(
            developer_id=developer_id,
            agent_id=agent.id,
            task_id=uuid7(),
            data=CreateTaskRequest(
                name="test task",
                description="test task about",
                input_schema={"type": "object", "additionalProperties": True},
                main=[{"evaluate": {"hi": "_"}}],
            ),
            connection_pool=pool,
        )
    
    
    @test("query: create or update task sql")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that a task can be successfully created or updated."""
    
        pool = await create_db_pool(dsn=dsn)
        await create_or_update_task(
            developer_id=developer_id,
            agent_id=agent.id,
            task_id=uuid7(),
            data=CreateTaskRequest(
                name="test task",
                description="test task about",
                input_schema={"type": "object", "additionalProperties": True},
                main=[{"evaluate": {"hi": "_"}}],
            ),
            connection_pool=pool,
        )
    
    
    @test("query: get task sql - exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, task=test_task):
        """Test that an existing task can be successfully retrieved."""
    
        pool = await create_db_pool(dsn=dsn)
    
        # Then retrieve it
        result = await get_task(
            developer_id=developer_id,
            task_id=task.id,
            connection_pool=pool,
        )
        assert result is not None
        assert isinstance(result, Task), f"Result is not a Task, got {type(result)}"
        assert result.id == task.id
        assert result.name == "test task"
        assert result.description == "test task about"
    
    
    @test("query: get task sql - not exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id):
        """Test that attempting to retrieve a non-existent task raises an error."""
    
        pool = await create_db_pool(dsn=dsn)
        task_id = uuid7()
    
        with raises(HTTPException) as exc:
            await get_task(
                developer_id=developer_id,
                task_id=task_id,
                connection_pool=pool,
            )
    
        assert exc.raised.status_code == 404
        assert "Task not found" in str(exc.raised.detail)
    
    
    @test("query: delete task sql - exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, task=test_task):
        """Test that a task can be successfully deleted."""
    
        pool = await create_db_pool(dsn=dsn)
    
        # First verify task exists
        result = await get_task(
            developer_id=developer_id,
            task_id=task.id,
            connection_pool=pool,
        )
        assert result is not None
        assert result.id == task.id
    
        # Delete the task
        deleted = await delete_task(
            developer_id=developer_id,
            task_id=task.id,
            connection_pool=pool,
        )
        assert deleted is not None
        assert deleted.id == task.id
    
        # Verify task no longer exists
        with raises(HTTPException) as exc:
            await get_task(
                developer_id=developer_id,
                task_id=task.id,
                connection_pool=pool,
            )
    
        assert exc.raised.status_code == 404
        assert "Task not found" in str(exc.raised.detail)
    
    
    @test("query: delete task sql - not exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id):
        """Test that attempting to delete a non-existent task raises an error."""
    
        pool = await create_db_pool(dsn=dsn)
        task_id = uuid7()
    
        with raises(HTTPException) as exc:
            await delete_task(
                developer_id=developer_id,
                task_id=task_id,
                connection_pool=pool,
            )
    
        assert exc.raised.status_code == 404
        assert "Task not found" in str(exc.raised.detail)
    
    
    # Add tests for list tasks
    @test("query: list tasks sql - with filters")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that tasks can be successfully filtered and retrieved."""
    
        pool = await create_db_pool(dsn=dsn)
        result = await list_tasks(
            developer_id=developer_id,
            agent_id=agent.id,
            limit=10,
            offset=0,
            sort_by="updated_at",
            direction="asc",
            metadata_filter={"test": True},
            connection_pool=pool,
        )
        assert result is not None
        assert isinstance(result, list)
        assert all(isinstance(task, Task) for task in result)
        assert all(task.metadata.get("test") is True for task in result)
    
    
    @test("query: list tasks sql - no filters")
    async def _(
        dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent, task=test_task
    ):
        """Test that a list of tasks can be successfully retrieved."""
    
        pool = await create_db_pool(dsn=dsn)
        result = await list_tasks(
            developer_id=developer_id,
            agent_id=agent.id,
            connection_pool=pool,
        )
        assert result is not None, "Result is None"
        assert isinstance(result, list), f"Result is not a list, got {type(result)}"
        assert len(result) > 0, "Result is empty"
        assert all(
            isinstance(task, Task) for task in result
        ), "Not all listed tasks are of type Task"
    
    
    @test("query: update task sql - exists")
    async def _(
        dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent, task=test_task
    ):
        """Test that a task can be successfully updated."""
    
        pool = await create_db_pool(dsn=dsn)
        updated = await update_task(
            developer_id=developer_id,
            task_id=task.id,
            agent_id=agent.id,
            data=UpdateTaskRequest(
                **{
                    "name": "updated task",
                    "canonical_name": "updated_task",
                    "description": "updated task description",
                    "input_schema": {"type": "object", "additionalProperties": True},
                    "main": [{"evaluate": {"hi": "_"}}],
                    "inherit_tools": False,
                    "metadata": {"updated": True},
                }
            ),
            connection_pool=pool,
        )
    
        assert updated is not None
        assert isinstance(updated, ResourceUpdatedResponse)
        assert updated.id == task.id
    
        # Verify task was updated
        updated_task = await get_task(
            developer_id=developer_id,
            task_id=task.id,
            connection_pool=pool,
        )
        assert updated_task.name == "updated task"
        assert updated_task.description == "updated task description"
        assert updated_task.metadata == {"updated": True}
    
    
    @test("query: update task sql - not exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that attempting to update a non-existent task raises an error."""
    
        pool = await create_db_pool(dsn=dsn)
        task_id = uuid7()
    
        with raises(HTTPException) as exc:
            await update_task(
                developer_id=developer_id,
                task_id=task_id,
                agent_id=agent.id,
                data=UpdateTaskRequest(
                    **{
                        "canonical_name": "updated_task",
                        "name": "updated task",
                        "description": "updated task description",
                        "input_schema": {"type": "object", "additionalProperties": True},
                        "main": [{"evaluate": {"hi": "_"}}],
                        "inherit_tools": False,
                    }
                ),
                connection_pool=pool,
            )
    
        assert exc.raised.status_code == 404
        assert "Task not found" in str(exc.raised.detail)
    
    
    @test("query: patch task sql - exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that patching an existing task works correctly."""
        pool = await create_db_pool(dsn=dsn)
    
        # Create initial task
        task = await create_task(
            developer_id=developer_id,
            agent_id=agent.id,
            data=CreateTaskRequest(
                **{
                    "canonical_name": "test_task",
                    "name": "test task",
                    "description": "test task description",
                    "input_schema": {"type": "object", "additionalProperties": True},
                    "main": [{"evaluate": {"hi": "_"}}],
                    "inherit_tools": False,
                    "metadata": {"initial": True},
                }
            ),
            connection_pool=pool,
        )
    
        # Patch the task
        updated = await patch_task(
            developer_id=developer_id,
            task_id=task.id,
            agent_id=agent.id,
            data=PatchTaskRequest(
                **{
                    "name": "patched task",
                    "metadata": {"patched": True},
                }
            ),
            connection_pool=pool,
        )
    
        assert updated is not None
        assert isinstance(updated, ResourceUpdatedResponse)
        assert updated.id == task.id
    
        # Verify task was patched correctly
        patched_task = await get_task(
            developer_id=developer_id,
            task_id=task.id,
            connection_pool=pool,
        )
        # Check that patched fields were updated
        assert patched_task.name == "patched task"
        assert patched_task.metadata == {"patched": True}
        # Check that non-patched fields remain unchanged
        assert patched_task.canonical_name == "test_task"
        assert patched_task.description == "test task description"
    
    
    @test("query: patch task sql - not exists")
    async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
        """Test that attempting to patch a non-existent task raises an error."""
        pool = await create_db_pool(dsn=dsn)
        task_id = uuid7()
    
        with raises(HTTPException) as exc:
            await patch_task(
                developer_id=developer_id,
                task_id=task_id,
                agent_id=agent.id,
                data=PatchTaskRequest(
                    **{
                        "name": "patched task",
                        "metadata": {"patched": True},
                    }
                ),
                connection_pool=pool,
            )
    
        assert exc.raised.status_code == 404
        assert "Task not found" in str(exc.raised.detail)

    Copy link
    Contributor

    qodo-merge-pro-for-open-source bot commented Dec 28, 2024

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Properly close database connections to prevent resource leaks

    Close the database connection pool after test execution to prevent connection leaks.

    agents-api/tests/test_task_queries.py [159-169]

     pool = await create_db_pool(dsn=dsn)
    -result = await list_tasks(
    -    developer_id=developer_id,
    -    agent_id=agent.id,
    -    connection_pool=pool,
    -)
    +try:
    +    result = await list_tasks(
    +        developer_id=developer_id,
    +        agent_id=agent.id,
    +        connection_pool=pool,
    +    )
    +finally:
    +    await pool.close()
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: Database connection leaks can cause serious performance issues and resource exhaustion. This suggestion fixes a critical resource management issue.

    9
    Ensure proper cleanup of database connection pools to prevent resource leaks

    Close the database connection pool after each test to prevent resource leaks. Add
    cleanup code using ward's teardown mechanism or async context managers.

    agents-api/tests/test_execution_workflow.py [39-40]

    -pool = await create_db_pool(dsn=dsn)
    -data = CreateExecutionRequest(input={"test": "input"})
    +async with await create_db_pool(dsn=dsn) as pool:
    +    data = CreateExecutionRequest(input={"test": "input"})
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: Unclosed database connection pools can lead to resource leaks and performance issues. Using async context managers ensures proper cleanup, making this a critical improvement for test reliability.

    8
    Include available tools information in the system prompt template to ensure the model is aware of its capabilities

    The system template should include a section for tools in the prompt, as tools are
    an important part of agent capabilities. Currently the template includes sections
    for agent info, user info, situation, instructions and docs, but omits tools.

    agents-api/agents_api/autogen/Sessions.py [34]

    -system_template: str = '{%- if agent.name -%}\nYou are {{agent.name}}.{{" "}}\n{%- endif -%}\n\n{%- if agent.about -%}\nAbout you: {{agent.about}}.{{" "}}\n{%- endif -%}\n\n{%- if user -%}\nYou are talking to a user\n  {%- if user.name -%}{{" "}} and their name is {{user.name}}\n    {%- if user.about -%}. About the user: {{user.about}}.{%- else -%}.{%- endif -%}\n  {%- endif -%}\n{%- endif -%}\n\n{{NEWLINE}}\n\n{%- if session.situation -%}\nSituation: {{session.situation}}\n{%- endif -%}\n\n{{NEWLINE+NEWLINE}}\n\n{%- if agent.instructions -%}\nInstructions:{{NEWLINE}}\n  {%- if agent.instructions is string -%}\n    {{agent.instructions}}{{NEWLINE}}\n  {%- else -%}\n    {%- for instruction in agent.instructions -%}\n      - {{instruction}}{{NEWLINE}}\n    {%- endfor -%}\n  {%- endif -%}\n  {{NEWLINE}}\n{%- endif -%}\n\n{%- if docs -%}\nRelevant documents:{{NEWLINE}}\n  {%- for doc in docs -%}\n    {{doc.title}}{{NEWLINE}}\n    {%- if doc.content is string -%}\n      {{doc.content}}{{NEWLINE}}\n    {%- else -%}\n      {%- for snippet in doc.content -%}\n        {{snippet}}{{NEWLINE}}\n      {%- endfor -%}\n    {%- endif -%}\n    {{"---"}}\n  {%- endfor -%}\n{%- endif -%}'
    +system_template: str = '{%- if agent.name -%}\nYou are {{agent.name}}.{{" "}}\n{%- endif -%}\n\n{%- if agent.about -%}\nAbout you: {{agent.about}}.{{" "}}\n{%- endif -%}\n\n{%- if user -%}\nYou are talking to a user\n  {%- if user.name -%}{{" "}} and their name is {{user.name}}\n    {%- if user.about -%}. About the user: {{user.about}}.{%- else -%}.{%- endif -%}\n  {%- endif -%}\n{%- endif -%}\n\n{{NEWLINE}}\n\n{%- if session.situation -%}\nSituation: {{session.situation}}\n{%- endif -%}\n\n{{NEWLINE+NEWLINE}}\n\n{%- if agent.instructions -%}\nInstructions:{{NEWLINE}}\n  {%- if agent.instructions is string -%}\n    {{agent.instructions}}{{NEWLINE}}\n  {%- else -%}\n    {%- for instruction in agent.instructions -%}\n      - {{instruction}}{{NEWLINE}}\n    {%- endfor -%}\n  {%- endif -%}\n  {{NEWLINE}}\n{%- endif -%}\n\n{%- if tools -%}\nTools:{{NEWLINE}}\n  {%- for tool in tools -%}\n    - {{tool.name + NEWLINE}}\n    {%- if tool.description -%}: {{tool.description + NEWLINE}}{%- endif -%}\n  {%- endfor -%}\n{{NEWLINE+NEWLINE}}\n{%- endif -%}\n\n{%- if docs -%}\nRelevant documents:{{NEWLINE}}\n  {%- for doc in docs -%}\n    {{doc.title}}{{NEWLINE}}\n    {%- if doc.content is string -%}\n      {{doc.content}}{{NEWLINE}}\n    {%- else -%}\n      {%- for snippet in doc.content -%}\n        {{snippet}}{{NEWLINE}}\n      {%- endfor -%}\n    {%- endif -%}\n    {{"---"}}\n  {%- endfor -%}\n{%- endif -%}'
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion identifies a critical omission in the system template - the tools section was removed in the PR but is essential for the agent to know what tools it can use, especially given the new forward_tool_calls feature.

    8
    General
    Implement proper test cleanup to prevent test data accumulation in the database

    Add cleanup of created test resources in the database after test execution to
    prevent test data accumulation and potential interference between test runs.

    agents-api/tests/test_task_queries.py [25-41]

     @test("query: create task sql")
     async def _(dsn=pg_dsn, developer_id=test_developer_id, agent=test_agent):
         pool = await create_db_pool(dsn=dsn)
    -    await create_task(
    +    task = await create_task(
             developer_id=developer_id,
             agent_id=agent.id,
             task_id=uuid7(),
             data=CreateTaskRequest(
                 name="test task",
                 description="test task about",
                 input_schema={"type": "object", "additionalProperties": True},
                 main=[{"evaluate": {"hi": "_"}}],
             ),
             connection_pool=pool,
         )
    +    try:
    +        yield
    +    finally:
    +        await delete_task(developer_id=developer_id, task_id=task.id, connection_pool=pool)
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion addresses an important issue of test data cleanup that could lead to database pollution and test interference. Proper cleanup is crucial for test isolation and reliability.

    8
    Add proper error handling for database operations to improve test reliability

    Add error handling around database operations to properly handle connection failures
    and other database-related exceptions.

    agents-api/tests/test_execution_workflow.py [42-45]

    -task = await create_task(
    -    developer_id=developer_id,
    -    agent_id=agent.id,
    -    data=CreateTaskRequest(
    +try:
    +    task = await create_task(
    +        developer_id=developer_id,
    +        agent_id=agent.id,
    +        data=CreateTaskRequest(
    +except Exception as e:
    +    raise RuntimeError(f"Failed to create task: {e}")
    • Apply this suggestion
    Suggestion importance[1-10]: 5

    Why: While error handling is important, in test code the default exception propagation might be sufficient as test failures should be visible. The suggestion provides moderate value for debugging failed tests.

    5
    Security
    Validate metadata content and size before database operations

    Add validation for the session metadata to ensure it doesn't exceed database size
    limits and contains valid JSON.

    agents-api/tests/test_session_queries.py [214-222]

    -data = PatchSessionRequest(
    -    metadata={"test": "metadata"},
    -)
    +metadata = {"test": "metadata"}
    +if len(str(metadata)) > 8192:  # Example size limit
    +    raise ValueError("Session metadata exceeds size limit")
    +try:
    +    json.dumps(metadata)  # Validate JSON
    +except (TypeError, ValueError) as e:
    +    raise ValueError(f"Invalid JSON in metadata: {str(e)}")
    +
    +data = PatchSessionRequest(metadata=metadata)
     result = await patch_session(
         developer_id=developer_id,
         session_id=session.id,
         data=data,
         connection_pool=pool,
     )
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: The suggestion adds important validation to prevent database errors from oversized or malformed metadata, improving application robustness and security.

    7

    @HamadaSalhab HamadaSalhab changed the base branch from dev to f/switch-to-pg December 28, 2024 00:30
    @creatorrr creatorrr merged commit a5f00b1 into f/switch-to-pg Dec 31, 2024
    8 of 13 checks passed
    @creatorrr creatorrr deleted the x/misc-session-fixes branch December 31, 2024 09:35
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    2 participants