Defining tools
Define typed Runiq tools with C# input and output models.
A Runiq tool implements IRuniqTool<TInput, TOutput>.
TInput is the structured input the model must provide. TOutput is the structured result returned by your .NET code.
Add metadata
Every tool class must be decorated with RuniqToolAttribute.
The name is the runtime tool name. The description tells the model when this tool is useful.
| Weak | Better |
|---|---|
Weather tool. | Returns deterministic demo weather guidance for a city. |
Searches things. | Searches customer support articles by query text. |
Budget helper. | Estimates an approximate travel budget from city, day count, group size, and style. |
Type rules
Runiq validates tool types when they are registered.
| Rule | Why it matters |
|---|---|
| Tool type must be a concrete class. | The runtime must be able to instantiate it. |
Tool type must implement IRuniqTool<TInput, TOutput>. | The runtime needs a typed input and output contract. |
Tool type must implement only one IRuniqTool<,> interface. | The runtime must know exactly which contract to expose. |
Tool type must have RuniqToolAttribute. | The model and dashboard need a name and description. |
| Tool names must be unique across registered tool types. | Runtime metadata and model tool definitions need unambiguous names. |
Input models
Use small, explicit input models.
Good:
Weak:
Clear property names help the model produce correct tool arguments and help the dashboard render the input shape.
Input types can be records or classes. Public readable properties are used to build dashboard schema metadata. For tools that do not need input, use EmptyToolInput.
Output models
Return structured data, not a long paragraph.
The final user-facing prose should usually be produced by the agent after the tool result returns to the model. The tool result itself is intermediate structured data.
Dependency injection
Tools are created through ASP.NET Core dependency injection using ActivatorUtilities.
This is the native .NET path: keep repositories, services, HTTP clients, database contexts, validators, and domain rules in your application and expose only the safe, typed capability to the agent.
Existing application code
You do not need to redesign the application around the agent. In Runiq.ExpenseDesk, the tool receives ExpenseDeskDatabase from DI and uses normal SQL filtering over application-owned tables. In a production app, the same pattern can wrap EF Core repositories, Dapper queries, HTTP clients, domain services, or policy engines.
Keep the tool contract small. Let the tool expose a safe operation such as "search expenses" or "lookup subscription state"; keep lower-level implementation details inside your existing .NET services.