-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
.Net: Don't limit [KernelFunction] to public methods #6206
.Net: Don't limit [KernelFunction] to public methods #6206
Conversation
A developer already need to opt-in a method on a plugin to being part of the plugin by specifying the [KernelFunction] attribute; requiring that method to also be public is superfluous, and means that a type's plugin surface area must be a subset of its public surface area. That prohibits patterns where a type wants to syntactically be a plugin but not expose those APIs via its .NET public surface area.
@stephentoub I was actually thinking about the idea of allowing to import plugins without But with changes in this PR, I'm not sure if the idea above will work, because it will also import something that is not part of public API, which would be kind of incorrect. Would be interesting to hear your opinion about this! |
Just including all public methods of an existing type is unlikely to yield a good plugin. The APIs are very likely to lack the metadata (e.g. Description) that would allow the methods to be appropriately described to the model. There's also very commonly functionality on these types that would not want included, whether they be operators, or methods from a base type (e.g. everything defined on System.Object), or interface implementations for common things like IEquatable, etc.
Nothing prevents having another overload of methods like CreateFromObject/Type that looks for something other than [KernelFunction], e.g. an extra bool argument. But, as noted above, I'm not convinced that's actually desirable. |
We can define on our side what is common and filter that, for example methods like But anyway, just a proposal I was thinking about for some period of time :) |
I would add a dedicated Attribute |
Recently we were discussing the possibility of having generic methods being able to me marked as |
Why is language visibility synonymous with Opem/Closed? KernelFunctionAttribute is just another domain of deciding what's open/closed. It's its own language for it. That's one of the reasons I don't like the public requirement... it's conflating two different schemes unnecessarily. |
Seems fine. |
I can't deny that we may want to expose methods to AI but not to the developer, but this can create a potential vector of attack for developers using plugins functions directly to be able to access those private methods as
Don't need to be |
I don't understand. The developer of the plugin is explicitly marking the method with the attribute... from a safety perspective, how is that any different than explicitly marking it as public? Why is:
any safer than:
? Those both work today, yet the latter method is not visible via the language to a consumer. |
One example. Assuming I don't want to expose the GetToken. IMHO when I implement something as private, it in theory should officially not be inaccessible to the public API's at any moment, overall there is not a problem adding public class A
{
[KernelMethod]
private string GetToken()
[KernelMethod]
public string GetEmails()
}
// Not public
var a = new A();
a.GetToken() -> Fails
// Works using this way (public)
var functions = kernel.ImportPluginFromType<A>();
var protectedToken = await functions["GetToken"].Invoke(kernel); |
Then don't mark it as [KernelFunction], the entire point of which is to expose it as part of the plugin 😄 |
It's similar to an explicit interface implementation. In: public class Foo : IBar
{
void IBar.M();
}
(public/private is also not a security boundary.) |
We don't need to merge this if folks are really against it. It just seems like an unnecessary restriction that forces a dev that wants to do this to work around it in awkward ways, and unnecessary friction for someone who explicitly tags a non-public method as [KernelFunction] but is then met with an exception. |
Allowing a private class with a public method but not a public class with a private method does seem odd. But I wasn't aware the example you provided above would work. We're going to discuss during todays stand up parking lot, I've sent you an invite. |
Offline there was a question about where else in .NET attributes on private methods are respected. A couple of examples that come to mind include [Event] with EventSource (the method will be included in the manifest / source regardless of its visibility) and [OnSerializing/Deserializing/...] with data contract serializers (the method will be used regardless of its visibility). |
@matthewbolanos, before this is merged, any thoughts / concerns? |
I chatted with Matthew about this and he approves of making this change. |
A developer already need to opt-in a method on a plugin to being part of the plugin by specifying the [KernelFunction] attribute; requiring that method to also be public is superfluous, and means that a type's plugin surface area must be a subset of its public surface area. That prohibits patterns where a type wants to syntactically be a plugin but not expose those APIs via its .NET public surface area.
(Curious to see if folks think this is controversial.)