Skip to content

Commit f60d7ba

Browse files
salmon131awharrison-28dluc
authored
Fix functions_view.py (#1213)
### Motivation and Context #1212 ### Description Fixed a bug in the process of checking native function. --------- Co-authored-by: Abby Harrison <[email protected]> Co-authored-by: Devis Lucato <[email protected]>
1 parent b2e1548 commit f60d7ba

File tree

2 files changed

+166
-1
lines changed

2 files changed

+166
-1
lines changed

python/semantic_kernel/skill_definition/functions_view.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,17 @@ def is_semantic(self, skill_name: str, function_name: str) -> bool:
4343
return as_sf
4444

4545
def is_native(self, skill_name: str, function_name: str) -> bool:
46-
return not self.is_semantic(skill_name, function_name)
46+
as_sf = self._semantic_functions.get(skill_name, [])
47+
as_sf = any(f.name == function_name for f in as_sf)
48+
49+
as_nf = self._native_functions.get(skill_name, [])
50+
as_nf = any(f.name == function_name for f in as_nf)
51+
52+
if as_sf and as_nf:
53+
raise KernelException(
54+
KernelException.ErrorCodes.AmbiguousImplementation,
55+
f"There are 2 functions with the same name: {function_name}."
56+
f"One is native and the other semantic.",
57+
)
58+
59+
return as_nf
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Copyright (c) Microsoft. All rights reserved.
2+
3+
import pytest
4+
from semantic_kernel.kernel_exception import KernelException
5+
from semantic_kernel.skill_definition.function_view import FunctionView
6+
from semantic_kernel.skill_definition.functions_view import FunctionsView, FunctionView
7+
8+
9+
def test_add_semantic_function():
10+
view = FunctionView(
11+
name="function1",
12+
skill_name="skill1",
13+
description="Semantic function",
14+
parameters=[],
15+
is_semantic=True,
16+
is_asynchronous=True,
17+
)
18+
functions_view = FunctionsView()
19+
functions_view.add_function(view)
20+
semantic_functions = functions_view._semantic_functions.get("skill1")
21+
assert len(semantic_functions) == 1
22+
assert semantic_functions[0] == view
23+
24+
25+
def test_add_native_function():
26+
view = FunctionView(
27+
name="function2",
28+
skill_name="skill2",
29+
description="Native function",
30+
parameters=[],
31+
is_semantic=False,
32+
is_asynchronous=True,
33+
)
34+
functions_view = FunctionsView()
35+
functions_view.add_function(view)
36+
native_functions = functions_view._native_functions.get("skill2")
37+
assert len(native_functions) == 1
38+
assert native_functions[0] == view
39+
40+
41+
def test_add_multiple_functions():
42+
semantic_function = FunctionView(
43+
name="function1",
44+
skill_name="skill1",
45+
description="Semantic function",
46+
parameters=[],
47+
is_semantic=True,
48+
is_asynchronous=True,
49+
)
50+
native_function = FunctionView(
51+
name="function2",
52+
skill_name="skill2",
53+
description="Native function",
54+
parameters=[],
55+
is_semantic=False,
56+
is_asynchronous=True,
57+
)
58+
functions_view = FunctionsView()
59+
functions_view.add_function(semantic_function)
60+
functions_view.add_function(native_function)
61+
semantic_functions = functions_view._semantic_functions.get("skill1")
62+
native_functions = functions_view._native_functions.get("skill2")
63+
assert len(semantic_functions) == 1
64+
assert semantic_functions[0] == semantic_function
65+
assert len(native_functions) == 1
66+
assert native_functions[0] == native_function
67+
68+
69+
def test_is_semantic():
70+
semantic_function = FunctionView(
71+
name="function1",
72+
skill_name="skill1",
73+
description="Semantic function",
74+
parameters=[],
75+
is_semantic=True,
76+
is_asynchronous=True,
77+
)
78+
native_function = FunctionView(
79+
name="function2",
80+
skill_name="skill2",
81+
description="Native function",
82+
parameters=[],
83+
is_semantic=False,
84+
is_asynchronous=True,
85+
)
86+
functions_view = FunctionsView()
87+
functions_view.add_function(semantic_function)
88+
functions_view.add_function(native_function)
89+
assert functions_view.is_semantic("skill1", "function1") is True
90+
assert functions_view.is_semantic("skill2", "function2") is False
91+
assert functions_view.is_semantic("skill1", "unregistered_function") is False
92+
93+
94+
def test_is_native():
95+
semantic_function = FunctionView(
96+
name="function1",
97+
skill_name="skill1",
98+
description="Semantic function",
99+
parameters=[],
100+
is_semantic=True,
101+
is_asynchronous=True,
102+
)
103+
native_function = FunctionView(
104+
name="function2",
105+
skill_name="skill2",
106+
description="Native function",
107+
parameters=[],
108+
is_semantic=False,
109+
is_asynchronous=True,
110+
)
111+
functions_view = FunctionsView()
112+
functions_view.add_function(semantic_function)
113+
functions_view.add_function(native_function)
114+
assert functions_view.is_native("skill1", "function1") is False
115+
assert functions_view.is_native("skill2", "function2") is True
116+
assert functions_view.is_native("skill2", "unregistered_function") is False
117+
118+
119+
def test_ambiguous_implementation():
120+
semantic_function = FunctionView(
121+
name="function1",
122+
skill_name="skill1",
123+
description="Semantic function",
124+
parameters=[],
125+
is_semantic=True,
126+
is_asynchronous=True,
127+
)
128+
native_function = FunctionView(
129+
name="function1",
130+
skill_name="skill1",
131+
description="Native function",
132+
parameters=[],
133+
is_semantic=False,
134+
is_asynchronous=True,
135+
)
136+
functions_view = FunctionsView()
137+
functions_view.add_function(semantic_function)
138+
functions_view.add_function(native_function)
139+
140+
with pytest.raises(KernelException) as exc_info:
141+
functions_view.is_semantic("skill1", "function1")
142+
143+
assert (
144+
exc_info.value.error_code == KernelException.ErrorCodes.AmbiguousImplementation
145+
)
146+
147+
with pytest.raises(KernelException) as exc_info:
148+
functions_view.is_native("skill1", "function1")
149+
150+
assert (
151+
exc_info.value.error_code == KernelException.ErrorCodes.AmbiguousImplementation
152+
)

0 commit comments

Comments
 (0)