Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions autogen/fast_depends/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ def _solve(
if (v := kwargs.pop(arg, Parameter.empty)) is not Parameter.empty:
kw[arg] = v

# Positional parameters can also be supplied by name (e.g. when an LLM
# tool call delivers all arguments as keyword args). Pull them out
# before assigning the remainder to ``var_keyword_arg`` so they don't
# get swallowed into ``**kwargs``.
if self.var_keyword_arg is not None:
for arg in self.positional_args:
if (v := kwargs.pop(arg, Parameter.empty)) is not Parameter.empty:
kw[arg] = v

if self.var_keyword_arg is not None:
kw[self.var_keyword_arg] = kwargs
else:
Expand Down
15 changes: 15 additions & 0 deletions test/fast_depends/async/test_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,21 @@ async def simple_func(
assert await simple_func(1.0, 2.0, 3, b=3.0, key=1.0) == (1, (2.0, 3.0), 3, {"key": 1})


@pytest.mark.anyio
async def test_positional_args_passed_by_name_with_var_keyword():
"""Regression for ag2 #1790 — async path."""

@inject
async def simple_func(
arg1: str,
arg2: str,
**kwargs: dict[str, str],
):
return arg1, arg2, kwargs

assert await simple_func(arg1="x", arg2="y", extra="z") == ("x", "y", {"extra": "z"})


@pytest.mark.anyio
async def test_args_kwargs_2():
@inject
Expand Down
19 changes: 19 additions & 0 deletions test/fast_depends/sync/test_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,25 @@ def simple_func(
assert simple_func(1.0, 2.0, 3, b=3.0, key=1.0) == (1, (2.0, 3.0), 3, {"key": 1})


def test_positional_args_passed_by_name_with_var_keyword():
"""Regression for ag2 #1790.

When a function has positional-or-keyword params and a ``**kwargs``, all
arguments may arrive as keyword args (e.g. from an LLM tool call). The
positional names must not be swept into ``**kwargs``.
"""

@inject
def simple_func(
arg1: str,
arg2: str,
**kwargs: dict[str, str],
):
return arg1, arg2, kwargs

assert simple_func(arg1="x", arg2="y", extra="z") == ("x", "y", {"extra": "z"})


def test_args_kwargs_2():
@inject
def simple_func(
Expand Down
Loading