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

X/misc fixes #1016

Merged
merged 6 commits into from
Jan 5, 2025
Merged

X/misc fixes #1016

merged 6 commits into from
Jan 5, 2025

Conversation

HamadaSalhab
Copy link
Contributor

@HamadaSalhab HamadaSalhab commented Jan 4, 2025

PR Type

Bug fix, Enhancement


Description

  • Fixed postgres_pool initialization to avoid redundant connections.

  • Standardized embedding naming across the codebase for consistency.

  • Updated entries table schema to use TIMESTAMPTZ for timestamp.

  • Improved error handling and robustness in database operations.


Changes walkthrough 📝

Relevant files
Enhancement
app.py
Refactor `postgres_pool` initialization in `lifespan`       

agents-api/agents_api/app.py

  • Introduced a global pool variable for shared database connections.
  • Avoided redundant postgres_pool initialization in lifespan.
  • Commented out unused code for closing postgres_pool.
  • +14/-8   
    000015_entries.up.sql
    Update `entries` table schema for `timestamp`                       

    memory-store/migrations/000015_entries.up.sql

  • Changed timestamp column type from DOUBLE PRECISION to TIMESTAMPTZ.
  • Improved schema consistency for entries table.
  • +1/-1     
    Bug fix
    search_docs_by_embedding.py
    Standardize `embedding` naming in vector search                   

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

  • Renamed query_embedding to embedding for consistency.
  • Updated parameter validation and conversion logic.
  • Adjusted SQL query to reflect the new naming.
  • +7/-7     
    utils.py
    Enhance database connection handling                                         

    agents-api/agents_api/queries/utils.py

  • Added safeguard for postgres_pool attribute access.
  • Improved robustness in database connection handling.
  • +1/-1     
    search_docs.py
    Update embedding references in document search                     

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

  • Renamed query_embedding to embedding in multiple cases.
  • Updated logic for MMR-based document filtering.
  • Adjusted parameter passing to reflect new naming.
  • +6/-6     

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


    Important

    Refactor database connection handling, update schema, and standardize naming for consistency and robustness.

    • Database Enhancements:
      • Refactor postgres_pool initialization in app.py to avoid redundant connections.
      • Update entries table schema in 000015_entries.up.sql to use TIMESTAMPTZ for timestamp.
      • Add safeguard for postgres_pool access in utils.py.
    • Naming Consistency:
      • Standardize embedding naming in search_docs_by_embedding.py and search_docs.py.
    • Error Handling:
      • Improve error handling in database operations in utils.py.

    This description was created by Ellipsis for be6b292. It will automatically update as commits are pushed.

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 Security concerns

    SQL Injection:
    The embedding_str in search_docs_by_embedding is constructed using string formatting (f-string). While the input is converted to string using map(str, embedding), additional validation of the embedding values should be added to prevent potential SQL injection.

    ⚡ Recommended focus areas for review

    Resource Leak

    The postgres connection pool closing logic is commented out. This could lead to connection leaks if the application restarts frequently or has multiple instances.

    # # CLOSE POSTGRES #
    # for container in containers:
    #     if hasattr(container, "state") and getattr(container.state, "postgres_pool", None):
    #         pool = getattr(container.state, "postgres_pool", None)
    #         if pool:
    #             await pool.close()
    #         container.state.postgres_pool = None
    Null Reference

    The postgres_pool attribute access could still fail if app.state is None. Consider adding additional null checks.

    else cast(asyncpg.Pool, getattr(app.state, "postgres_pool", None))

    Copy link
    Contributor

    qodo-merge-pro-for-open-source bot commented Jan 4, 2025

    CI Failure Feedback 🧐

    (Checks updated until commit be6b292)

    Action: Test

    Failed stage: [❌]

    Failed test name: test_entry_queries:64

    Failure summary:

    The action failed due to two main issues:

  • In test_entry_queries:64 ("query: list entries sql - session exists"), there was a type mismatch
    error where a float timestamp (1736024614.502017) was provided when a datetime.date or
    datetime.datetime object was expected
  • In test_docs_routes, there was an unexpected keyword argument error where 'query_embedding' was
    passed to search_docs_by_embedding() function when it wasn't expecting that parameter

  • Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    1331:  PASS  test_agent_queries:44 query: create or update agent sql                2%
    1332:  PASS  test_agent_queries:63 query: update agent sql                          2%
    1333:  PASS  test_agent_queries:85 query: get agent not exists sql                  3%
    1334:  PASS  test_agent_queries:96 query: get agent exists sql                      3%
    1335:  PASS  test_agent_queries:111 query: list agents sql                          4%
    1336:  PASS  test_agent_queries:122 query: patch agent sql                          4%
    1337:  PASS  test_agent_queries:143 query: delete agent sql                         5%
    1338:  INFO:httpx:HTTP Request: POST http://testserver/agents "HTTP/1.1 403 Forbidden"
    1339:  PASS  test_agent_routes:9 route: unauthorized should fail                    6%
    ...
    
    1409:  INFO:httpx:HTTP Request: POST http://testserver/agents/06779a22-4a4b-77cf-8000-0f166dcae48c/search "HTTP/1.1 200 OK"
    1410:  PASS  test_docs_routes:217 route: search agent docs hybrid with mmr         29%
    1411:  INFO:httpx:HTTP Request: POST http://testserver/embed "HTTP/1.1 200 OK"
    1412:  PASS  test_docs_routes:241 routes: embed route                              29%
    1413:  PASS  test_entry_queries:27 query: create entry no session                  30%
    1414:  PASS  test_entry_queries:49 query: list entries sql - no session            30%
    1415:  FAIL  test_entry_queries:64 query: list entries sql - session exists        31%
    1416:  ───────────────── chat: check that chat route calls both mocks ─────────────────
    1417:  Failed at tests/test_chat_routes.py                                           
    ...
    
    1419:  │ in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg:175 │  
    1420:  │                                                                          │  
    1421:  │ in asyncpg.protocol.protocol.Codec.encode:227                            │  
    1422:  │                                                                          │  
    1423:  │ in asyncpg.protocol.protocol.Codec.encode_scalar:129                     │  
    1424:  │                                                                          │  
    1425:  │ in asyncpg.pgproto.pgproto.timestamptz_encode:208                        │  
    1426:  ╰──────────────────────────────────────────────────────────────────────────╯  
    1427:  TypeError: expected a datetime.date or datetime.datetime instance, got        
    ...
    
    1430:  ╭─────────────────── Traceback (most recent call last) ────────────────────╮  
    1431:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:259 │  
    1432:  │ in async_wrapper                                                         │  
    1433:  │                                                                          │  
    1434:  │   256 │   │   @wraps(func)                                               │  
    1435:  │   257 │   │   async def async_wrapper(*args: P.args, **kwargs: P.kwargs) │  
    1436:  │   258 │   │   │   try:                                                   │  
    1437:  │ ❱ 259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    1438:  │   260 │   │   │   except BaseException as error:                         │  
    1439:  │   261 │   │   │   │   _check_error(error)                                │  
    1440:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    1690:  │ │                    │   │   │   │   │   ]                             │ │  
    1691:  │ │                    │   │   │   │   ]                                 │ │  
    1692:  │ │                    │   │   │   ],                                    │ │  
    1693:  │ │                    │   │   │   'timeout': 90.0                       │ │  
    1694:  │ │                    │   │   }                                         │ │  
    1695:  │ │                    │   )                                             │ │  
    1696:  │ │                    ]                                                 │ │  
    1697:  │ │             conn = <PoolConnectionProxy [released] 0x7f635164beb0>   │ │  
    1698:  │ │ connection_error = False                                             │ │  
    ...
    
    1728:  │ │                    │   │   │   tool_call_id=None,                    │ │  
    1729:  │ │                    │   │   │   timestamp=1736024599.835148           │ │  
    1730:  │ │                    │   │   )                                         │ │  
    1731:  │ │                    │   ]                                             │ │  
    1732:  │ │                    }                                                 │ │  
    1733:  │ │           method = <bound method Connection.fetchmany of             │ │  
    1734:  │ │                    <PoolConnectionProxy [released] 0x7f635164beb0>>  │ │  
    1735:  │ │      method_name = 'fetchmany'                                       │ │  
    1736:  │ │    only_on_error = False                                             │ │  
    ...
    
    1982:  │ in bind_execute_many:268                                                 │  
    1983:  │                                                                          │  
    1984:  │ in asyncpg.protocol.protocol.CoreProtocol._bind_execute_many_more:1054   │  
    1985:  │                                                                          │  
    1986:  │ in genexpr:230                                                           │  
    1987:  │                                                                          │  
    1988:  │ in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg:204 │  
    1989:  ╰──────────────────────────────────────────────────────────────────────────╯  
    1990:  DataError: invalid input for query argument $14 in element #0 of              
    ...
    
    2013:  │ │                      0x7f6379e247c0>,                                │ │  
    2014:  │ │                      │   <class                                      │ │  
    2015:  │ │                      'starlette.exceptions.WebSocketException'>:     │ │  
    2016:  │ │                      <bound method                                   │ │  
    2017:  │ │                      ExceptionMiddleware.websocket_exception of      │ │  
    2018:  │ │                      <starlette.middleware.exceptions.ExceptionMidd… │ │  
    2019:  │ │                      object at 0x7f63677ba0f0>>,                     │ │  
    2020:  │ │                      │   <class                                      │ │  
    2021:  │ │                      'fastapi.exceptions.RequestValidationError'>:   │ │  
    ...
    
    2025:  │ │                      │   <class                                      │ │  
    2026:  │ │                      'fastapi.exceptions.WebSocketRequestValidation… │ │  
    2027:  │ │                      <function                                       │ │  
    2028:  │ │                      websocket_request_validation_exception_handler  │ │  
    2029:  │ │                      at 0x7f6379e249a0>,                             │ │  
    2030:  │ │                      │   <class 'fastapi.exceptions.HTTPException'>: │ │  
    2031:  │ │                      <function http_exception_handler at             │ │  
    2032:  │ │                      0x7f6367c9a980>,                                │ │  
    2033:  │ │                      │   <class 'temporalio.service.RPCError'>:      │ │  
    2034:  │ │                      <function validation_error_handler at           │ │  
    2035:  │ │                      0x7f6367c9a2a0>,                                │ │  
    2036:  │ │                      │   <class                                      │ │  
    2037:  │ │                      'agents_api.common.exceptions.BaseCommonExcept… │ │  
    2038:  │ │                      <function session_not_found_error_handler at    │ │  
    2039:  │ │                      0x7f6367c98ea0>,                                │ │  
    2040:  │ │                      │   <class                                      │ │  
    2041:  │ │                      'agents_api.exceptions.PromptTooBigError'>:     │ │  
    2042:  │ │                      <function prompt_too_big_error at               │ │  
    2043:  │ │                      0x7f6367c9a340>,                                │ │  
    2044:  │ │                      │   <class 'litellm.exceptions.APIError'>:      │ │  
    2045:  │ │                      <function litellm_api_error at 0x7f6367c9a200>  │ │  
    ...
    
    2199:  │ │        0x7f635164bfb0>                                               │ │  
    2200:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2201:  │                                                                          │  
    2202:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:261 │  
    2203:  │ in async_wrapper                                                         │  
    2204:  │                                                                          │  
    2205:  │   258 │   │   │   try:                                                   │  
    2206:  │   259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    2207:  │   260 │   │   │   except BaseException as error:                         │  
    2208:  │ ❱ 261 │   │   │   │   _check_error(error)                                │  
    2209:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    2242:  │ │          │   │   │   tool_call_id=None,                              │ │  
    2243:  │ │          │   │   │   timestamp=1736024599.835148                     │ │  
    2244:  │ │          │   │   )                                                   │ │  
    2245:  │ │          │   ]                                                       │ │  
    2246:  │ │          }                                                           │ │  
    2247:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2248:  │                                                                          │  
    2249:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:251 │  
    2250:  │ in _check_error                                                          │  
    2251:  │                                                                          │  
    2252:  │   248 │   │   │   │   setattr(new_error, "__cause__", error)             │  
    2253:  │   249 │   │   │   │                                                      │  
    2254:  │   250 │   │   │   │   print(error)                                       │  
    2255:  │ ❱ 251 │   │   │   │   raise new_error from error                         │  
    2256:  │   252 │                                                                  │  
    2257:  │   253 │   def decorator(                                                 │  
    2258:  │   254 │   │   func: Callable[P, T | Awaitable[T]],                       │  
    2259:  │                                                                          │  
    2260:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    2261:  │ │        error = DataError("invalid input for query argument $14 in    │ │  
    2262:  │ │                element #0 of executemany() sequence:                 │ │  
    2263:  │ │                1736024599.842211 (expected a datetime.date or        │ │  
    2264:  │ │                datetime.datetime instance, got 'float')")            │ │  
    2265:  │ │      mapping = {                                                     │ │  
    2266:  │ │                │   <class                                            │ │  
    2267:  │ │                'asyncpg.exceptions.ForeignKeyViolationError'>:       │ │  
    2268:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2269:  │ │                │   <class                                            │ │  
    2270:  │ │                'asyncpg.exceptions.UniqueViolationError'>: <class    │ │  
    2271:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    2272:  │ │                │   <class 'asyncpg.exceptions.CheckViolationError'>: │ │  
    2273:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2274:  │ │                │   <class 'asyncpg.exceptions.DataError'>: <class    │ │  
    2275:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    2276:  │ │                │   <class 'asyncpg.exceptions.NoDataFoundError'>:    │ │  
    2277:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2278:  │ │                │   <class 'socket.gaierror'>: <class                 │ │  
    2279:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    2280:  │ │                │   <class                                            │ │  
    2281:  │ │                'asyncpg.exceptions.InvalidTextRepresentationError'>: │ │  
    2282:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2283:  │ │                │   <class                                            │ │  
    2284:  │ │                'asyncpg.exceptions.NumericValueOutOfRangeError'>:    │ │  
    2285:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2286:  │ │                │   <class                                            │ │  
    2287:  │ │                'asyncpg.exceptions.StringDataRightTruncationError'>: │ │  
    2288:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    2289:  │ │                │   <class                                            │ │  
    2290:  │ │                'asyncpg.exceptions.NotNullViolationError'>: <class   │ │  
    2291:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    2292:  │ │                │   ... +6                                            │ │  
    2293:  │ │                }                                                     │ │  
    2294:  │ │    new_error = HTTPException(status_code=400, detail='Invalid entry  │ │  
    ...
    
    2319:  │                                                                          │  
    2320:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2321:  │ python3.12/asyncio/runners.py:118 in run                                 │  
    2322:  │                                                                          │  
    2323:  │   115 │   │                                                              │  
    2324:  │   116 │   │   self._interrupt_count = 0                                  │  
    2325:  │   117 │   │   try:                                                       │  
    2326:  │ ❱ 118 │   │   │   return self._loop.run_until_complete(task)             │  
    2327:  │   119 │   │   except exceptions.CancelledError:                          │  
    ...
    
    2332:  │ │        context = <_contextvars.Context object at 0x7f63659c96c0>     │ │  
    2333:  │ │           coro = <coroutine object _ at 0x7f636777be20>              │ │  
    2334:  │ │           self = <asyncio.runners.Runner object at 0x7f6365d80890>   │ │  
    2335:  │ │ sigint_handler = functools.partial(<bound method Runner._on_sigint   │ │  
    2336:  │ │                  of <asyncio.runners.Runner object at                │ │  
    2337:  │ │                  0x7f6365d80890>>, main_task=<Task finished          │ │  
    2338:  │ │                  name='Task-415' coro=<_() done, defined at          │ │  
    2339:  │ │                  /home/runner/work/julep/julep/agents-api/tests/tes… │ │  
    2340:  │ │                  exception=RuntimeError('Caught handled exception,   │ │  
    2341:  │ │                  but response already started.')>)                   │ │  
    2342:  │ │           task = <Task finished name='Task-415' coro=<_() done,      │ │  
    2343:  │ │                  defined at                                          │ │  
    2344:  │ │                  /home/runner/work/julep/julep/agents-api/tests/tes… │ │  
    2345:  │ │                  exception=RuntimeError('Caught handled exception,   │ │  
    ...
    
    2801:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    2802:  │ │        0x7f63677b9730>                                               │ │  
    2803:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2804:  │                                                                          │  
    2805:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2806:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    2807:  │                                                                          │  
    2808:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    2809:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    2810:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    2811:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    2812:  │   457 │   │   │   │   else:                                              │  
    2813:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    2885:  │ │                       at 0x7f6367766ac0>,                            │ │  
    2886:  │ │                       │   <function                                  │ │  
    2887:  │ │                       _TestClientTransport.handle_request.<locals>.… │ │  
    2888:  │ │                       at 0x7f6364043420>                             │ │  
    2889:  │ │                       )                                              │ │  
    2890:  │ │                func = <fastapi.applications.FastAPI object at        │ │  
    2891:  │ │                       0x7f63699592e0>                                │ │  
    2892:  │ │              future = <Future at 0x7f6365d98080 state=finished       │ │  
    2893:  │ │                       raised RuntimeError>                           │ │  
    ...
    
    2979:  │ │         │   ],                                                       │ │  
    2980:  │ │         │   'client': ['testclient', 50000],                         │ │  
    2981:  │ │         │   ... +9                                                   │ │  
    2982:  │ │         }                                                            │ │  
    2983:  │ │  self = <fastapi.applications.FastAPI object at 0x7f63699592e0>      │ │  
    2984:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2985:  │                                                                          │  
    2986:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    2987:  │ ges/starlette/middleware/errors.py:187 in __call__                       │  
    2988:  │                                                                          │  
    2989:  │   184 │   │   │   # We always continue to raise the exception.           │  
    2990:  │   185 │   │   │   # This allows servers to log the error, or allows test │  
    2991:  │   186 │   │   │   # to optionally raise the error within the test case.  │  
    ...
    
    3022:  │ │                    │   │   │   b'95969155867466152012341228824940'   │ │  
    3023:  │ │                    │   │   ),                                        │ │  
    3024:  │ │                    │   │   (b'content-length', b'184'),              │ │  
    3025:  │ │                    │   │   (b'content-type', b'application/json')    │ │  
    3026:  │ │                    │   ],                                            │ │  
    3027:  │ │                    │   'client': ['testclient', 50000],              │ │  
    3028:  │ │                    │   ... +9                                        │ │  
    3029:  │ │                    }                                                 │ │  
    3030:  │ │             self = <starlette.middleware.errors.ServerErrorMiddlewa… │ │  
    3031:  │ │                    object at 0x7f636778ef60>                         │ │  
    3032:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3033:  │                                                                          │  
    3034:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3035:  │ ges/starlette/middleware/errors.py:165 in __call__                       │  
    ...
    
    3070:  │ │                    │   │   │   b'95969155867466152012341228824940'   │ │  
    3071:  │ │                    │   │   ),                                        │ │  
    3072:  │ │                    │   │   (b'content-length', b'184'),              │ │  
    3073:  │ │                    │   │   (b'content-type', b'application/json')    │ │  
    3074:  │ │                    │   ],                                            │ │  
    3075:  │ │                    │   'client': ['testclient', 50000],              │ │  
    3076:  │ │                    │   ... +9                                        │ │  
    3077:  │ │                    }                                                 │ │  
    3078:  │ │             self = <starlette.middleware.errors.ServerErrorMiddlewa… │ │  
    ...
    
    3335:  │ ges/starlette/_exception_handler.py:53 in wrapped_app                    │  
    3336:  │                                                                          │  
    3337:  │   50 │   │   │   │   handler = _lookup_exception_handler(exception_handl │  
    3338:  │   51 │   │   │                                                           │  
    3339:  │   52 │   │   │   if handler is None:                                     │  
    3340:  │ ❱ 53 │   │   │   │   raise exc                                           │  
    3341:  │   54 │   │   │                                                           │  
    3342:  │   55 │   │   │   if response_started:                                    │  
    3343:  │   56 │   │   │   │   raise RuntimeError("Caught handled exception, but r │  
    ...
    
    3354:  │ │                      0x7f6379e247c0>,                                │ │  
    3355:  │ │                      │   <class                                      │ │  
    3356:  │ │                      'starlette.exceptions.WebSocketException'>:     │ │  
    3357:  │ │                      <bound method                                   │ │  
    3358:  │ │                      ExceptionMiddleware.websocket_exception of      │ │  
    3359:  │ │                      <starlette.middleware.exceptions.ExceptionMidd… │ │  
    3360:  │ │                      object at 0x7f63677ba0f0>>,                     │ │  
    3361:  │ │                      │   <class                                      │ │  
    3362:  │ │                      'fastapi.exceptions.RequestValidationError'>:   │ │  
    ...
    
    3366:  │ │                      │   <class                                      │ │  
    3367:  │ │                      'fastapi.exceptions.WebSocketRequestValidation… │ │  
    3368:  │ │                      <function                                       │ │  
    3369:  │ │                      websocket_request_validation_exception_handler  │ │  
    3370:  │ │                      at 0x7f6379e249a0>,                             │ │  
    3371:  │ │                      │   <class 'fastapi.exceptions.HTTPException'>: │ │  
    3372:  │ │                      <function http_exception_handler at             │ │  
    3373:  │ │                      0x7f6367c9a980>,                                │ │  
    3374:  │ │                      │   <class 'temporalio.service.RPCError'>:      │ │  
    3375:  │ │                      <function validation_error_handler at           │ │  
    3376:  │ │                      0x7f6367c9a2a0>,                                │ │  
    3377:  │ │                      │   <class                                      │ │  
    3378:  │ │                      'agents_api.common.exceptions.BaseCommonExcept… │ │  
    3379:  │ │                      <function session_not_found_error_handler at    │ │  
    3380:  │ │                      0x7f6367c98ea0>,                                │ │  
    3381:  │ │                      │   <class                                      │ │  
    3382:  │ │                      'agents_api.exceptions.PromptTooBigError'>:     │ │  
    3383:  │ │                      <function prompt_too_big_error at               │ │  
    3384:  │ │                      0x7f6367c9a340>,                                │ │  
    3385:  │ │                      │   <class 'litellm.exceptions.APIError'>:      │ │  
    3386:  │ │                      <function litellm_api_error at 0x7f6367c9a200>  │ │  
    ...
    
    3446:  │ │                      0x7f6379e247c0>,                                │ │  
    3447:  │ │                      │   <class                                      │ │  
    3448:  │ │                      'starlette.exceptions.WebSocketException'>:     │ │  
    3449:  │ │                      <bound method                                   │ │  
    3450:  │ │                      ExceptionMiddleware.websocket_exception of      │ │  
    3451:  │ │                      <starlette.middleware.exceptions.ExceptionMidd… │ │  
    3452:  │ │                      object at 0x7f63677ba0f0>>,                     │ │  
    3453:  │ │                      │   <class                                      │ │  
    3454:  │ │                      'fastapi.exceptions.RequestValidationError'>:   │ │  
    ...
    
    3458:  │ │                      │   <class                                      │ │  
    3459:  │ │                      'fastapi.exceptions.WebSocketRequestValidation… │ │  
    3460:  │ │                      <function                                       │ │  
    3461:  │ │                      websocket_request_validation_exception_handler  │ │  
    3462:  │ │                      at 0x7f6379e249a0>,                             │ │  
    3463:  │ │                      │   <class 'fastapi.exceptions.HTTPException'>: │ │  
    3464:  │ │                      <function http_exception_handler at             │ │  
    3465:  │ │                      0x7f6367c9a980>,                                │ │  
    3466:  │ │                      │   <class 'temporalio.service.RPCError'>:      │ │  
    3467:  │ │                      <function validation_error_handler at           │ │  
    3468:  │ │                      0x7f6367c9a2a0>,                                │ │  
    3469:  │ │                      │   <class                                      │ │  
    3470:  │ │                      'agents_api.common.exceptions.BaseCommonExcept… │ │  
    3471:  │ │                      <function session_not_found_error_handler at    │ │  
    3472:  │ │                      0x7f6367c98ea0>,                                │ │  
    3473:  │ │                      │   <class                                      │ │  
    3474:  │ │                      'agents_api.exceptions.PromptTooBigError'>:     │ │  
    3475:  │ │                      <function prompt_too_big_error at               │ │  
    3476:  │ │                      0x7f6367c9a340>,                                │ │  
    3477:  │ │                      │   <class 'litellm.exceptions.APIError'>:      │ │  
    3478:  │ │                      <function litellm_api_error at 0x7f6367c9a200>  │ │  
    ...
    
    3699:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3700:  │                                                                          │  
    3701:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3702:  │ ges/starlette/_exception_handler.py:56 in wrapped_app                    │  
    3703:  │                                                                          │  
    3704:  │   53 │   │   │   │   raise exc                                           │  
    3705:  │   54 │   │   │                                                           │  
    3706:  │   55 │   │   │   if response_started:                                    │  
    3707:  │ ❱ 56 │   │   │   │   raise RuntimeError("Caught handled exception, but r │  
    ...
    
    3719:  │ │                      0x7f6379e247c0>,                                │ │  
    3720:  │ │                      │   <class                                      │ │  
    3721:  │ │                      'starlette.exceptions.WebSocketException'>:     │ │  
    3722:  │ │                      <bound method                                   │ │  
    3723:  │ │                      ExceptionMiddleware.websocket_exception of      │ │  
    3724:  │ │                      <starlette.middleware.exceptions.ExceptionMidd… │ │  
    3725:  │ │                      object at 0x7f63677ba0f0>>,                     │ │  
    3726:  │ │                      │   <class                                      │ │  
    3727:  │ │                      'fastapi.exceptions.RequestValidationError'>:   │ │  
    ...
    
    3731:  │ │                      │   <class                                      │ │  
    3732:  │ │                      'fastapi.exceptions.WebSocketRequestValidation… │ │  
    3733:  │ │                      <function                                       │ │  
    3734:  │ │                      websocket_request_validation_exception_handler  │ │  
    3735:  │ │                      at 0x7f6379e249a0>,                             │ │  
    3736:  │ │                      │   <class 'fastapi.exceptions.HTTPException'>: │ │  
    3737:  │ │                      <function http_exception_handler at             │ │  
    3738:  │ │                      0x7f6367c9a980>,                                │ │  
    3739:  │ │                      │   <class 'temporalio.service.RPCError'>:      │ │  
    3740:  │ │                      <function validation_error_handler at           │ │  
    3741:  │ │                      0x7f6367c9a2a0>,                                │ │  
    3742:  │ │                      │   <class                                      │ │  
    3743:  │ │                      'agents_api.common.exceptions.BaseCommonExcept… │ │  
    3744:  │ │                      <function session_not_found_error_handler at    │ │  
    3745:  │ │                      0x7f6367c98ea0>,                                │ │  
    3746:  │ │                      │   <class                                      │ │  
    3747:  │ │                      'agents_api.exceptions.PromptTooBigError'>:     │ │  
    3748:  │ │                      <function prompt_too_big_error at               │ │  
    3749:  │ │                      0x7f6367c9a340>,                                │ │  
    3750:  │ │                      │   <class 'litellm.exceptions.APIError'>:      │ │  
    3751:  │ │                      <function litellm_api_error at 0x7f6367c9a200>  │ │  
    ...
    
    3782:  │ │                      │   │   )                                       │ │  
    3783:  │ │                      │   ],                                          │ │  
    3784:  │ │                      │   'client': ['testclient', 50000],            │ │  
    3785:  │ │                      │   ... +9                                      │ │  
    3786:  │ │                      }                                               │ │  
    3787:  │ │    status_handlers = {}                                              │ │  
    3788:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3789:  ╰──────────────────────────────────────────────────────────────────────────╯  
    3790:  RuntimeError: Caught handled exception, but response already started.         
    3791:  Captured stdout                                                               
    3792:  invalid input for query argument $14 in element #0 of executemany()         
    3793:  sequence: 1736024599.842211 (expected a datetime.date or datetime.datetime  
    3794:  instance, got 'float')                                                      
    3795:  ─────────────────────── query: search docs by embedding ────────────────────────
    3796:  Failed at tests/test_docs_queries.py                                          
    3797:  ╭─────────────────── Traceback (most recent call last) ────────────────────╮  
    3798:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:259 │  
    3799:  │ in async_wrapper                                                         │  
    3800:  │                                                                          │  
    3801:  │   256 │   │   @wraps(func)                                               │  
    3802:  │   257 │   │   async def async_wrapper(*args: P.args, **kwargs: P.kwargs) │  
    3803:  │   258 │   │   │   try:                                                   │  
    3804:  │ ❱ 259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    3805:  │   260 │   │   │   except BaseException as error:                         │  
    3806:  │   261 │   │   │   │   _check_error(error)                                │  
    3807:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    3883:  │ in wrapper                                                               │  
    3884:  │                                                                          │  
    3885:  │   107 │   │   │   connection_pool: asyncpg.Pool | None = None,           │  
    3886:  │   108 │   │   │   **kwargs: P.kwargs,                                    │  
    3887:  │   109 │   │   ) -> list[Record]:                                         │  
    3888:  │ ❱ 110 │   │   │   query_args = await func(*args, **kwargs)               │  
    3889:  │   111 │   │   │   batch = prepare_pg_query_args(query_args)              │  
    3890:  │   112 │   │   │                                                          │  
    3891:  │   113 │   │   │   not only_on_error and debug and pprint(batch)          │  
    ...
    
    3915:  │ │                   │   │   1.0,                                       │ │  
    3916:  │ │                   │   │   1.0,                                       │ │  
    3917:  │ │                   │   │   1.0,                                       │ │  
    3918:  │ │                   │   │   ... +1014                                  │ │  
    3919:  │ │                   │   ],                                             │ │  
    3920:  │ │                   │   'k': 3,                                        │ │  
    3921:  │ │                   │   'metadata_filter': {'test': 'test'}            │ │  
    3922:  │ │                   }                                                  │ │  
    3923:  │ │   only_on_error = False                                              │ │  
    ...
    
    3949:  │ │          │   │   1.0,                                                │ │  
    3950:  │ │          │   │   ... +1014                                           │ │  
    3951:  │ │          │   ],                                                      │ │  
    3952:  │ │          │   'k': 3,                                                 │ │  
    3953:  │ │          │   'metadata_filter': {'test': 'test'}                     │ │  
    3954:  │ │          }                                                           │ │  
    3955:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3956:  ╰──────────────────────────────────────────────────────────────────────────╯  
    3957:  TypeError: search_docs_by_embedding() got an unexpected keyword argument      
    ...
    
    3978:  │                                                                          │  
    3979:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3980:  │ python3.12/asyncio/runners.py:118 in run                                 │  
    3981:  │                                                                          │  
    3982:  │   115 │   │                                                              │  
    3983:  │   116 │   │   self._interrupt_count = 0                                  │  
    3984:  │   117 │   │   try:                                                       │  
    3985:  │ ❱ 118 │   │   │   return self._loop.run_until_complete(task)             │  
    3986:  │   119 │   │   except exceptions.CancelledError:                          │  
    ...
    
    4107:  │ │                   ]                                                  │ │  
    4108:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4109:  │                                                                          │  
    4110:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:261 │  
    4111:  │ in async_wrapper                                                         │  
    4112:  │                                                                          │  
    4113:  │   258 │   │   │   try:                                                   │  
    4114:  │   259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    4115:  │   260 │   │   │   except BaseException as error:                         │  
    4116:  │ ❱ 261 │   │   │   │   _check_error(error)                                │  
    4117:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    4145:  │ │          │   'k': 3,                                                 │ │  
    4146:  │ │          │   'metadata_filter': {'test': 'test'},                    │ │  
    4147:  │ │          │   'connection_pool': <asyncpg.pool.Pool object at         │ │  
    4148:  │ │          0x7f63516dd6c0>                                             │ │  
    4149:  │ │          }                                                           │ │  
    4150:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4151:  │                                                                          │  
    4152:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:251 │  
    4153:  │ in _check_error                                                          │  
    4154:  │                                                                          │  
    4155:  │   248 │   │   │   │   setattr(new_error, "__cause__", error)             │  
    4156:  │   249 │   │   │   │                                                      │  
    4157:  │   250 │   │   │   │   print(error)                                       │  
    4158:  │ ❱ 251 │   │   │   │   raise new_error from error                         │  
    4159:  │   252 │                                                                  │  
    4160:  │   253 │   def decorator(                                                 │  
    4161:  │   254 │   │   func: Callable[P, T | Awaitable[T]],                       │  
    4162:  │                                                                          │  
    4163:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    4164:  │ │        error = TypeError("search_docs_by_embedding() got an          │ │  
    4165:  │ │                unexpected keyword argument 'query_embedding'")       │ │  
    4166:  │ │      mapping = {                                                     │ │  
    4167:  │ │                │   <class                                            │ │  
    4168:  │ │                'asyncpg.exceptions.ForeignKeyViolationError'>:       │ │  
    4169:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4170:  │ │                │   <class                                            │ │  
    4171:  │ │                'asyncpg.exceptions.UniqueViolationError'>: <class    │ │  
    4172:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4173:  │ │                │   <class 'asyncpg.exceptions.CheckViolationError'>: │ │  
    4174:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4175:  │ │                │   <class 'asyncpg.exceptions.DataError'>: <class    │ │  
    4176:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4177:  │ │                │   <class 'asyncpg.exceptions.NoDataFoundError'>:    │ │  
    4178:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4179:  │ │                │   <class 'socket.gaierror'>: <class                 │ │  
    4180:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4181:  │ │                │   <class                                            │ │  
    4182:  │ │                'asyncpg.exceptions.InvalidTextRepresentationError'>: │ │  
    4183:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4184:  │ │                │   <class                                            │ │  
    4185:  │ │                'asyncpg.exceptions.NumericValueOutOfRangeError'>:    │ │  
    4186:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4187:  │ │                │   <class                                            │ │  
    4188:  │ │                'asyncpg.exceptions.StringDataRightTruncationError'>: │ │  
    4189:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4190:  │ │                │   <class                                            │ │  
    4191:  │ │                'asyncpg.exceptions.NotNullViolationError'>: <class   │ │  
    4192:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4193:  │ │                │   ... +6                                            │ │  
    4194:  │ │                }                                                     │ │  
    4195:  │ │    new_error = HTTPException(status_code=400, detail='Invalid type   │ │  
    ...
    
    4197:  │ │ should_catch = True                                                  │ │  
    4198:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4199:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4200:  HTTPException: 400: Invalid type for doc during search                        
    4201:  Captured stdout                                                               
    4202:  search_docs_by_embedding() got an unexpected keyword argument               
    4203:  'query_embedding'                                                           
    4204:  ─────────────────── query: list entries sql - session exists ───────────────────
    4205:  Failed at tests/test_entry_queries.py                                         
    ...
    
    4207:  │ in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg:175 │  
    4208:  │                                                                          │  
    4209:  │ in asyncpg.protocol.protocol.Codec.encode:227                            │  
    4210:  │                                                                          │  
    4211:  │ in asyncpg.protocol.protocol.Codec.encode_scalar:129                     │  
    4212:  │                                                                          │  
    4213:  │ in asyncpg.pgproto.pgproto.timestamptz_encode:208                        │  
    4214:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4215:  TypeError: expected a datetime.date or datetime.datetime instance, got        
    ...
    
    4218:  ╭─────────────────── Traceback (most recent call last) ────────────────────╮  
    4219:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:259 │  
    4220:  │ in async_wrapper                                                         │  
    4221:  │                                                                          │  
    4222:  │   256 │   │   @wraps(func)                                               │  
    4223:  │   257 │   │   async def async_wrapper(*args: P.args, **kwargs: P.kwargs) │  
    4224:  │   258 │   │   │   try:                                                   │  
    4225:  │ ❱ 259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    4226:  │   260 │   │   │   except BaseException as error:                         │  
    4227:  │   261 │   │   │   │   _check_error(error)                                │  
    4228:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    4490:  │ │                    │   │   │   │   │   ]                             │ │  
    4491:  │ │                    │   │   │   │   ]                                 │ │  
    4492:  │ │                    │   │   │   ],                                    │ │  
    4493:  │ │                    │   │   │   'timeout': 90.0                       │ │  
    4494:  │ │                    │   │   }                                         │ │  
    4495:  │ │                    │   )                                             │ │  
    4496:  │ │                    ]                                                 │ │  
    4497:  │ │             conn = <PoolConnectionProxy [released] 0x7f636515cdc0>   │ │  
    4498:  │ │ connection_error = False                                             │ │  
    ...
    
    4528:  │ │                    │   │   │   tool_call_id=None,                    │ │  
    4529:  │ │                    │   │   │   timestamp=1736024614.501916           │ │  
    4530:  │ │                    │   │   )                                         │ │  
    4531:  │ │                    │   ]                                             │ │  
    4532:  │ │                    }                                                 │ │  
    4533:  │ │           method = <bound method Connection.fetchmany of             │ │  
    4534:  │ │                    <PoolConnectionProxy [released] 0x7f636515cdc0>>  │ │  
    4535:  │ │      method_name = 'fetchmany'                                       │ │  
    4536:  │ │    only_on_error = False                                             │ │  
    ...
    
    4806:  │ in bind_execute_many:268                                                 │  
    4807:  │                                                                          │  
    4808:  │ in asyncpg.protocol.protocol.CoreProtocol._bind_execute_many_more:1054   │  
    4809:  │                                                                          │  
    4810:  │ in genexpr:230                                                           │  
    4811:  │                                                                          │  
    4812:  │ in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg:204 │  
    4813:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4814:  DataError: invalid input for query argument $14 in element #0 of              
    ...
    
    4836:  │                                                                          │  
    4837:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4838:  │ python3.12/asyncio/runners.py:118 in run                                 │  
    4839:  │                                                                          │  
    4840:  │   115 │   │                                                              │  
    4841:  │   116 │   │   self._interrupt_count = 0                                  │  
    4842:  │   117 │   │   try:                                                       │  
    4843:  │ ❱ 118 │   │   │   return self._loop.run_until_complete(task)             │  
    4844:  │   119 │   │   except exceptions.CancelledError:                          │  
    ...
    
    4915:  │ │                  )                                                   │ │  
    4916:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4917:  │                                                                          │  
    4918:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:261 │  
    4919:  │ in async_wrapper                                                         │  
    4920:  │                                                                          │  
    4921:  │   258 │   │   │   try:                                                   │  
    4922:  │   259 │   │   │   │   result: T = await func(*args, **kwargs)            │  
    4923:  │   260 │   │   │   except BaseException as error:                         │  
    4924:  │ ❱ 261 │   │   │   │   _check_error(error)                                │  
    4925:  │   262 │   │   │   │   raise error                                        │  
    ...
    
    4960:  │ │          │   │   )                                                   │ │  
    4961:  │ │          │   ],                                                      │ │  
    4962:  │ │          │   'connection_pool': <asyncpg.pool.Pool object at         │ │  
    4963:  │ │          0x7f63516dd840>                                             │ │  
    4964:  │ │          }                                                           │ │  
    4965:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4966:  │                                                                          │  
    4967:  │ /home/runner/work/julep/julep/agents-api/agents_api/queries/utils.py:251 │  
    4968:  │ in _check_error                                                          │  
    4969:  │                                                                          │  
    4970:  │   248 │   │   │   │   setattr(new_error, "__cause__", error)             │  
    4971:  │   249 │   │   │   │                                                      │  
    4972:  │   250 │   │   │   │   print(error)                                       │  
    4973:  │ ❱ 251 │   │   │   │   raise new_error from error                         │  
    4974:  │   252 │                                                                  │  
    4975:  │   253 │   def decorator(                                                 │  
    4976:  │   254 │   │   func: Callable[P, T | Awaitable[T]],                       │  
    4977:  │                                                                          │  
    4978:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    4979:  │ │        error = DataError("invalid input for query argument $14 in    │ │  
    4980:  │ │                element #0 of executemany() sequence:                 │ │  
    4981:  │ │                1736024614.502017 (expected a datetime.date or        │ │  
    4982:  │ │                datetime.datetime instance, got 'float')")            │ │  
    4983:  │ │      mapping = {                                                     │ │  
    4984:  │ │                │   <class                                            │ │  
    4985:  │ │                'asyncpg.exceptions.ForeignKeyViolationError'>:       │ │  
    4986:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4987:  │ │                │   <class                                            │ │  
    4988:  │ │                'asyncpg.exceptions.UniqueViolationError'>: <class    │ │  
    4989:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4990:  │ │                │   <class 'asyncpg.exceptions.CheckViolationError'>: │ │  
    4991:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4992:  │ │                │   <class 'asyncpg.exceptions.DataError'>: <class    │ │  
    4993:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4994:  │ │                │   <class 'asyncpg.exceptions.NoDataFoundError'>:    │ │  
    4995:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    4996:  │ │                │   <class 'socket.gaierror'>: <class                 │ │  
    4997:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    4998:  │ │                │   <class                                            │ │  
    4999:  │ │                'asyncpg.exceptions.InvalidTextRepresentationError'>: │ │  
    5000:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    5001:  │ │                │   <class                                            │ │  
    5002:  │ │                'asyncpg.exceptions.NumericValueOutOfRangeError'>:    │ │  
    5003:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    5004:  │ │                │   <class                                            │ │  
    5005:  │ │                'asyncpg.exceptions.StringDataRightTruncationError'>: │ │  
    5006:  │ │                <class 'fastapi.exceptions.HTTPException'>,           │ │  
    5007:  │ │                │   <class                                            │ │  
    5008:  │ │                'asyncpg.exceptions.NotNullViolationError'>: <class   │ │  
    5009:  │ │                'fastapi.exceptions.HTTPException'>,                  │ │  
    5010:  │ │                │   ... +6                                            │ │  
    5011:  │ │                }                                                     │ │  
    5012:  │ │    new_error = HTTPException(status_code=400, detail='Invalid entry  │ │  
    ...
    
    5018:  Captured stdout                                                               
    5019:  invalid input for query argument $14 in element #0 of executemany()         
    5020:  sequence: 1736024614.502017 (expected a datetime.date or datetime.datetime  
    5021:  instance, got 'float')                                                      
    5022:  ────────────────────────────────────────────────────────────────────────────────
    5023:  ╭──────────── Results ─────────────╮
    5024:  │  55  Tests Encountered           │
    5025:  │  52  Passes             (94.5%)  │
    5026:  │   3  Failures           (5.5%)   │
    5027:  ╰──────────────────────────────────╯
    5028:  ─────────────────────────── FAILED in 68.38 seconds ────────────────────────────
    5029:  ##[error]The operation was canceled.
    ...
    
    5031:  [command]/usr/bin/git version
    5032:  git version 2.47.1
    5033:  Temporarily overriding HOME='/home/runner/work/_temp/1157ef97-7116-4150-8a26-4937717763d5' before making global git config changes
    5034:  Adding repository directory to the temporary git global config as a safe directory
    5035:  [command]/usr/bin/git config --global --add safe.directory /home/runner/work/julep/julep
    5036:  [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
    5037:  [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
    5038:  fatal: No url found for submodule path 'drafts/cozo' in .gitmodules
    5039:  ##[warning]The process '/usr/bin/git' failed with exit code 128
    

    ✨ 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 failed. Default is true.
    • excluded_checks_list - a list of checks to exclude from the feedback, for example: ["check1", "check2"]. Default is an empty list.
    • enable_help_text - if set to true, the tool will provide a help message with the feedback. Default is true.
    • persistent_comment - if set to true, the tool will overwrite a previous checks comment with the new feedback. Default is true.
    • final_update_message - if persistent_comment is true and updating a previous checks message, the tool will also create a new message: "Persistent checks updated to latest commit". Default is true.

    See more information about the checks tool in the docs.

    Copy link
    Contributor

    @ellipsis-dev ellipsis-dev bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ❌ Changes requested. Reviewed everything up to 5cddb90 in 36 seconds

    More details
    • Looked at 191 lines of code in 5 files
    • Skipped 0 files when reviewing.
    • Skipped posting 1 drafted comments based on config settings.
    1. memory-store/migrations/000015_entries.up.sql:45
    • Draft comment:
      Changing the timestamp column from DOUBLE PRECISION to TIMESTAMPTZ is a significant change. Ensure that this change is compatible with existing data and application logic, as it may affect how timestamps are stored and queried.
    • Reason this comment was not posted:
      Comment did not seem useful.

    Workflow ID: wflow_AFJmHjrfS7FKVIkl


    Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

    agents-api/agents_api/app.py Show resolved Hide resolved
    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Ensure proper cleanup of database connections to prevent resource leaks

    The global pool variable should be properly closed when the application shuts down.
    Uncomment and fix the pool closing logic in the finally block to prevent connection
    leaks.

    agents-api/agents_api/app.py [59-65]

    -# # CLOSE POSTGRES #
    -# for container in containers:
    -#     if hasattr(container, "state") and getattr(container.state, "postgres_pool", None):
    -#         pool = getattr(container.state, "postgres_pool", None)
    -#         if pool:
    -#             await pool.close()
    -#         container.state.postgres_pool = None
    +# CLOSE POSTGRES #
    +global pool
    +if pool:
    +    await pool.close()
    +    pool = None
    +for container in containers:
    +    if hasattr(container, "state"):
    +        container.state.postgres_pool = None
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: The suggestion addresses a critical issue of potential database connection leaks. The current code has commented out the cleanup logic, which could lead to resource exhaustion in production.

    9
    Add proper error handling for uninitialized database connections

    Add null check before accessing the pool to prevent potential NoneType errors when
    the database connection is not initialized.

    agents-api/agents_api/queries/utils.py [116-119]

    -pool = (
    -    connection_pool
    -    if connection_pool is not None
    -    else cast(asyncpg.Pool, getattr(app.state, "postgres_pool", None))
    -)
    +pool = connection_pool if connection_pool is not None else getattr(app.state, "postgres_pool", None)
    +if pool is None:
    +    raise RuntimeError("Database connection pool not initialized")
    +pool = cast(asyncpg.Pool, pool)
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion adds crucial error handling to prevent silent failures and potential crashes when the database connection is not properly initialized, improving system reliability.

    8
    General
    Validate input vector dimensions to prevent database errors

    Add validation for embedding vector length to ensure it matches the expected
    dimension (1024) before executing the query.

    agents-api/agents_api/queries/docs/search_docs_by_embedding.py [59-60]

     if not embedding:
         raise HTTPException(status_code=400, detail="Empty embedding provided")
    +if len(embedding) != 1024:
    +    raise HTTPException(status_code=400, detail="Embedding must have exactly 1024 dimensions")
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: The suggestion adds important input validation to prevent database errors by ensuring the embedding vector matches the expected dimension, as indicated in the SQL query's vector(1024) type.

    7

    Copy link
    Contributor

    @ellipsis-dev ellipsis-dev bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    👍 Looks good to me! Incremental review on 47a9ce4 in 7 seconds

    More details
    • Looked at 13 lines of code in 1 files
    • Skipped 0 files when reviewing.
    • Skipped posting 1 drafted comments based on config settings.
    1. memory-store/migrations/000004_agents.up.sql:17
    • Draft comment:
      Increasing the length constraint for the about column from 1000 to 5000 may have performance implications, especially if this column is frequently queried or indexed. Consider evaluating the impact on performance.
    • Reason this comment was not posted:
      Confidence changes required: 50%
      The change in the length constraint for the 'about' column from 1000 to 5000 is a significant increase. This should be noted for potential performance implications, especially if this column is frequently queried or indexed.

    Workflow ID: wflow_EurHYY6wzSQ11MSW


    You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

    Copy link
    Contributor

    @ellipsis-dev ellipsis-dev bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    👍 Looks good to me! Incremental review on be6b292 in 9 seconds

    More details
    • Looked at 13 lines of code in 1 files
    • Skipped 0 files when reviewing.
    • Skipped posting 1 drafted comments based on config settings.
    1. agents-api/agents_api/queries/chat/gather_messages.py:123
    • Draft comment:
      Ensure the variable embedding is consistently used across the codebase for clarity and maintainability. This change aligns with the PR's goal of standardizing naming conventions.
    • Reason this comment was not posted:
      Confidence changes required: 50%
      The change from query_embedding to embedding is consistent with the PR's goal of standardizing naming conventions. However, the change should be applied consistently across the codebase.

    Workflow ID: wflow_lLePacQ6f0OH2tAo


    You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

    @whiterabbit1983 whiterabbit1983 merged commit 577a808 into f/switch-to-pg Jan 5, 2025
    6 of 11 checks passed
    @whiterabbit1983 whiterabbit1983 deleted the x/misc-fixes branch January 5, 2025 07:57
    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