Table of Contents

Class LMFunctionAttribute

Namespace
LMKit.Agents.Tools
Assembly
LM-Kit.NET.dll

Marks a method as a tool that can be invoked by language models through an agent.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LMFunctionAttribute : Attribute
Inheritance
LMFunctionAttribute
Inherited Members

Examples

Example: Basic tool definition with attribute

using LMKit.Agents.Tools;

public class UtilityTools
{
    [LMFunction("get_current_time", "Get the current time in a specific timezone")]
    public string GetCurrentTime(string timezone = "UTC")
    {
        var tz = TimeZoneInfo.FindSystemTimeZoneById(timezone);
        var time = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz);
        return time.ToString("yyyy-MM-dd HH:mm:ss");
    }

    [LMFunction("calculate", "Perform basic arithmetic calculations")]
    public double Calculate(double a, string operation, double b)
    {
        return operation switch
        {
            "+" or "add" => a + b,
            "-" or "subtract" => a - b,
            "*" or "multiply" => a * b,
            "/" or "divide" => b != 0 ? a / b : throw new ArgumentException("Cannot divide by zero"),
            _ => throw new ArgumentException($"Unknown operation: {operation}")
        };
    }
}

// Register all tools from an instance
var registry = new ToolRegistry();
var tools = new UtilityTools();
registry.Register(tools);

Example: Async tool with HTTP client

using LMKit.Agents.Tools;
using System.Net.Http.Json;

public class ApiTools
{
    private readonly HttpClient _httpClient = new();

    [LMFunction("fetch_json", "Fetch JSON data from a URL")]
    public async Task<string> FetchJson(string url)
    {
        var response = await _httpClient.GetAsync(url);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }

    [LMFunction("post_data", "Send JSON data to a URL via POST")]
    public async Task<string> PostData(string url, string jsonBody)
    {
        var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
        var response = await _httpClient.PostAsync(url, content);
        return await response.Content.ReadAsStringAsync();
    }
}

Example: Using with AgentBuilder

using LMKit.Agents;
using LMKit.Agents.Tools;
using LMKit.Model;

public class SearchTools
{
    [LMFunction("search_documents", "Search the document database")]
    public string SearchDocuments(string query, int maxResults = 10)
    {
        // Implementation...
        return JsonSerializer.Serialize(results);
    }
}

using var model = new LM("path/to/model.gguf");

var agent = Agent.CreateBuilder()
    .WithModel(model)
    .WithPersona("ResearchAssistant")
    .WithTools(registry =>
    {
        // Register tools from the SearchTools class
        registry.Register(new SearchTools());
    })
    .Build();

var result = await agent.RunAsync("Find documents about machine learning");

Remarks

Apply this attribute to public instance methods to expose them as tools without implementing ITool directly. The ToolRegistry can discover annotated methods and automatically generate tool wrappers with proper input schemas derived from method parameters.

Requirements:

  • The method must be a public instance method
  • The containing class must have a public parameterless constructor (for type-based discovery)
  • Parameters must be JSON-serializable primitive types (string, int, bool, double, etc.)
  • Return type can be string, Task<string>, or any JSON-serializable type

Auto-Generated Schema:
The tool's input schema is automatically generated from the method's parameters:

  • Parameter names become property names
  • Parameter types are mapped to JSON Schema types
  • Optional parameters (with default values) are not marked as required
  • Use DescriptionAttribute on parameters to add descriptions

Constructors

LMFunctionAttribute(string, string)

Creates a new LMFunctionAttribute with the specified name and description.

Properties

Description

Gets the description of what this tool does.

Name

Gets the stable, unique name for this tool.