using System.Globalization;using System.Text.Json;namespace Agent.Core.ToolCalling;/// <summary>Default Agent-Core tools: current local time and date.</summary>public static class BuiltInTools{ public const string GetTimeName = "get_time"; public const string GetDateName = "get_date"; public const string ChangeNameName = "change_name"; public static void Register(ToolRegistry registry) { registry.Register(new AgentTool( GetTimeName, "Returns the current local time on this machine.", _ => DateTime.Now.ToString("T", CultureInfo.CurrentCulture))); registry.Register(new AgentTool( GetDateName, "Returns today's local date on this machine.", _ => DateTime.Now.ToString("D", CultureInfo.CurrentCulture))); registry.Register(new AgentTool( "store_memory", "Stores a persistent user fact in hierarchical vector memory (NOT workspace files). Use for preferences, name, job, pets, etc. Paths like user/name or user/preferences/color.", args => { if (registry.Memory is null) return "Error: Memory system is not initialized."; try { using var doc = JsonDocument.Parse(args); var root = doc.RootElement; if (!root.TryGetProperty("path", out var pathProp) || !root.TryGetProperty("content", out var contentProp)) { return "Error: Missing path or content properties."; } string path = pathProp.GetString() ?? ""; string content = contentProp.GetString() ?? ""; if (string.IsNullOrWhiteSpace(path)) return "Error: Path cannot be empty."; registry.Memory.StoreAsync(path, content).GetAwaiter().GetResult(); return $"Success: Stored memory under path '{path}'."; } catch (Exception ex) { return $"Error: {ex.Message}"; } }, new { type = "object", properties = new { path = new { type = "string", description = "The hierarchical path, e.g., 'user/name' or 'user/preferences/color'." }, content = new { type = "string", description = "The fact or information to store." } }, required = new[] { "path", "content" } } )); registry.Register(new AgentTool( "get_memory_at_path", "Reads one exact memory entry by hierarchical path (e.g. user/preferences/color).", args => { if (registry.Memory is null) return "Error: Memory system is not initialized."; try { using var doc = JsonDocument.Parse(args); var root = doc.RootElement; if (!root.TryGetProperty("path", out var pathProp)) { return "Error: Missing path property."; } string path = pathProp.GetString() ?? ""; if (string.IsNullOrWhiteSpace(path)) return "Error: Path cannot be empty."; string? value = registry.Memory.QueryPath(path); if (value is null) return $"No memory found at path '{path}'."; return value; } catch (Exception ex) { return $"Error: {ex.Message}"; } }, new { type = "object", properties = new { path = new { type = "string", description = "Exact memory path, e.g. 'user/job' or 'user/preferences/color'." } }, required = new[] { "path" } } )); registry.Register(new AgentTool( "retrieve_memory", "Semantic search over vector memory. Use when you do not know the exact path (e.g. 'user profession', 'favorite color', 'pets').", args => { if (registry.Memory is null) return "Error: Memory system is not initialized."; try { using var doc = JsonDocument.Parse(args); var root = doc.RootElement; if (!root.TryGetProperty("query", out var queryProp)) { return "Error: Missing query property."; } string query = queryProp.GetString() ?? ""; if (string.IsNullOrWhiteSpace(query)) return "Error: Query cannot be empty."; var matches = registry.Memory.RetrieveAsync(query, topN: 3).GetAwaiter().GetResult(); if (matches.Count == 0) return "No matching memories found."; return JsonSerializer.Serialize(matches.Select(m => new { path = m.Path, content = m.Value })); } catch (Exception ex) { return $"Error: {ex.Message}"; } }, new { type = "object", properties = new { query = new { type = "string", description = "The semantic query to search memory for, e.g. 'What is the user's name?'." } }, required = new[] { "query" } } )); registry.Register(new AgentTool( ChangeNameName, "Changes the name of the assistant.", args => { string newName = ParseName(args); if (string.IsNullOrWhiteSpace(newName)) return "Error: name cannot be empty."; registry.InvokeNameChanged(newName); return $"Success: Name changed to {newName}."; }, new { type = "object", properties = new { name = new { type = "string", description = "The new name for the assistant." } }, required = new[] { "name" } })); } private static string ParseName(string argumentsJson) { try { using var doc = JsonDocument.Parse(argumentsJson); if (doc.RootElement.TryGetProperty("name", out var nameProp)) { return nameProp.GetString()?.Trim() ?? ""; } } catch (JsonException) { } return ""; }}
Documentation
Tool calling (Version 3)
Agent-Core exposes a small tool registry for Ollama function calling. Lilith registers these tools on the chat client at boot.
| Tool | Description | |------|-------------| | get_time | Current local time | | get_date | Today's local date |
Register more tools with ToolRegistry.Register before chat starts.