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

chore(agents-api): remove jinja templates from PromptStep and LogStep #1081

Merged
merged 1 commit into from
Jan 24, 2025

Conversation

Ahmad-mtos
Copy link
Contributor

@Ahmad-mtos Ahmad-mtos commented Jan 23, 2025

PR Type

Enhancement


Description

  • Removed usage of render_template in LogStep and PromptStep.

  • Replaced render_template with base_evaluate for expression evaluation.

  • Simplified logic for handling prompt expressions in PromptStep.


Changes walkthrough 📝

Relevant files
Enhancement
log_step.py
Replace `render_template` with `base_evaluate` in `LogStep`

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

  • Removed render_template usage for log evaluation.
  • Introduced base_evaluate for expression evaluation.
  • Simplified the logic for evaluating log expressions.
  • +3/-7     
    prompt_step.py
    Replace `render_template` with `base_evaluate` in `PromptStep`

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

  • Removed render_template usage for prompt evaluation.
  • Integrated base_evaluate for expression handling.
  • Simplified prompt handling logic by removing template rendering.
  • +0/-10   

    Need help?
  • Type /help how to ... in the comments thread for any question about Qodo Merge usage.
  • Check out the documentation for more information.

  • Important

    Replaces Jinja templates with base_evaluate in log_step() and prompt_step() to simplify expression evaluation.

    • Behavior:
      • Replaces Jinja template rendering with base_evaluate in log_step() in log_step.py.
      • Removes Jinja template rendering in prompt_step() in prompt_step.py.
    • Functions:
      • log_step(): Uses base_evaluate to process context.current_step.log.
      • prompt_step(): Removes template rendering logic for non-evaluated prompts.

    This description was created by Ellipsis for 3331cf1. 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: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Validation Check

    The removal of template rendering may affect prompt message validation. Verify that base_evaluate properly validates prompt message structure and content.

    # Wrap the prompt in a list if it is not already
    prompt = prompt if isinstance(prompt, list) else [{"role": "user", "content": prompt}]
    Error Handling

    The new implementation using base_evaluate may need additional error handling for expression evaluation failures.

    expr = context.current_step.log
    output = await base_evaluate(expr, await context.prepare_for_step())

    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! Reviewed everything up to 3331cf1 in 29 seconds

    More details
    • Looked at 56 lines of code in 2 files
    • Skipped 0 files when reviewing.
    • Skipped posting 2 drafted comments based on config settings.
    1. agents-api/agents_api/activities/task_steps/log_step.py:21
    • Draft comment:
      Ensure that base_evaluate can handle all cases previously managed by render_template, including any specific variable handling like skip_vars.
    • Reason this comment was not posted:
      Confidence changes required: 50%
      The removal of the render_template function is appropriate given the context of the changes. However, the base_evaluate function should be checked for its ability to handle the same cases as render_template.
    2. agents-api/agents_api/activities/task_steps/prompt_step.py:77
    • Draft comment:
      Ensure that base_evaluate can handle all cases previously managed by render_template, including any specific variable handling like skip_vars. This applies to the changes in log_step.py as well.
    • Reason this comment was not posted:
      Confidence changes required: 50%
      The removal of the render_template function is appropriate given the context of the changes. However, the base_evaluate function should be checked for its ability to handle the same cases as render_template.

    Workflow ID: wflow_CAeETHtZCOGYrQ1w


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

    Copy link
    Contributor

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

    CI Feedback 🧐

    (Feedback updated until commit 3331cf1)

    A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

    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,
    leading to three test failures:

  • 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
    ...
    
    1334:  PASS  test_agent_queries:28 query: create agent sql                          1%
    1335:  PASS  test_agent_queries:44 query: create or update agent sql                2%
    1336:  PASS  test_agent_queries:63 query: update agent sql                          2%
    1337:  PASS  test_agent_queries:85 query: get agent not exists sql                  3%
    1338:  PASS  test_agent_queries:96 query: get agent exists sql                      3%
    1339:  PASS  test_agent_queries:111 query: list agents sql                          4%
    1340:  PASS  test_agent_queries:122 query: patch agent sql                          4%
    1341:  PASS  test_agent_queries:143 query: delete agent sql                         5%
    1342:  FAIL  test_agent_routes:9 route: unauthorized should fail                    5%
    1343:  FAIL  test_agent_routes:26 route: create agent                               6%
    1344:  FAIL  test_agent_routes:43 route: create agent with instructions             6%
    1345:  ─────────────────────── route: unauthorized should fail ────────────────────────
    1346:  Failed at tests/test_agent_routes.py                                          
    ...
    
    1467:  │ │              name = '_dsn'                                           │ │  
    1468:  │ │              self = TestArgumentResolver(                            │ │  
    1469:  │ │                     │   test=Test(                                   │ │  
    1470:  │ │                     │   │   fn=<function _ at 0x7fb9c99ab920>,       │ │  
    1471:  │ │                     │   │   module_name='test_agent_routes',         │ │  
    1472:  │ │                     │   │   id='ee816ee766d84a519cbd07d62019fe13',   │ │  
    1473:  │ │                     │   │   marker=None,                             │ │  
    1474:  │ │                     │   │   description='route: unauthorized should  │ │  
    1475:  │ │                     fail',                                           │ │  
    ...
    
    1594:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    1595:  │ │        0x7fb9c97b4bc0>                                               │ │  
    1596:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1597:  │                                                                          │  
    1598:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    1599:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    1600:  │                                                                          │  
    1601:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    1602:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    1603:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    1604:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    1605:  │   457 │   │   │   │   else:                                              │  
    1606:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    1638:  │   221 │   │   except self._cancelled_exc_class:                          │  
    1639:  │                                                                          │  
    1640:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1641:  │ │                args = ()                                             │ │  
    1642:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    1643:  │ │                       <starlette.testclient.TestClient object at     │ │  
    1644:  │ │                       0x7fb9c97b0dd0>>                               │ │  
    1645:  │ │              future = <Future at 0x7fb9c98745c0 state=finished       │ │  
    1646:  │ │                       raised ValueError>                             │ │  
    ...
    
    1650:  │ │               scope = None                                           │ │  
    1651:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    1652:  │ │                       object at 0x7fb9c97b4bc0>                      │ │  
    1653:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1654:  │                                                                          │  
    1655:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    1656:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    1657:  │                                                                          │  
    1658:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    1659:  │   772 │   │   )                                                          │  
    1660:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    1661:  │ ❱ 774 │   │   │   await receive()                                        │  
    1662:  │   775 │                                                                  │  
    1663:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    1664:  │   777 │   │   async def receive() -> typing.Any:                         │  
    1665:  │                                                                          │  
    1666:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1667:  │ │ message = {                                                          │ │  
    1668:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    1687:  │ │ message = None                                                       │ │  
    1688:  │ │    self = <starlette.testclient.TestClient object at 0x7fb9c97b0dd0> │ │  
    1689:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1690:  │                                                                          │  
    1691:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    1692:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    1693:  │                                                                          │  
    1694:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    1695:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    1731:  │   221 │   │   except self._cancelled_exc_class:                          │  
    1732:  │                                                                          │  
    1733:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    1734:  │ │                args = ()                                             │ │  
    1735:  │ │                func = <bound method TestClient.lifespan of           │ │  
    1736:  │ │                       <starlette.testclient.TestClient object at     │ │  
    1737:  │ │                       0x7fb9c97b0dd0>>                               │ │  
    1738:  │ │              future = <Future at 0x7fb9c97b4f20 state=finished       │ │  
    1739:  │ │                       raised ValueError>                             │ │  
    ...
    
    1846:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    1847:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    1848:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    1849:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    1850:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    1851:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    1852:  │                                                                          │  
    1853:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    1854:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    1874:  │ │   scope = {                                                          │ │  
    1875:  │ │           │   'type': 'lifespan',                                    │ │  
    1876:  │ │           │   'state': {},                                           │ │  
    1877:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    1878:  │ │           0x7fb9cb36f560>,                                           │ │  
    1879:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    1880:  │ │           0x7fb9d69767b0>                                            │ │  
    1881:  │ │           }                                                          │ │  
    1882:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    2104:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    2105:  │                                                                          │  
    2106:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    2107:  │   691 │   │   await receive()                                            │  
    2108:  │   692 │   │   try:                                                       │  
    2109:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    2110:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    2111:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    2112:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    2148:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2149:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2150:  │                                                                          │  
    2151:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2152:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2153:  │   209 │   │   try:                                                       │  
    2154:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2155:  │   211 │   │   except StopAsyncIteration:                                 │  
    2156:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2182:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2183:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2184:  │                                                                          │  
    2185:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2186:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2187:  │   209 │   │   try:                                                       │  
    2188:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2189:  │   211 │   │   except StopAsyncIteration:                                 │  
    2190:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2216:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2217:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2218:  │                                                                          │  
    2219:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2220:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2221:  │   209 │   │   try:                                                       │  
    2222:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2223:  │   211 │   │   except StopAsyncIteration:                                 │  
    2224:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2250:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2251:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2252:  │                                                                          │  
    2253:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2254:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2255:  │   209 │   │   try:                                                       │  
    2256:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2257:  │   211 │   │   except StopAsyncIteration:                                 │  
    2258:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2284:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2285:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2286:  │                                                                          │  
    2287:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2288:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2289:  │   209 │   │   try:                                                       │  
    2290:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2291:  │   211 │   │   except StopAsyncIteration:                                 │  
    2292:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2318:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2319:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2320:  │                                                                          │  
    2321:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2322:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2323:  │   209 │   │   try:                                                       │  
    2324:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2325:  │   211 │   │   except StopAsyncIteration:                                 │  
    2326:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2352:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2353:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2354:  │                                                                          │  
    2355:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2356:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2357:  │   209 │   │   try:                                                       │  
    2358:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2359:  │   211 │   │   except StopAsyncIteration:                                 │  
    2360:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2386:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2387:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2388:  │                                                                          │  
    2389:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2390:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2391:  │   209 │   │   try:                                                       │  
    2392:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2393:  │   211 │   │   except StopAsyncIteration:                                 │  
    2394:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2420:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2421:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2422:  │                                                                          │  
    2423:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2424:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2425:  │   209 │   │   try:                                                       │  
    2426:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2427:  │   211 │   │   except StopAsyncIteration:                                 │  
    2428:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2454:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2455:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2456:  │                                                                          │  
    2457:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2458:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2459:  │   209 │   │   try:                                                       │  
    2460:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2461:  │   211 │   │   except StopAsyncIteration:                                 │  
    2462:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2488:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    2489:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    2490:  │                                                                          │  
    2491:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    2492:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    2493:  │   209 │   │   try:                                                       │  
    2494:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    2495:  │   211 │   │   except StopAsyncIteration:                                 │  
    2496:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    2559:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2560:  │                                                                          │  
    2561:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    2562:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    2563:  │                                                                          │  
    2564:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    2565:  │    359 │   │                                                             │  
    2566:  │    360 │   │   if min_size > max_size:                                   │  
    2567:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    2568:  │    362 │   │                                                             │  
    2569:  │    363 │   │   if max_queries <= 0:                                      │  
    2570:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    2584:  │ │                        max_size = 4                                  │ │  
    2585:  │ │                        min_size = 10                                 │ │  
    2586:  │ │                           reset = None                               │ │  
    2587:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    2588:  │ │                                   0x7fb9c971d900>                    │ │  
    2589:  │ │                           setup = None                               │ │  
    2590:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2591:  ╰──────────────────────────────────────────────────────────────────────────╯  
    2592:  ValueError: min_size is greater than max_size                                 
    ...
    
    2669:  │ │         │   }                                                        │ │  
    2670:  │ │         )                                                            │ │  
    2671:  │ │  self = TestArgumentResolver(                                        │ │  
    2672:  │ │         │   test=Test(                                               │ │  
    2673:  │ │         │   │   fn=<function _ at 0x7fb9c99ab920>,                   │ │  
    2674:  │ │         │   │   module_name='test_agent_routes',                     │ │  
    2675:  │ │         │   │   id='ee816ee766d84a519cbd07d62019fe13',               │ │  
    2676:  │ │         │   │   marker=None,                                         │ │  
    2677:  │ │         │   │   description='route: unauthorized should fail',       │ │  
    ...
    
    2796:  │ │      resolved_args = {}                                              │ │  
    2797:  │ │               self = TestArgumentResolver(                           │ │  
    2798:  │ │                      │   test=Test(                                  │ │  
    2799:  │ │                      │   │   fn=<function _ at 0x7fb9c99ab920>,      │ │  
    2800:  │ │                      │   │   module_name='test_agent_routes',        │ │  
    2801:  │ │                      │   │   id='ee816ee766d84a519cbd07d62019fe13',  │ │  
    2802:  │ │                      │   │   marker=None,                            │ │  
    2803:  │ │                      │   │   description='route: unauthorized should │ │  
    2804:  │ │                      fail',                                          │ │  
    ...
    
    2829:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2830:  │                                                                          │  
    2831:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    2832:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    2833:  │                                                                          │  
    2834:  │   634 │   │   │   else:                                                  │  
    2835:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    2836:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    2837:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    2950:  │ │              name = '_dsn'                                           │ │  
    2951:  │ │              self = TestArgumentResolver(                            │ │  
    2952:  │ │                     │   test=Test(                                   │ │  
    2953:  │ │                     │   │   fn=<function _ at 0x7fb9c99ab920>,       │ │  
    2954:  │ │                     │   │   module_name='test_agent_routes',         │ │  
    2955:  │ │                     │   │   id='ee816ee766d84a519cbd07d62019fe13',   │ │  
    2956:  │ │                     │   │   marker=None,                             │ │  
    2957:  │ │                     │   │   description='route: unauthorized should  │ │  
    2958:  │ │                     fail',                                           │ │  
    ...
    
    2977:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    2978:  │ │                     0x7fb9c973fc20>,                                 │ │  
    2979:  │ │                     │   │   tags=[]                                  │ │  
    2980:  │ │                     │   ),                                           │ │  
    2981:  │ │                     │   iteration=0                                  │ │  
    2982:  │ │                     )                                                │ │  
    2983:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2984:  ╰──────────────────────────────────────────────────────────────────────────╯  
    2985:  FixtureError: Unable to resolve fixture 'client'                              
    2986:  ───────────────────────────── route: create agent ──────────────────────────────
    2987:  Failed at tests/test_agent_routes.py                                          
    ...
    
    3234:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    3235:  │ │        0x7fb9c97b6cc0>                                               │ │  
    3236:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3237:  │                                                                          │  
    3238:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3239:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    3240:  │                                                                          │  
    3241:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    3242:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    3243:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    3244:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    3245:  │   457 │   │   │   │   else:                                              │  
    3246:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    3278:  │   221 │   │   except self._cancelled_exc_class:                          │  
    3279:  │                                                                          │  
    3280:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3281:  │ │                args = ()                                             │ │  
    3282:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    3283:  │ │                       <starlette.testclient.TestClient object at     │ │  
    3284:  │ │                       0x7fb9c97b5df0>>                               │ │  
    3285:  │ │              future = <Future at 0x7fb9c97b7080 state=finished       │ │  
    3286:  │ │                       raised ValueError>                             │ │  
    ...
    
    3290:  │ │               scope = None                                           │ │  
    3291:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    3292:  │ │                       object at 0x7fb9c97b6cc0>                      │ │  
    3293:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3294:  │                                                                          │  
    3295:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3296:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    3297:  │                                                                          │  
    3298:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    3299:  │   772 │   │   )                                                          │  
    3300:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    3301:  │ ❱ 774 │   │   │   await receive()                                        │  
    3302:  │   775 │                                                                  │  
    3303:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    3304:  │   777 │   │   async def receive() -> typing.Any:                         │  
    3305:  │                                                                          │  
    3306:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3307:  │ │ message = {                                                          │ │  
    3308:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    3327:  │ │ message = None                                                       │ │  
    3328:  │ │    self = <starlette.testclient.TestClient object at 0x7fb9c97b5df0> │ │  
    3329:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3330:  │                                                                          │  
    3331:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3332:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    3333:  │                                                                          │  
    3334:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    3335:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    3371:  │   221 │   │   except self._cancelled_exc_class:                          │  
    3372:  │                                                                          │  
    3373:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    3374:  │ │                args = ()                                             │ │  
    3375:  │ │                func = <bound method TestClient.lifespan of           │ │  
    3376:  │ │                       <starlette.testclient.TestClient object at     │ │  
    3377:  │ │                       0x7fb9c97b5df0>>                               │ │  
    3378:  │ │              future = <Future at 0x7fb9c97b6fc0 state=finished       │ │  
    3379:  │ │                       raised ValueError>                             │ │  
    ...
    
    3486:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    3487:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    3488:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    3489:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    3490:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    3491:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    3492:  │                                                                          │  
    3493:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    3494:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    3514:  │ │   scope = {                                                          │ │  
    3515:  │ │           │   'type': 'lifespan',                                    │ │  
    3516:  │ │           │   'state': {},                                           │ │  
    3517:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    3518:  │ │           0x7fb9cb36f560>,                                           │ │  
    3519:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    3520:  │ │           0x7fb9d69767b0>                                            │ │  
    3521:  │ │           }                                                          │ │  
    3522:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    3744:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    3745:  │                                                                          │  
    3746:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    3747:  │   691 │   │   await receive()                                            │  
    3748:  │   692 │   │   try:                                                       │  
    3749:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    3750:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    3751:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    3752:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    3788:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3789:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3790:  │                                                                          │  
    3791:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3792:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3793:  │   209 │   │   try:                                                       │  
    3794:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3795:  │   211 │   │   except StopAsyncIteration:                                 │  
    3796:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3822:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3823:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3824:  │                                                                          │  
    3825:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3826:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3827:  │   209 │   │   try:                                                       │  
    3828:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3829:  │   211 │   │   except StopAsyncIteration:                                 │  
    3830:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3856:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3857:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3858:  │                                                                          │  
    3859:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3860:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3861:  │   209 │   │   try:                                                       │  
    3862:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3863:  │   211 │   │   except StopAsyncIteration:                                 │  
    3864:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3890:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3891:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3892:  │                                                                          │  
    3893:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3894:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3895:  │   209 │   │   try:                                                       │  
    3896:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3897:  │   211 │   │   except StopAsyncIteration:                                 │  
    3898:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3924:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3925:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3926:  │                                                                          │  
    3927:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3928:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3929:  │   209 │   │   try:                                                       │  
    3930:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3931:  │   211 │   │   except StopAsyncIteration:                                 │  
    3932:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3958:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3959:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3960:  │                                                                          │  
    3961:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3962:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3963:  │   209 │   │   try:                                                       │  
    3964:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3965:  │   211 │   │   except StopAsyncIteration:                                 │  
    3966:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    3992:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    3993:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    3994:  │                                                                          │  
    3995:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    3996:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    3997:  │   209 │   │   try:                                                       │  
    3998:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    3999:  │   211 │   │   except StopAsyncIteration:                                 │  
    4000:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4026:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4027:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4028:  │                                                                          │  
    4029:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4030:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4031:  │   209 │   │   try:                                                       │  
    4032:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4033:  │   211 │   │   except StopAsyncIteration:                                 │  
    4034:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4060:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4061:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4062:  │                                                                          │  
    4063:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4064:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4065:  │   209 │   │   try:                                                       │  
    4066:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4067:  │   211 │   │   except StopAsyncIteration:                                 │  
    4068:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4094:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4095:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4096:  │                                                                          │  
    4097:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4098:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4099:  │   209 │   │   try:                                                       │  
    4100:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4101:  │   211 │   │   except StopAsyncIteration:                                 │  
    4102:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4128:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    4129:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    4130:  │                                                                          │  
    4131:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    4132:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    4133:  │   209 │   │   try:                                                       │  
    4134:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    4135:  │   211 │   │   except StopAsyncIteration:                                 │  
    4136:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    4199:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4200:  │                                                                          │  
    4201:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    4202:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    4203:  │                                                                          │  
    4204:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    4205:  │    359 │   │                                                             │  
    4206:  │    360 │   │   if min_size > max_size:                                   │  
    4207:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    4208:  │    362 │   │                                                             │  
    4209:  │    363 │   │   if max_queries <= 0:                                      │  
    4210:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    4224:  │ │                        max_size = 4                                  │ │  
    4225:  │ │                        min_size = 10                                 │ │  
    4226:  │ │                           reset = None                               │ │  
    4227:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    4228:  │ │                                   0x7fb9c37d8a00>                    │ │  
    4229:  │ │                           setup = None                               │ │  
    4230:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4231:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4232:  ValueError: min_size is greater than max_size                                 
    ...
    
    4610:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4611:  │                                                                          │  
    4612:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    4613:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    4614:  │                                                                          │  
    4615:  │   634 │   │   │   else:                                                  │  
    4616:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    4617:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    4618:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    4757:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    4758:  │ │                     0x7fb9c9875be0>,                                 │ │  
    4759:  │ │                     │   │   tags=[]                                  │ │  
    4760:  │ │                     │   ),                                           │ │  
    4761:  │ │                     │   iteration=0                                  │ │  
    4762:  │ │                     )                                                │ │  
    4763:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    4764:  ╰──────────────────────────────────────────────────────────────────────────╯  
    4765:  FixtureError: Unable to resolve fixture 'client'                              
    4766:  ──────────────────── route: create agent with instructions ─────────────────────
    4767:  Failed at tests/test_agent_routes.py                                          
    ...
    
    5015:  │ │ self = <anyio._backends._asyncio.BlockingPortal object at            │ │  
    5016:  │ │        0x7fb9c97b7e90>                                               │ │  
    5017:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5018:  │                                                                          │  
    5019:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5020:  │ python3.12/concurrent/futures/_base.py:456 in result                     │  
    5021:  │                                                                          │  
    5022:  │   453 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    5023:  │   454 │   │   │   │   │   raise CancelledError()                         │  
    5024:  │   455 │   │   │   │   elif self._state == FINISHED:                      │  
    5025:  │ ❱ 456 │   │   │   │   │   return self.__get_result()                     │  
    5026:  │   457 │   │   │   │   else:                                              │  
    5027:  │   458 │   │   │   │   │   raise TimeoutError()                           │  
    ...
    
    5059:  │   221 │   │   except self._cancelled_exc_class:                          │  
    5060:  │                                                                          │  
    5061:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5062:  │ │                args = ()                                             │ │  
    5063:  │ │                func = <bound method TestClient.wait_startup of       │ │  
    5064:  │ │                       <starlette.testclient.TestClient object at     │ │  
    5065:  │ │                       0x7fb9c97b7170>>                               │ │  
    5066:  │ │              future = <Future at 0x7fb9c850c290 state=finished       │ │  
    5067:  │ │                       raised ValueError>                             │ │  
    ...
    
    5071:  │ │               scope = None                                           │ │  
    5072:  │ │                self = <anyio._backends._asyncio.BlockingPortal       │ │  
    5073:  │ │                       object at 0x7fb9c97b7e90>                      │ │  
    5074:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5075:  │                                                                          │  
    5076:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5077:  │ ges/starlette/testclient.py:774 in wait_startup                          │  
    5078:  │                                                                          │  
    5079:  │   771 │   │   │   "lifespan.startup.failed",                             │  
    5080:  │   772 │   │   )                                                          │  
    5081:  │   773 │   │   if message["type"] == "lifespan.startup.failed":           │  
    5082:  │ ❱ 774 │   │   │   await receive()                                        │  
    5083:  │   775 │                                                                  │  
    5084:  │   776 │   async def wait_shutdown(self) -> None:                         │  
    5085:  │   777 │   │   async def receive() -> typing.Any:                         │  
    5086:  │                                                                          │  
    5087:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5088:  │ │ message = {                                                          │ │  
    5089:  │ │           │   'type': 'lifespan.startup.failed',                     │ │  
    ...
    
    5108:  │ │ message = None                                                       │ │  
    5109:  │ │    self = <starlette.testclient.TestClient object at 0x7fb9c97b7170> │ │  
    5110:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5111:  │                                                                          │  
    5112:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5113:  │ python3.12/concurrent/futures/_base.py:449 in result                     │  
    5114:  │                                                                          │  
    5115:  │   446 │   │   │   │   if self._state in [CANCELLED, CANCELLED_AND_NOTIFI │  
    5116:  │   447 │   │   │   │   │   raise CancelledError()                         │  
    ...
    
    5152:  │   221 │   │   except self._cancelled_exc_class:                          │  
    5153:  │                                                                          │  
    5154:  │ ╭─────────────────────────────── locals ───────────────────────────────╮ │  
    5155:  │ │                args = ()                                             │ │  
    5156:  │ │                func = <bound method TestClient.lifespan of           │ │  
    5157:  │ │                       <starlette.testclient.TestClient object at     │ │  
    5158:  │ │                       0x7fb9c97b7170>>                               │ │  
    5159:  │ │              future = <Future at 0x7fb9c850c1d0 state=finished       │ │  
    5160:  │ │                       raised ValueError>                             │ │  
    ...
    
    5267:  │ │           waiting_senders=OrderedDict()), _closed=False),            │ │  
    5268:  │ │           receive_stream=MemoryObjectReceiveStream(_state=MemoryObj… │ │  
    5269:  │ │           buffer=deque([]), open_send_channels=1,                    │ │  
    5270:  │ │           open_receive_channels=1, waiting_receivers=OrderedDict(),  │ │  
    5271:  │ │           waiting_senders=OrderedDict()), _closed=False))>           │ │  
    5272:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5273:  │                                                                          │  
    5274:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5275:  │ ges/starlette/middleware/errors.py:152 in __call__                       │  
    ...
    
    5295:  │ │   scope = {                                                          │ │  
    5296:  │ │           │   'type': 'lifespan',                                    │ │  
    5297:  │ │           │   'state': {},                                           │ │  
    5298:  │ │           │   'app': <fastapi.applications.FastAPI object at         │ │  
    5299:  │ │           0x7fb9cb36f560>,                                           │ │  
    5300:  │ │           │   'router': <fastapi.routing.APIRouter object at         │ │  
    5301:  │ │           0x7fb9d69767b0>                                            │ │  
    5302:  │ │           }                                                          │ │  
    5303:  │ │    self = <starlette.middleware.errors.ServerErrorMiddleware object  │ │  
    ...
    
    5525:  │ ges/starlette/routing.py:693 in lifespan                                 │  
    5526:  │                                                                          │  
    5527:  │   690 │   │   app: typing.Any = scope.get("app")                         │  
    5528:  │   691 │   │   await receive()                                            │  
    5529:  │   692 │   │   try:                                                       │  
    5530:  │ ❱ 693 │   │   │   async with self.lifespan_context(app) as maybe_state:  │  
    5531:  │   694 │   │   │   │   if maybe_state is not None:                        │  
    5532:  │   695 │   │   │   │   │   if "state" not in scope:                       │  
    5533:  │   696 │   │   │   │   │   │   raise RuntimeError('The server does not su │  
    ...
    
    5569:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5570:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5571:  │                                                                          │  
    5572:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5573:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5574:  │   209 │   │   try:                                                       │  
    5575:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5576:  │   211 │   │   except StopAsyncIteration:                                 │  
    5577:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5603:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5604:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5605:  │                                                                          │  
    5606:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5607:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5608:  │   209 │   │   try:                                                       │  
    5609:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5610:  │   211 │   │   except StopAsyncIteration:                                 │  
    5611:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5637:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5638:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5639:  │                                                                          │  
    5640:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5641:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5642:  │   209 │   │   try:                                                       │  
    5643:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5644:  │   211 │   │   except StopAsyncIteration:                                 │  
    5645:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5671:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5672:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5673:  │                                                                          │  
    5674:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5675:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5676:  │   209 │   │   try:                                                       │  
    5677:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5678:  │   211 │   │   except StopAsyncIteration:                                 │  
    5679:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5705:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5706:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5707:  │                                                                          │  
    5708:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5709:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5710:  │   209 │   │   try:                                                       │  
    5711:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5712:  │   211 │   │   except StopAsyncIteration:                                 │  
    5713:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5739:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5740:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5741:  │                                                                          │  
    5742:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5743:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5744:  │   209 │   │   try:                                                       │  
    5745:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5746:  │   211 │   │   except StopAsyncIteration:                                 │  
    5747:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5773:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5774:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5775:  │                                                                          │  
    5776:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5777:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5778:  │   209 │   │   try:                                                       │  
    5779:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5780:  │   211 │   │   except StopAsyncIteration:                                 │  
    5781:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5807:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5808:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5809:  │                                                                          │  
    5810:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5811:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5812:  │   209 │   │   try:                                                       │  
    5813:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5814:  │   211 │   │   except StopAsyncIteration:                                 │  
    5815:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5841:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5842:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5843:  │                                                                          │  
    5844:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5845:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5846:  │   209 │   │   try:                                                       │  
    5847:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5848:  │   211 │   │   except StopAsyncIteration:                                 │  
    5849:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5875:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5876:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5877:  │                                                                          │  
    5878:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5879:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5880:  │   209 │   │   try:                                                       │  
    5881:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5882:  │   211 │   │   except StopAsyncIteration:                                 │  
    5883:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5909:  │ /home/runner/.local/share/uv/python/cpython-3.12.8-linux-x86_64-gnu/lib/ │  
    5910:  │ python3.12/contextlib.py:210 in __aenter__                               │  
    5911:  │                                                                          │  
    5912:  │   207 │   │   # they are only needed for recreation, which is not possib │  
    5913:  │   208 │   │   del self.args, self.kwds, self.func                        │  
    5914:  │   209 │   │   try:                                                       │  
    5915:  │ ❱ 210 │   │   │   return await anext(self.gen)                           │  
    5916:  │   211 │   │   except StopAsyncIteration:                                 │  
    5917:  │   212 │   │   │   raise RuntimeError("generator didn't yield") from None │  
    ...
    
    5980:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    5981:  │                                                                          │  
    5982:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    5983:  │ ges/asyncpg/pool.py:361 in __init__                                      │  
    5984:  │                                                                          │  
    5985:  │    358 │   │   │   │   'min_size is expected to be greater or equal to z │  
    5986:  │    359 │   │                                                             │  
    5987:  │    360 │   │   if min_size > max_size:                                   │  
    5988:  │ ❱  361 │   │   │   raise ValueError('min_size is greater than max_size') │  
    5989:  │    362 │   │                                                             │  
    5990:  │    363 │   │   if max_queries <= 0:                                      │  
    5991:  │    364 │   │   │   raise ValueError('max_queries is expected to be great │  
    ...
    
    6005:  │ │                        max_size = 4                                  │ │  
    6006:  │ │                        min_size = 10                                 │ │  
    6007:  │ │                           reset = None                               │ │  
    6008:  │ │                            self = <asyncpg.pool.Pool object at       │ │  
    6009:  │ │                                   0x7fb9c37d9180>                    │ │  
    6010:  │ │                           setup = None                               │ │  
    6011:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6012:  ╰──────────────────────────────────────────────────────────────────────────╯  
    6013:  ValueError: min_size is greater than max_size                                 
    ...
    
    6393:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6394:  │                                                                          │  
    6395:  │ /home/runner/work/julep/julep/agents-api/.venv/lib/python3.12/site-packa │  
    6396:  │ ges/ward/testing.py:637 in _resolve_single_arg                           │  
    6397:  │                                                                          │  
    6398:  │   634 │   │   │   else:                                                  │  
    6399:  │   635 │   │   │   │   fixture.resolved_val = arg(**args_to_inject)       │  
    6400:  │   636 │   │   except (Exception, SystemExit) as e:                       │  
    6401:  │ ❱ 637 │   │   │   raise FixtureError(f"Unable to resolve fixture '{fixtu │  
    ...
    
    6541:  │ │                     │   │   timer=<ward._testing._Timer object at    │ │  
    6542:  │ │                     0x7fb9c973f290>,                                 │ │  
    6543:  │ │                     │   │   tags=[]                                  │ │  
    6544:  │ │                     │   ),                                           │ │  
    6545:  │ │                     │   iteration=0                                  │ │  
    6546:  │ │                     )                                                │ │  
    6547:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    6548:  ╰──────────────────────────────────────────────────────────────────────────╯  
    6549:  FixtureError: Unable to resolve fixture 'client'                              
    6550:  ────────────────────────────────────────────────────────────────────────────────
    6551:  ╭──────────── Results ─────────────╮
    6552:  │  12  Tests Encountered           │
    6553:  │   9  Passes             (75.0%)  │
    6554:  │   3  Failures           (25.0%)  │
    6555:  ╰──────────────────────────────────╯
    6556:  ─────────────────────────── FAILED in 57.23 seconds ────────────────────────────
    6557:  ##[error]Process completed with exit code 1.
    

    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Validate prompt message structure

    Validate that prompt messages in the list have required 'role' and 'content' fields
    to prevent runtime errors.

    agents-api/agents_api/activities/task_steps/prompt_step.py [78]

    -prompt = prompt if isinstance(prompt, list) else [{"role": "user", "content": prompt}]
    +if isinstance(prompt, list):
    +    for msg in prompt:
    +        if not isinstance(msg, dict) or 'role' not in msg or 'content' not in msg:
    +            raise ApplicationError("Each prompt message must be a dict with 'role' and 'content' fields")
    +else:
    +    prompt = [{"role": "user", "content": prompt}]
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: This validation is crucial for preventing runtime errors by ensuring the prompt messages have the required structure before processing. Without this check, malformed messages could cause failures in downstream operations.

    9
    Add error handling for evaluation

    Add error handling for base_evaluate call to properly handle evaluation failures and
    provide meaningful error messages.

    agents-api/agents_api/activities/task_steps/log_step.py [20-21]

     expr = context.current_step.log
    -output = await base_evaluate(expr, await context.prepare_for_step())
    +try:
    +    output = await base_evaluate(expr, await context.prepare_for_step())
    +except Exception as eval_error:
    +    raise ApplicationError(f"Failed to evaluate log expression: {str(eval_error)}")
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: Adding specific error handling for base_evaluate is important for debugging and error reporting, especially since this replaces the previous template rendering system. The suggestion provides more granular error information.

    8

    @whiterabbit1983 whiterabbit1983 merged commit 3331cf1 into dev Jan 24, 2025
    11 of 15 checks passed
    @whiterabbit1983 whiterabbit1983 deleted the c/remove-jinja-templates branch January 24, 2025 06:45
    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