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

dev -> main #1040

Merged
merged 423 commits into from
Jan 11, 2025
Merged

dev -> main #1040

merged 423 commits into from
Jan 11, 2025

Conversation

creatorrr
Copy link
Contributor

@creatorrr creatorrr commented Jan 11, 2025

PR Type

Enhancement, Tests


Description

  • Added a comprehensive Jupyter Notebook for the "Companion AI" project, including tasks for storyline generation, session updates, and user persona management.

  • Enhanced session and task models with new fields, improved documentation, and refactored logic for better modularity and readability.

  • Introduced safe utility functions for JSON, YAML, and Base64 operations with security limits.

  • Refactored and optimized task execution workflows, error handling, and validation logic across multiple modules.

  • Added and refactored extensive test cases for session, task, document, file, and developer queries, improving test coverage and migrating to async database connections.

  • Deleted outdated notebooks and redundant model files to streamline the codebase.


Changes walkthrough 📝

Relevant files
Enhancement
13 files
09_companion_agent.ipynb
Added Companion AI Notebook with tasks and examples.         

cookbooks/09_companion_agent.ipynb

  • Added a comprehensive Jupyter Notebook for the "Companion AI" project.
  • Introduced tasks for storyline generation, session updates, and user
    persona management.
  • Included detailed markdown documentation and Python code for API
    interactions.
  • Provided examples of task execution and monitoring outputs.
  • +1523/-0
    04-hook-generator-trending-reels.py
    Refactored Hook Generator Script for readability.               

    cookbooks/04-hook-generator-trending-reels.py

  • Refactored code for better readability and consistency in formatting.
  • Updated hooks data structure with improved indentation and formatting.
  • Simplified task and execution creation logic.
  • Enhanced JSON response handling and output formatting.
  • +228/-213
    Sessions.py
    Enhanced session models with new fields and refactoring. 

    agents-api/agents_api/autogen/Sessions.py

  • Introduced system_template field for session-related models.
  • Added forward_tool_calls field for enhanced tool call handling.
  • Refactored session situation logic for better modularity.
  • Improved type annotations and documentation for session models.
  • +50/-10 
    base_evaluate.py
    Refactored base evaluation logic and error handling.         

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

  • Refactored error handling and logging for evaluation errors.
  • Removed redundant code and improved function annotations.
  • Simplified lambda validation and evaluation logic.
  • Marked base_evaluate as an activity definition.
  • +13/-34 
    for_each_step.py
    Simplified and annotated for_each_step activity.                 

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

  • Marked for_each_step as an activity definition.
  • Removed unused imports and redundant decorators.
  • +1/-12   
    Sessions.py
    Enhance session model with system template and tool forwarding.

    integrations-service/integrations/autogen/Sessions.py

  • Added system_template field to replace situation for session context.
  • Introduced forward_tool_calls field to control tool call forwarding.
  • Updated docstrings for better clarity and consistency.
  • +50/-10 
    utils.py
    Add safe utility functions with security limits.                 

    agents-api/agents_api/activities/utils.py

  • Introduced safe utility functions for JSON, YAML, and Base64
    operations.
  • Added security limits for string length, collection size, and range
    size.
  • Updated ALLOWED_FUNCTIONS and stdlib with safe operations.
  • Removed unused or unsafe standard library imports.
  • +286/-97
    __init__.py
    Refactor and optimize task execution workflow logic.         

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

  • Removed unused imports and streamlined function parameters.
  • Added validation for execution_input.task to ensure it is not None.
  • Replaced repetitive exception handling with consistent error message
    formatting.
  • Removed redundant code and optimized logic for handling transitions
    and outcomes.
  • +71/-106
    Tasks.py
    Add canonical name and improve task model documentation. 

    agents-api/agents_api/autogen/Tasks.py

  • Added canonical_name field with validation to task-related models.
  • Improved documentation for task model fields.
  • Refactored redundant code for better readability.
  • +91/-74 
    Tasks.py
    Add canonical name and improve task model documentation. 

    integrations-service/integrations/autogen/Tasks.py

  • Added canonical_name field with validation to task-related models.
  • Improved documentation for task model fields.
  • Refactored redundant code for better readability.
  • +91/-74 
    openapi_model.py
    Refactor and enhance validation in openapi models.             

    agents-api/agents_api/autogen/openapi_model.py

  • Improved error handling with consistent message formatting.
  • Removed unused imports and redundant code.
  • Enhanced validation logic for Python expressions and Jinja templates.
  • +48/-56 
    utils.py
    Add PostgreSQL query utilities and concurrent execution support.

    agents-api/agents_api/queries/utils.py

  • Added utility functions for preparing and executing PostgreSQL
    queries.
  • Introduced decorators for exception handling and data transformation.
  • Implemented concurrent execution support for query functions.
  • +301/-0 
    execute_system.py
    Simplify and enhance system execution logic.                         

    agents-api/agents_api/activities/execute_system.py

  • Removed redundant imports and unused process pool executor.
  • Simplified handler execution logic by removing unnecessary async
    checks.
  • Added connection pool support for database queries.
  • Improved error handling and logging for system execution.
  • +30/-72 
    Tests
    9 files
    test_execution_workflow.py
    Refactor test execution workflow to use connection pools.

    agents-api/tests/test_execution_workflow.py

  • Replaced client with connection_pool for database interactions.
  • Updated test fixtures to include _s3_client for potential blob store
    usage.
  • Simplified task creation by removing redundant dictionary unpacking.
  • Enhanced test cases with improved database connection handling.
  • +485/-512
    fixtures.py
    Refactor test fixtures to support PostgreSQL and S3.         

    agents-api/tests/fixtures.py

  • Replaced Cozo database client with PostgreSQL connection pool.
  • Added new fixtures for PostgreSQL DSN and random email generation.
  • Refactored test fixtures to use async database operations.
  • Improved test setup for S3 client using localstack.
  • +243/-287
    test_session_queries.py
    Add and refactor tests for session query functions.           

    agents-api/tests/test_session_queries.py

  • Added comprehensive tests for session query functions.
  • Refactored tests to use PostgreSQL connection pool.
  • Improved test coverage for session creation, update, and deletion.
  • Introduced exception handling for non-existent sessions.
  • +188/-101
    test_task_queries.py
    Add and refactor task query tests with async DB support. 

    agents-api/tests/test_task_queries.py

  • Migrated tests to use async database connections via create_db_pool.
  • Added new tests for patch_task, delete_task, and list_tasks with
    filters.
  • Improved test coverage for task-related SQL queries.
  • Replaced deprecated UUID generation with uuid7.
  • +258/-97
    test_docs_queries.py
    Enhance document query tests with async DB and search.     

    agents-api/tests/test_docs_queries.py

  • Added tests for creating, listing, and deleting user and agent
    documents.
  • Introduced hybrid and embedding-based document search tests.
  • Migrated tests to use async database connections via create_db_pool.
  • Improved test coverage for document-related SQL queries.
  • +247/-104
    test_task_routes.py
    Extend task route tests with execution transitions.           

    agents-api/tests/test_task_routes.py

  • Added tests for listing and retrieving execution transitions.
  • Improved test coverage for task execution routes.
  • Skipped failing test due to temporal connection issue.
  • +149/-71
    test_files_queries.py
    Add and refactor file query tests with async DB.                 

    agents-api/tests/test_files_queries.py

  • Added tests for creating, listing, and deleting user and agent files.
  • Migrated tests to use async database connections via create_db_pool.
  • Improved test coverage for file-related SQL queries.
  • +226/-32
    test_agent_queries.py
    Refactor and extend agent query tests with async DB.         

    agents-api/tests/test_agent_queries.py

  • Migrated agent query tests to async database connections.
  • Added tests for patch_agent and delete_agent queries.
  • Improved test coverage for agent-related SQL queries.
  • +99/-93 
    test_developer_queries.py
    Add and refactor developer query tests with async DB.       

    agents-api/tests/test_developer_queries.py

  • Added tests for creating, updating, and patching developers.
  • Migrated tests to use async database connections via create_db_pool.
  • Improved test coverage for developer-related SQL queries.
  • +79/-23 
    Miscellaneous
    1 files
    __init__.py
    Refactor router import alias for clarity.                               

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

    • Updated import alias for router to improve clarity.
    +1/-1     
    Additional files
    101 files
    .env.example +1/-2     
    lint-agents-api-pr.yml +5/-0     
    test-agents-api-pr.yml +5/-0     
    typecheck-agents-api-pr.yml +5/-0     
    Dockerfile +1/-1     
    Dockerfile.migration +0/-22   
    Dockerfile.worker +1/-1     
    demo.py +3/-4     
    embed_docs.py +0/-75   
    excecute_api_call.py +8/-10   
    execute_integration.py +24/-18 
    mem_mgmt.py +0/-192 
    mem_rating.py +0/-100 
    summarization.py +0/-86   
    sync_items_remote.py +4/-8     
    __init__.py +1/-1     
    cozo_query_step.py +0/-30   
    evaluate_step.py +4/-21   
    get_value_step.py +5/-14   
    if_else_step.py +2/-14   
    log_step.py +3/-13   
    map_reduce_step.py +1/-12   
    pg_query_step.py +22/-0   
    prompt_step.py +18/-27 
    raise_complete_async.py +0/-2     
    return_step.py +2/-14   
    set_value_step.py +4/-16   
    switch_step.py +2/-12   
    tool_call_step.py +3/-6     
    transition_step.py +14/-32 
    wait_for_input_step.py +2/-12   
    yield_step.py +16/-18 
    truncation.py +0/-60   
    types.py +0/-36   
    app.py +121/-0 
    Agents.py +40/-35 
    Chat.py +13/-21 
    Docs.py +20/-2   
    Entries.py +2/-1     
    Executions.py +1/-3     
    Tools.py +8/-18   
    __init__.py +1/-4     
    async_s3.py +44/-74 
    cozo.py +0/-29   
    integrations.py +2/-2     
    litellm.py +33/-41 
    pg.py +20/-0   
    temporal.py +27/-13 
    __init__.py +0/-3     
    types.py +0/-41   
    worker.py +0/-21   
    agents.py +3/-9     
    sessions.py +1/-3     
    tools.py +0/-2     
    users.py +2/-6     
    interceptors.py +115/-75
    nlp.py +2/-4     
    remote.py +20/-77 
    sessions.py +10/-15 
    state_machine.py +206/-0 
    tasks.py +20/-37 
    storage_handler.py +0/-226 
    __init__.py +1/-1     
    cozo.py +0/-26   
    datetime.py +2/-2     
    db_exceptions.py +192/-0 
    debug.py +0/-23   
    template.py +4/-15   
    types.py +5/-13   
    auth.py +2/-5     
    content_length.py +7/-0     
    developer_id.py +12/-14 
    query_filter.py +3/-4     
    env.py +41/-44 
    exceptions.py +9/-0     
    counters.py +112/-76
    model_registry.py +11/-13 
    __init__.py +0/-20   
    __init__.py +0/-22   
    create_agent.py +0/-147 
    create_or_update_agent.py +0/-186 
    delete_agent.py +0/-134 
    get_agent.py +0/-117 
    list_agents.py +0/-122 
    patch_agent.py +0/-132 
    update_agent.py +0/-149 
    gather_messages.py +0/-214 
    get_cached_response.py +0/-15   
    prepare_chat_context.py +0/-144 
    set_cached_response.py +0/-19   
    get_developer.py +0/-74   
    create_doc.py +0/-140 
    delete_doc.py +0/-102 
    embed_snippets.py +0/-102 
    get_doc.py +0/-103 
    list_docs.py +0/-141 
    search_docs_by_embedding.py +0/-372 
    search_docs_by_text.py +0/-209 
    search_docs_hybrid.py +0/-138 
    __init__.py +0/-19   
    Additional files not shown

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

    Vedantsahai18 and others added 23 commits January 8, 2025 15:27
    feat(llm-proxy): Add support for O1 & other LLMs
    X/openai embed: Changed embedding from Voyage to OpenAI
    fix: Add safety clause to text seaerch altering query
    fix(memory-store, agents-api): Fix distance and confidence values for vector search
    hotfix(agents-api): Fixes for connection pool getting exhausted
    Signed-off-by: Diwank Singh Tomer <[email protected]>
    fix(memory-store): Remove bad indices
    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

    Error Handling

    The error handling in execute_system() could be improved. Currently it catches all BaseException which is too broad and could mask important errors. Consider catching specific exceptions and handling them appropriately.

    except BaseException as e:
        if activity.in_activity():
            activity.logger.error(f"Error in execute_system_call: {e}")
    Resource Cleanup

    The connection pool is passed to handlers but there's no explicit cleanup or closing of connections. Consider implementing proper connection handling and cleanup.

    connection_pool = getattr(app.state, "postgres_pool", None)

    Copy link

    gitguardian bot commented Jan 11, 2025

    ⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

    Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

    🔎 Detected hardcoded secret in your pull request
    GitGuardian id GitGuardian status Secret Commit Filename
    14144715 Triggered Generic Password ad24128 memory-store/docker-compose.yml View secret
    🛠 Guidelines to remediate hardcoded secrets
    1. Understand the implications of revoking this secret by investigating where it is used in your code.
    2. Replace and store your secret safely. Learn here the best practices.
    3. Revoke and rotate this secret.
    4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

    To avoid such incidents in the future consider


    🦉 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 Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Missing mock setup for integration service in test case could lead to test failures

    The test for the weather integration tool is marked as skipped in the old code but
    not in the new code, yet the integration service mock setup is missing. Add proper
    mocking setup for the integration service to ensure the test works correctly.

    agents-api/tests/test_execution_workflow.py [696-702]

     @test("workflow: tool call integration mocked weather")
     async def _(
         dsn=pg_dsn,
         developer_id=test_developer_id,
         agent=test_agent,
         _s3_client=s3_client,  # Adding coz blob store might be used
     ):
    +    with patch_integration_service(return_value={"temperature": 20, "humidity": 60}) as mock_integration_service:
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion correctly identifies a critical issue where the test would fail without proper mocking of the integration service. The mock setup is essential for testing the weather integration functionality in isolation.

    8
    Add validation for required environment variables to fail fast if they are missing

    Add error handling for the API key environment variables to ensure they are not None
    before proceeding with API calls.

    cookbooks/04-hook-generator-trending-reels.py [14-16]

     RAPID_API_KEY = os.getenv("RAPID_API_KEY")
    +if not RAPID_API_KEY:
    +    raise ValueError("RAPID_API_KEY environment variable is not set")
     RAPID_API_HOST = os.getenv("RAPID_API_HOST")
    +if not RAPID_API_HOST:
    +    raise ValueError("RAPID_API_HOST environment variable is not set")
     JULEP_API_KEY = os.getenv("JULEP_API_KEY") or os.getenv("JULEP_API_KEY_LOCAL")
    +if not JULEP_API_KEY:
    +    raise ValueError("Neither JULEP_API_KEY nor JULEP_API_KEY_LOCAL environment variables are set")
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion adds critical error handling for required API keys, which would prevent runtime errors and provide clear error messages when environment variables are missing.

    8
    Improve API response field access with safer default values to prevent potential division by zero errors

    Add error handling around the API response parsing to handle cases where expected
    fields are missing.

    cookbooks/04-hook-generator-trending-reels.py [306-307]

    -'virality_score': (((response.get('reshare_count') or 0) / (response.get('play_count') or 1)) if (response.get('play_count') or 0) > 0 else 0),
    -'engagement_score': (((response.get('like_count') or 0) / (response.get('play_count') or 1)) if (response.get('play_count') or 0) > 0 else 0),
    +'virality_score': (((response.get('reshare_count', 0) or 0) / (response.get('play_count', 1) or 1)) if (response.get('play_count', 0) or 0) > 0 else 0),
    +'engagement_score': (((response.get('like_count', 0) or 0) / (response.get('play_count', 1) or 1)) if (response.get('play_count', 0) or 0) > 0 else 0),
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: The suggestion improves robustness of API response handling by providing safer default values in the get() method, reducing the risk of division by zero errors.

    7
    General
    Add input validation to prevent processing of invalid or malformed data

    Add input validation to ensure that the session_id and user_input parameters are not
    empty or malformed before processing them in the task execution.

    cookbooks/09_companion_agent.ipynb [797-803]

    +# Validate inputs
    +if not SESSION_ID or not isinstance(SESSION_ID, str):
    +    raise ValueError("Invalid session_id")
    +user_input = "I'm not really sure. What kind of clubs are you into?"
    +if not user_input or not isinstance(user_input, str):
    +    raise ValueError("Invalid user_input")
    +    
     execution_2 = client.executions.create(
         task_id=TASK_UUID_2,
         input={
           "session_id": str(SESSION_ID),
    -      "user_input": "I'm not really sure. What kind of clubs are you into?",
    +      "user_input": user_input,
         }
     )
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Adding input validation is important for robustness and error prevention, helping catch potential issues early before they cause runtime errors. The suggestion provides clear validation checks for both session_id and user_input parameters.

    7

    Copy link
    Contributor

    CI Failure Feedback 🧐

    Action: Test

    Failed stage: Run tests [❌]

    Failed test name: test_agent_routes

    Failure summary:

    The action failed due to a database connection pool configuration error. Specifically, the min_size
    (10) was set larger than the max_size (4) in the AsyncPG connection pool initialization, which is
    invalid. This caused the test fixtures to fail when trying to establish database connections,
    affecting multiple test cases:

  • test_agent_routes:9 route: unauthorized should fail
  • test_agent_routes:26 route: create agent
  • test_agent_routes:43 route: create agent with instructions

  • Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    1332:  PASS  test_agent_queries:28 query: create agent sql                          1%
    1333:  PASS  test_agent_queries:44 query: create or update agent sql                2%
    1334:  PASS  test_agent_queries:63 query: update agent sql                          2%
    1335:  PASS  test_agent_queries:85 query: get agent not exists sql                  3%
    1336:  PASS  test_agent_queries:96 query: get agent exists sql                      3%
    1337:  PASS  test_agent_queries:111 query: list agents sql                          4%
    1338:  PASS  test_agent_queries:122 query: patch agent sql                          4%
    1339:  PASS  test_agent_queries:143 query: delete agent sql                         5%
    1340:  FAIL  test_agent_routes:9 route: unauthorized should fail                    6%
    1341:  FAIL  test_agent_routes:26 route: create agent                               6%
    1342:  FAIL  test_agent_routes:43 route: create agent with instructions             7%
    1343:  ─────────────────────── route: unauthorized should fail ────────────────────────
    1344:  Failed at tests/test_agent_routes.py                                          
    ...
    
    1465:  │ │              name = '_dsn'                                           │ │  
    1466:  │ │              self = TestArgumentResolver(                            │ │  
    1467:  │ │                     │   test=Test(                                   │ │  
    1468:  │ │                     │   │   fn=<function _ at 0x7f4a51b5d440>,       │ │  
    1469:  │ │                     │   │   module_name='test_agent_routes',         │ │  
    1470:  │ │                     │   │   id='2dd8266b4a754053bd5c1118da08bed7',   │ │  
    1471:  │ │                     │   │   marker=None,                             │ │  
    1472:  │ │                     │   │   description='route: unauthorized should  │ │  
    1473:  │ │                     fail',                                           │ │  
    ...
    
    1592:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    1593:  │ │        0x7f4a50558050>                                               │ │  
    1594:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1595:  │                                                                          │  
    1596:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    1597:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    1598:  │                                                                          │  
    1599:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    1600:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    1601:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    1602:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    1603:  │   457 │   │   │   │   else:                                              │  
    1604:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    1636:  │   221 │   │   except self._cancelled_exc_class:                          │  
    1637:  │                                                                          │  
    1638:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1639:  │ │                args = ()                                             │ │  
    1640:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    1641:  │ │                       <starlette.testclient.TestClient object at     │ │  
    1642:  │ │                       0x7f4a50546fc0>>                               │ │  
    1643:  │ │              future = <Future at 0x7f4a51bd4f50 state=finished       │ │  
    1644:  │ │                       raised ValueError>                             │ │  
    ...
    
    1648:  │ │               scope = None                                           │ │  
    1649:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    1650:  │ │                       object at 0x7f4a50558050>                      │ │  
    1651:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1652:  │                                                                          │  
    1653:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    1654:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    1655:  │                                                                          │  
    1656:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    1657:  │   772 │   │   )                                                          │  
    1658:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    1659:  │ ❱ 774 │   │   │   await receive()                                        │  
    1660:  │   775 │                                                                  │  
    1661:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    1662:  │   777 │   │   async def receive() -> typing.Any:                         │  
    1663:  │                                                                          │  
    1664:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1665:  │ │ message = {                                                          │ │  
    1666:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    1685:  │ │ message = None                                                       │ │  
    1686:  │ │    self = <starlette.testclient.TestClient object at 0x7f4a50546fc0> │ │  
    1687:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1688:  │                                                                          │  
    1689:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    1690:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    1691:  │                                                                          │  
    1692:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    1693:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    1729:  │   221 │   │   except self._cancelled_exc_class:                          │  
    1730:  │                                                                          │  
    1731:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1732:  │ │                args = ()                                             │ │  
    1733:  │ │                func = <bound method TestClient.lifespan of           │ │  
    1734:  │ │                       <starlette.testclient.TestClient object at     │ │  
    1735:  │ │                       0x7f4a50546fc0>>                               │ │  
    1736:  │ │              future = <Future at 0x7f4a50558e30 state=finished       │ │  
    1737:  │ │                       raised ValueError>                             │ │  
    ...
    
    1844:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    1845:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    1846:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    1847:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    1848:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    1849:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1850:  │                                                                          │  
    1851:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    1852:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    1872:  │ │   scope = {                                                          │ │  
    1873:  │ │           │   'type': 'lifespan',                                    │ │  
    1874:  │ │           │   'state': {},                                           │ │  
    1875:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    1876:  │ │           0x7f4a53280170>,                                           │ │  
    1877:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    1878:  │ │           0x7f4a53d94500>                                            │ │  
    1879:  │ │           }                                                          │ │  
    1880:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    2102:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    2103:  │                                                                          │  
    2104:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    2105:  │   691 │   │   await receive()                                            │  
    2106:  │   692 │   │   try:                                                       │  
    2107:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    2108:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    2109:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    2110:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    2146:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2147:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2148:  │                                                                          │  
    2149:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2150:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2151:  │   209 │   │   try:                                                       │  
    2152:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2153:  │   211 │   │   except StopAsyncIteration:                                 │  
    2154:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2180:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2181:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2182:  │                                                                          │  
    2183:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2184:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2185:  │   209 │   │   try:                                                       │  
    2186:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2187:  │   211 │   │   except StopAsyncIteration:                                 │  
    2188:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2214:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2215:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2216:  │                                                                          │  
    2217:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2218:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2219:  │   209 │   │   try:                                                       │  
    2220:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2221:  │   211 │   │   except StopAsyncIteration:                                 │  
    2222:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2248:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2249:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2250:  │                                                                          │  
    2251:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2252:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2253:  │   209 │   │   try:                                                       │  
    2254:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2255:  │   211 │   │   except StopAsyncIteration:                                 │  
    2256:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2282:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2283:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2284:  │                                                                          │  
    2285:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2286:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2287:  │   209 │   │   try:                                                       │  
    2288:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2289:  │   211 │   │   except StopAsyncIteration:                                 │  
    2290:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2316:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2317:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2318:  │                                                                          │  
    2319:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2320:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2321:  │   209 │   │   try:                                                       │  
    2322:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2323:  │   211 │   │   except StopAsyncIteration:                                 │  
    2324:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2350:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2351:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2352:  │                                                                          │  
    2353:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2354:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2355:  │   209 │   │   try:                                                       │  
    2356:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2357:  │   211 │   │   except StopAsyncIteration:                                 │  
    2358:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2384:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2385:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2386:  │                                                                          │  
    2387:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2388:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2389:  │   209 │   │   try:                                                       │  
    2390:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2391:  │   211 │   │   except StopAsyncIteration:                                 │  
    2392:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2418:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2419:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2420:  │                                                                          │  
    2421:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2422:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2423:  │   209 │   │   try:                                                       │  
    2424:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2425:  │   211 │   │   except StopAsyncIteration:                                 │  
    2426:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2452:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2453:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2454:  │                                                                          │  
    2455:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2456:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2457:  │   209 │   │   try:                                                       │  
    2458:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2459:  │   211 │   │   except StopAsyncIteration:                                 │  
    2460:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2486:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2487:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2488:  │                                                                          │  
    2489:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2490:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2491:  │   209 │   │   try:                                                       │  
    2492:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2493:  │   211 │   │   except StopAsyncIteration:                                 │  
    2494:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2557:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2558:  │                                                                          │  
    2559:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    2560:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    2561:  │                                                                          │  
    2562:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    2563:  │    359 │   │                                                             │  
    2564:  │    360 │   │   if min_size > max_size:                                   │  
    2565:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    2566:  │    362 │   │                                                             │  
    2567:  │    363 │   │   if max_queries <= 0:                                      │  
    2568:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    2582:  │ │                        max_size = 4                                  │ │  
    2583:  │ │                        min_size = 10                                 │ │  
    2584:  │ │                           reset = None                               │ │  
    2585:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    2586:  │ │                                   0x7f4a50981fc0>                    │ │  
    2587:  │ │                           setup = None                               │ │  
    2588:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2589:  ╰──────────────────────────────────────────────────────────────────────────╯  
    2590:  ValueError: min_size is greater than max_size                                 
    ...
    
    2667:  │ │         │   }                                                        │ │  
    2668:  │ │         )                                                            │ │  
    2669:  │ │  self = TestArgumentResolver(                                        │ │  
    2670:  │ │         │   test=Test(                                               │ │  
    2671:  │ │         │   │   fn=<function _ at 0x7f4a51b5d440>,                   │ │  
    2672:  │ │         │   │   module_name='test_agent_routes',                     │ │  
    2673:  │ │         │   │   id='2dd8266b4a754053bd5c1118da08bed7',               │ │  
    2674:  │ │         │   │   marker=None,                                         │ │  
    2675:  │ │         │   │   description='route: unauthorized should fail',       │ │  
    ...
    
    2794:  │ │      resolved_args = {}                                              │ │  
    2795:  │ │               self = TestArgumentResolver(                           │ │  
    2796:  │ │                      │   test=Test(                                  │ │  
    2797:  │ │                      │   │   fn=<function _ at 0x7f4a51b5d440>,      │ │  
    2798:  │ │                      │   │   module_name='test_agent_routes',        │ │  
    2799:  │ │                      │   │   id='2dd8266b4a754053bd5c1118da08bed7',  │ │  
    2800:  │ │                      │   │   marker=None,                            │ │  
    2801:  │ │                      │   │   description='route: unauthorized should │ │  
    2802:  │ │                      fail',                                          │ │  
    ...
    
    2827:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2828:  │                                                                          │  
    2829:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    2830:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    2831:  │                                                                          │  
    2832:  │   634 │   │   │   else:                                                  │  
    2833:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    2834:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    2835:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    2948:  │ │              name = '_dsn'                                           │ │  
    2949:  │ │              self = TestArgumentResolver(                            │ │  
    2950:  │ │                     │   test=Test(                                   │ │  
    2951:  │ │                     │   │   fn=<function _ at 0x7f4a51b5d440>,       │ │  
    2952:  │ │                     │   │   module_name='test_agent_routes',         │ │  
    2953:  │ │                     │   │   id='2dd8266b4a754053bd5c1118da08bed7',   │ │  
    2954:  │ │                     │   │   marker=None,                             │ │  
    2955:  │ │                     │   │   description='route: unauthorized should  │ │  
    2956:  │ │                     fail',                                           │ │  
    ...
    
    2975:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    2976:  │ │                     0x7f4a51b8c800>,                                 │ │  
    2977:  │ │                     │   │   tags=[]                                  │ │  
    2978:  │ │                     │   ),                                           │ │  
    2979:  │ │                     │   iteration=0                                  │ │  
    2980:  │ │                     )                                                │ │  
    2981:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2982:  ╰──────────────────────────────────────────────────────────────────────────╯  
    2983:  FixtureError: Unable to resolve fixture 'client'                              
    2984:  ───────────────────────────── route: create agent ──────────────────────────────
    2985:  Failed at tests/test_agent_routes.py                                          
    ...
    
    3232:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    3233:  │ │        0x7f4a50547ef0>                                               │ │  
    3234:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3235:  │                                                                          │  
    3236:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3237:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    3238:  │                                                                          │  
    3239:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    3240:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    3241:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    3242:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    3243:  │   457 │   │   │   │   else:                                              │  
    3244:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    3276:  │   221 │   │   except self._cancelled_exc_class:                          │  
    3277:  │                                                                          │  
    3278:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3279:  │ │                args = ()                                             │ │  
    3280:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    3281:  │ │                       <starlette.testclient.TestClient object at     │ │  
    3282:  │ │                       0x7f4a50546b40>>                               │ │  
    3283:  │ │              future = <Future at 0x7f4a50546db0 state=finished       │ │  
    3284:  │ │                       raised ValueError>                             │ │  
    ...
    
    3288:  │ │               scope = None                                           │ │  
    3289:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    3290:  │ │                       object at 0x7f4a50547ef0>                      │ │  
    3291:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3292:  │                                                                          │  
    3293:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3294:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    3295:  │                                                                          │  
    3296:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    3297:  │   772 │   │   )                                                          │  
    3298:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    3299:  │ ❱ 774 │   │   │   await receive()                                        │  
    3300:  │   775 │                                                                  │  
    3301:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    3302:  │   777 │   │   async def receive() -> typing.Any:                         │  
    3303:  │                                                                          │  
    3304:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3305:  │ │ message = {                                                          │ │  
    3306:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    3325:  │ │ message = None                                                       │ │  
    3326:  │ │    self = <starlette.testclient.TestClient object at 0x7f4a50546b40> │ │  
    3327:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3328:  │                                                                          │  
    3329:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3330:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    3331:  │                                                                          │  
    3332:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    3333:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    3369:  │   221 │   │   except self._cancelled_exc_class:                          │  
    3370:  │                                                                          │  
    3371:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3372:  │ │                args = ()                                             │ │  
    3373:  │ │                func = <bound method TestClient.lifespan of           │ │  
    3374:  │ │                       <starlette.testclient.TestClient object at     │ │  
    3375:  │ │                       0x7f4a50546b40>>                               │ │  
    3376:  │ │              future = <Future at 0x7f4a505461e0 state=finished       │ │  
    3377:  │ │                       raised ValueError>                             │ │  
    ...
    
    3484:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    3485:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    3486:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    3487:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    3488:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    3489:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3490:  │                                                                          │  
    3491:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3492:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    3512:  │ │   scope = {                                                          │ │  
    3513:  │ │           │   'type': 'lifespan',                                    │ │  
    3514:  │ │           │   'state': {},                                           │ │  
    3515:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    3516:  │ │           0x7f4a53280170>,                                           │ │  
    3517:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    3518:  │ │           0x7f4a53d94500>                                            │ │  
    3519:  │ │           }                                                          │ │  
    3520:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    3742:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    3743:  │                                                                          │  
    3744:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    3745:  │   691 │   │   await receive()                                            │  
    3746:  │   692 │   │   try:                                                       │  
    3747:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    3748:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    3749:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    3750:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    3786:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3787:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3788:  │                                                                          │  
    3789:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3790:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3791:  │   209 │   │   try:                                                       │  
    3792:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3793:  │   211 │   │   except StopAsyncIteration:                                 │  
    3794:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3820:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3821:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3822:  │                                                                          │  
    3823:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3824:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3825:  │   209 │   │   try:                                                       │  
    3826:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3827:  │   211 │   │   except StopAsyncIteration:                                 │  
    3828:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3854:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3855:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3856:  │                                                                          │  
    3857:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3858:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3859:  │   209 │   │   try:                                                       │  
    3860:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3861:  │   211 │   │   except StopAsyncIteration:                                 │  
    3862:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3888:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3889:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3890:  │                                                                          │  
    3891:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3892:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3893:  │   209 │   │   try:                                                       │  
    3894:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3895:  │   211 │   │   except StopAsyncIteration:                                 │  
    3896:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3922:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3923:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3924:  │                                                                          │  
    3925:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3926:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3927:  │   209 │   │   try:                                                       │  
    3928:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3929:  │   211 │   │   except StopAsyncIteration:                                 │  
    3930:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3956:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3957:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3958:  │                                                                          │  
    3959:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3960:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3961:  │   209 │   │   try:                                                       │  
    3962:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3963:  │   211 │   │   except StopAsyncIteration:                                 │  
    3964:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3990:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3991:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3992:  │                                                                          │  
    3993:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3994:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3995:  │   209 │   │   try:                                                       │  
    3996:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3997:  │   211 │   │   except StopAsyncIteration:                                 │  
    3998:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4024:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4025:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4026:  │                                                                          │  
    4027:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4028:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4029:  │   209 │   │   try:                                                       │  
    4030:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4031:  │   211 │   │   except StopAsyncIteration:                                 │  
    4032:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4058:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4059:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4060:  │                                                                          │  
    4061:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4062:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4063:  │   209 │   │   try:                                                       │  
    4064:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4065:  │   211 │   │   except StopAsyncIteration:                                 │  
    4066:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4092:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4093:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4094:  │                                                                          │  
    4095:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4096:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4097:  │   209 │   │   try:                                                       │  
    4098:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4099:  │   211 │   │   except StopAsyncIteration:                                 │  
    4100:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4126:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4127:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4128:  │                                                                          │  
    4129:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4130:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4131:  │   209 │   │   try:                                                       │  
    4132:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4133:  │   211 │   │   except StopAsyncIteration:                                 │  
    4134:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4197:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4198:  │                                                                          │  
    4199:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    4200:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    4201:  │                                                                          │  
    4202:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    4203:  │    359 │   │                                                             │  
    4204:  │    360 │   │   if min_size > max_size:                                   │  
    4205:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    4206:  │    362 │   │                                                             │  
    4207:  │    363 │   │   if max_queries <= 0:                                      │  
    4208:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    4222:  │ │                        max_size = 4                                  │ │  
    4223:  │ │                        min_size = 10                                 │ │  
    4224:  │ │                           reset = None                               │ │  
    4225:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    4226:  │ │                                   0x7f4a50982b00>                    │ │  
    4227:  │ │                           setup = None                               │ │  
    4228:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4229:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4230:  ValueError: min_size is greater than max_size                                 
    ...
    
    4608:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4609:  │                                                                          │  
    4610:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    4611:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    4612:  │                                                                          │  
    4613:  │   634 │   │   │   else:                                                  │  
    4614:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    4615:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    4616:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    4755:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    4756:  │ │                     0x7f4a50547d70>,                                 │ │  
    4757:  │ │                     │   │   tags=[]                                  │ │  
    4758:  │ │                     │   ),                                           │ │  
    4759:  │ │                     │   iteration=0                                  │ │  
    4760:  │ │                     )                                                │ │  
    4761:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4762:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4763:  FixtureError: Unable to resolve fixture 'client'                              
    4764:  ──────────────────── route: create agent with instructions ─────────────────────
    4765:  Failed at tests/test_agent_routes.py                                          
    ...
    
    5013:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    5014:  │ │        0x7f4a505453a0>                                               │ │  
    5015:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5016:  │                                                                          │  
    5017:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5018:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    5019:  │                                                                          │  
    5020:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    5021:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    5022:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    5023:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    5024:  │   457 │   │   │   │   else:                                              │  
    5025:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    5057:  │   221 │   │   except self._cancelled_exc_class:                          │  
    5058:  │                                                                          │  
    5059:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5060:  │ │                args = ()                                             │ │  
    5061:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    5062:  │ │                       <starlette.testclient.TestClient object at     │ │  
    5063:  │ │                       0x7f4a505463f0>>                               │ │  
    5064:  │ │              future = <Future at 0x7f4a50544a10 state=finished       │ │  
    5065:  │ │                       raised ValueError>                             │ │  
    ...
    
    5069:  │ │               scope = None                                           │ │  
    5070:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    5071:  │ │                       object at 0x7f4a505453a0>                      │ │  
    5072:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5073:  │                                                                          │  
    5074:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5075:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    5076:  │                                                                          │  
    5077:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    5078:  │   772 │   │   )                                                          │  
    5079:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    5080:  │ ❱ 774 │   │   │   await receive()                                        │  
    5081:  │   775 │                                                                  │  
    5082:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    5083:  │   777 │   │   async def receive() -> typing.Any:                         │  
    5084:  │                                                                          │  
    5085:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5086:  │ │ message = {                                                          │ │  
    5087:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    5106:  │ │ message = None                                                       │ │  
    5107:  │ │    self = <starlette.testclient.TestClient object at 0x7f4a505463f0> │ │  
    5108:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5109:  │                                                                          │  
    5110:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5111:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    5112:  │                                                                          │  
    5113:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    5114:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    5150:  │   221 │   │   except self._cancelled_exc_class:                          │  
    5151:  │                                                                          │  
    5152:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5153:  │ │                args = ()                                             │ │  
    5154:  │ │                func = <bound method TestClient.lifespan of           │ │  
    5155:  │ │                       <starlette.testclient.TestClient object at     │ │  
    5156:  │ │                       0x7f4a505463f0>>                               │ │  
    5157:  │ │              future = <Future at 0x7f4a50544c50 state=finished       │ │  
    5158:  │ │                       raised ValueError>                             │ │  
    ...
    
    5265:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    5266:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    5267:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    5268:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    5269:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    5270:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5271:  │                                                                          │  
    5272:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5273:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    5293:  │ │   scope = {                                                          │ │  
    5294:  │ │           │   'type': 'lifespan',                                    │ │  
    5295:  │ │           │   'state': {},                                           │ │  
    5296:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    5297:  │ │           0x7f4a53280170>,                                           │ │  
    5298:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    5299:  │ │           0x7f4a53d94500>                                            │ │  
    5300:  │ │           }                                                          │ │  
    5301:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    5523:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    5524:  │                                                                          │  
    5525:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    5526:  │   691 │   │   await receive()                                            │  
    5527:  │   692 │   │   try:                                                       │  
    5528:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    5529:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    5530:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    5531:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    5567:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5568:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5569:  │                                                                          │  
    5570:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5571:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5572:  │   209 │   │   try:                                                       │  
    5573:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5574:  │   211 │   │   except StopAsyncIteration:                                 │  
    5575:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5601:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5602:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5603:  │                                                                          │  
    5604:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5605:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5606:  │   209 │   │   try:                                                       │  
    5607:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5608:  │   211 │   │   except StopAsyncIteration:                                 │  
    5609:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5635:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5636:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5637:  │                                                                          │  
    5638:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5639:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5640:  │   209 │   │   try:                                                       │  
    5641:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5642:  │   211 │   │   except StopAsyncIteration:                                 │  
    5643:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5669:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5670:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5671:  │                                                                          │  
    5672:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5673:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5674:  │   209 │   │   try:                                                       │  
    5675:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5676:  │   211 │   │   except StopAsyncIteration:                                 │  
    5677:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5703:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5704:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5705:  │                                                                          │  
    5706:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5707:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5708:  │   209 │   │   try:                                                       │  
    5709:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5710:  │   211 │   │   except StopAsyncIteration:                                 │  
    5711:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5737:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5738:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5739:  │                                                                          │  
    5740:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5741:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5742:  │   209 │   │   try:                                                       │  
    5743:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5744:  │   211 │   │   except StopAsyncIteration:                                 │  
    5745:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5771:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5772:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5773:  │                                                                          │  
    5774:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5775:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5776:  │   209 │   │   try:                                                       │  
    5777:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5778:  │   211 │   │   except StopAsyncIteration:                                 │  
    5779:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5805:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5806:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5807:  │                                                                          │  
    5808:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5809:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5810:  │   209 │   │   try:                                                       │  
    5811:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5812:  │   211 │   │   except StopAsyncIteration:                                 │  
    5813:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5839:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5840:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5841:  │                                                                          │  
    5842:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5843:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5844:  │   209 │   │   try:                                                       │  
    5845:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5846:  │   211 │   │   except StopAsyncIteration:                                 │  
    5847:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5873:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5874:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5875:  │                                                                          │  
    5876:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5877:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5878:  │   209 │   │   try:                                                       │  
    5879:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5880:  │   211 │   │   except StopAsyncIteration:                                 │  
    5881:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5907:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5908:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5909:  │                                                                          │  
    5910:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5911:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5912:  │   209 │   │   try:                                                       │  
    5913:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5914:  │   211 │   │   except StopAsyncIteration:                                 │  
    5915:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5978:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5979:  │                                                                          │  
    5980:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5981:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    5982:  │                                                                          │  
    5983:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    5984:  │    359 │   │                                                             │  
    5985:  │    360 │   │   if min_size > max_size:                                   │  
    5986:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    5987:  │    362 │   │                                                             │  
    5988:  │    363 │   │   if max_queries <= 0:                                      │  
    5989:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    6003:  │ │                        max_size = 4                                  │ │  
    6004:  │ │                        min_size = 10                                 │ │  
    6005:  │ │                           reset = None                               │ │  
    6006:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    6007:  │ │                                   0x7f4a50982380>                    │ │  
    6008:  │ │                           setup = None                               │ │  
    6009:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6010:  ╰──────────────────────────────────────────────────────────────────────────╯  
    6011:  ValueError: min_size is greater than max_size                                 
    ...
    
    6391:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6392:  │                                                                          │  
    6393:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    6394:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    6395:  │                                                                          │  
    6396:  │   634 │   │   │   else:                                                  │  
    6397:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    6398:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    6399:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    6539:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    6540:  │ │                     0x7f4a50547a10>,                                 │ │  
    6541:  │ │                     │   │   tags=[]                                  │ │  
    6542:  │ │                     │   ),                                           │ │  
    6543:  │ │                     │   iteration=0                                  │ │  
    6544:  │ │                     )                                                │ │  
    6545:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6546:  ╰──────────────────────────────────────────────────────────────────────────╯  
    6547:  FixtureError: Unable to resolve fixture 'client'                              
    6548:  ────────────────────────────────────────────────────────────────────────────────
    6549:  ╭──────────── Results ─────────────╮
    6550:  │  12  Tests Encountered           │
    6551:  │   9  Passes             (75.0%)  │
    6552:  │   3  Failures           (25.0%)  │
    6553:  ╰──────────────────────────────────╯
    6554:  ─────────────────────────── FAILED in 50.17 seconds ────────────────────────────
    6555:  ##[error]Process completed with exit code 1.
    

    ✨ CI feedback usage guide:

    The CI feedback tool (/checks) automatically triggers when a PR has a failed check.
    The tool analyzes the failed checks and provides several feedbacks:

    • Failed stage
    • Failed test name
    • Failure summary
    • Relevant error logs

    In addition to being automatically triggered, the tool can also be invoked manually by commenting on a PR:

    /checks "https://github.com/{repo_name}/actions/runs/{run_number}/job/{job_number}"
    

    where {repo_name} is the name of the repository, {run_number} is the run number of the failed check, and {job_number} is the job number of the failed check.

    Configuration options

    • enable_auto_checks_feedback - if set to true, the tool will automatically provide feedback when a check is faile...

    @whiterabbit1983 whiterabbit1983 merged commit 1be5357 into main Jan 11, 2025
    8 of 11 checks passed
    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.

    5 participants