Native Python Function not returning correct result
Describe the bug
I have written a native Python function, but it does not appear to be returning the expected value. Instead, it just returns its input
To Reproduce Steps to reproduce the behavior:
I have a file native_function.py which contains:
from semantic_kernel.skill_definition import sk_function
class PythonGroundingSkill:
@sk_function(
description="Extract contents of <json_block> tags",
name="ParseJsonBlock",
)
def extract_json_block_from_text(self, text: str):
start_tag = "<json_block>"
end_tag = "</json_block>"
i_0 = text.find(start_tag) + len(start_tag)
i_1 = text.find(end_tag)
extracted_text = text[i_0:i_1]
print(f"=~=~=~=\n{extracted_text}\n=~=~=~=\n")
return extracted_text
I then call it through the following file:
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import AzureTextCompletion, OpenAITextCompletion
kernel = sk.Kernel()
useAzureOpenAI = True
# Configure AI service used by the kernel
if useAzureOpenAI:
deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
kernel.add_text_completion_service("dv", AzureTextCompletion(deployment, endpoint, api_key))
else:
api_key, org_id = sk.openai_settings_from_dot_env()
kernel.add_text_completion_service("dv", OpenAITextCompletion("text-davinci-003", api_key, org_id))
skills_directory = "../../skills"
groundingNativeFunctions = kernel.import_native_skill_from_directory(skills_directory, "GroundingSkill")
jsonblock_fetch = groundingNativeFunctions["ParseJsonBlock"]
function_result = jsonblock_fetch("something <json_block>[0, 1]</json_block> something else")
print(function_result.result)
I get output
=~=~=~=
[0, 1]
=~=~=~=
something <json_block>[0, 1]</json_block> something else
So internally, the function is doing the right thing (as seen from the =~=~ bits), but the returned value was the original string, not the return value of the function defined.
Expected behavior
If I return a value from a function, I would like to receive that value back.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: Win11 / Python 3.11
- IDE: [e.g. Visual Studio, VS Code]
- NuGet Package Version [e.g. 0.1.0]
Additional context
Name: semantic-kernel
Version: 0.2.7.dev0
Summary:
Home-page:
Author: Microsoft
Author-email: [email protected]
This behaviour would be consistent with the following being the only 'Python native' sample test function: https://github.com/microsoft/semantic-kernel/blob/11d77358ef5ba1be7eb7f26fee352a0a7761df59/python/tests/test_native_skills/TestNativeSkill/native_function.py
I had similar issue today , can you try adding a return type hint ? e.g.
def extract_json_block_from_text(self, text: str): -> str
Looking a bit more at this. When there is no return type it infers a DelegateTypes.Void.
- It would probably be better to raise an exception in this case and infers Void when it's explicit.
DelegateTypes.Voidshould also not return $input
OK, so changing the signature to -> str did indeed let it get back the right information.
However, when I try changing the return type to ->Union[Dict[str,Any], List[Any]] (which is what I'd like it to be long-term), it still doesn't work. Now, the function apparently isn't even in the dictionary. Why is this?
Looking a bit more at this. When there is no return type it infers a
DelegateTypes.Void.
- It would probably be better to raise an exception in this case and infers Void when it's explicit.
DelegateTypes.Voidshould also not return $input
Given that type hints aren't usually required in Python and that -> None is allowable, I think raising an exception for a forgotten return value would be a very good idea.
@mkarle can you take a look at this.
Team triage: improve function signature detection
OK, so changing the signature to
-> strdid indeed let it get back the right information.However, when I try changing the return type to
->Union[Dict[str,Any], List[Any]](which is what I'd like it to be long-term), it still doesn't work. Now, the function apparently isn't even in the dictionary. Why is this?
Even I am facing the same issue. I want my native function to return dict and list values as well, but it only returns string values.
Right now you can only return None, str, and SKContext types. You can put dict and list values in the SKContext object though.
Right now you can only return None, str, and SKContext types. You can put dict and list values in the SKContext object though.
Can you give an example of how to use SKContext for returning a JSON or a dict object in Python.