MODULE 03 · LESSON 3.1
Choose a local method, standalone tool, or plugin
Select the smallest reusable tool boundary for an operation.
Lesson 11 of 86 · FabrCore 2.0
Overview
A local method is appropriate for behavior private to one agent. A static ToolAlias method is a simple reusable function. A plugin is a stateful collection with per-agent initialization, dependencies and disposal. Start with a fixture lookup before connecting a real ticket system.
A callable tool is a controlled entry point
A model cannot execute arbitrary methods just because they exist in your project. You expose a selected function with a name, description and input shape, then include it in the agent's available tools. Operations Desk starts with a fixture lookup so tool selection can be learned without credentials or writes to a real ticket system.
When a plugin is worth the extra structure
A local function fits one agent's private helper. A standalone aliased static tool fits a small reusable operation without per-instance state. A plugin fits several related operations that share dependencies and initialization. A request-system client with a tenant-bound connection belongs in a plugin; adding a plugin merely to concatenate two strings adds lifecycle work without a benefit.
Choose the smallest tool boundary
Download the Operations Desk source. The README lists project setup, package prerequisites and local ports.
- Implement GetRequest as a deterministic function returning a typed record. Give the function and parameters clear Description attributes.
- Use a standalone tool for pure formatting or validation. Move request lookup into a plugin when it needs an HTTP client, settings or agent context.
- Select tools/plugins in AgentConfiguration and resolve configured tools once during initialization.
using System.ComponentModel;
using FabrCore.Core;
public static class RequestTools
{
[ToolAlias("request-lookup")]
[Description("Read the fixture request by its exact ID. Returns null when absent.")]
public static string? Lookup(
[Description("Request ID, for example SR-1042")] string requestId)
=> requestId == "SR-1042"
? "SR-1042: Printer unavailable; status Open."
: null;
}
{
"Tools": [
"request-lookup"
]
}
Compare a known and an unknown request
- Implement a fixture lookup that returns a record for SR-1042 and an explicit not-found result for SR-9999. Call the method directly first so its data contract is known before a model is involved.
- Expose only the lookup operation to a test agent and ask for SR-1042. Inspect the tool invocation and confirm its request ID is exactly the requested value.
- Ask for SR-9999. The expected answer reports that the lookup found no record; inventing a ticket is a failure even if the tool call itself succeeded.
The tool boundary converts a model's proposed action into a typed application call. The next lesson packages this lookup into a plugin with a deliberate lifecycle.
If the result is different
Registering a class with DI is not always tool selection. Check discovery, alias spelling and the instance's configured tool/plugin list.
Go deeper
Explore the related documentation.