-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Python: New Feature: more generic KernelFunctionFromMethod
parameter parsing in Python
#10008
Comments
KernelFunctionFromMethod
parameter parsing in PythonKernelFunctionFromMethod
parameter parsing in Python
@Druid-of-Luhn thanks for reaching out, I've looked a bit into this, and indeed when a Union (or | ) is used we don't do any parsing of the values since we can't know which one is meant and it becomes very expensive to do that for all cases, for instance what if one is a known type and the other is a forwardref, then we can't parse the second, so what would we do? I did check and BaseModel's work, when I took this function and run it with a dict as input, it does work (with this code): async def test_kernel_function_invoke(kernel: Kernel):
decorator_test = MiscClass()
my_func = getattr(decorator_test, "func_input_object_annotated")
input_obj = dict(arg1="test", arg2=1)
kernel.add_function(plugin_name="test", function=my_func)
result = await kernel.invoke(function_name="func_input_object_annotated", plugin_name="test", input=input_obj)
assert result.value == input_obj Also there is a escape for more complex scenario's and that is to set the Let me know if this helps! |
@eavanvalkenburg Thanks for the explanation and how to get around some cases. I had spotted the potential for the |
hmm I haven't spent much time on the process side of things, @moonbox3 can you have a look? |
Hi @Druid-of-Luhn, could you give a more concrete example, please, of what you want to achieve in the process framework?
This is currently true about how we handle the "fan-in" behavior from previous steps -- we are making sure that for the given kernel function signature, we have all of the required parameters, which could be coming from different (previous) steps. In any case, I would love to see further details, if possible. Thanks. |
The diagram below should illustrate the case that led to me raising this request. One step can emit one of two events, which fan out. Depending on the event, it might skip one of the fanned-out steps. The step that it may skip outputs a different type of data in its event, meaning that the fan-in step doesn't know what type of data it is receiving (in my case, it is one of two types). So in the diagram below, the fan-in step flowchart LR
START --> A
A -->|Path1, data=ClassX| B
A -->|Path1&2, data=ClassX| C
A -->|Path2, data=ClassX| D
B -->|Path1, data=ClassY| D
C -->|Path1&2, data=ClassZ| D
D --> END
At the moment, since the fan-in only happens at the end of the process, I have just removed it and used |
It sounds like the case where the variants are pydantic classes can be solved by emitting the values as |
name: Feature request
about: Suggest an idea for this project
When creating a
KernelFunction
from a method in Python, theKernelFunctionFromMethod._parse_parameter
method is called to verify the values passed to the function against the function definition.It performs a series of checks to handle different cases:
model_validate
method (it's a pydantic type): validate the value's model; this does not allow base classes likeBaseModel
to be used as function arguments, because themodel_validate
method tries to instantiate the class, which fails for base classes, nor does it work for aUnion
of concrete pydantic classes.BaseModel
to be used as function arguments.int
andstr
; this does not work withUnion
orAny
.This seems to mean that function argument types for kernel functions must be specific: they can't be
Union
s,Any
or pydantic base classes (likeBaseModel
orKernelBaseModel
).In the process framework, this prevents me from creating a generic step (which accepts all types of event payload, for example, or some subset of types). I would need to create some kind of non-abstract base class to replicate the desired behaviour. Ideally I could just specify the types as
Any
orUnion[...]
orBaseModel
.Would this be possible?
The text was updated successfully, but these errors were encountered: