# AI Tools Scope

When creating custom tools for the Chat AI assistant, your code runs within the ToolScope. This scope provides context about the chat, the user, and utilities for interacting with the conversation.

Class: Mosaik.AI.ToolScope

# Properties

Property Type Description
Graph Mosaik.GraphDB.Safe.Graph Access to the graph database.
ChatAI ChatAI Helper for interacting with the AI subsystem.
CurrentUser UID128 The user interacting with the chat.
TaskUID UID128 The UID of the current task execution.
CurrentChat UID128 The UID of the active chat session.
Logger ILogger Logger for diagnostics.
CancellationToken CancellationToken Token to monitor for cancellation.

# Methods

# Context Management

Tools can store and retrieve context data that persists within the chat session.

  • TryGetContext<T>(string name, out T context)
  • GetOrCreateContext<T>(string name, Func<T> creator)
  • StoreContext<T>(string name, T value)

# Chat Interaction

  • SetToolCallDisplayName(string name): Updates the name of the tool call shown in the UI.
  • AddSnippet(...): Adds a reference/snippet to the chat context (e.g., citing a document).

# Execution

  • RunEndpointAsync<T>(...): Executes a custom endpoint.
  • RunToolAsync<T>(...): Chains another tool execution.

# Example

public class SearchTool
{
    [Tool("Search for files that the user has access to. To reference results for the user, use the snippetId in brackets, such as [1].")]
    public static async Task<string> Search(ToolScope scope,
          [Parameter("The search query", required: true)] string query,
          [Parameter("Number of top results to return", required: false)] int limit,
          [Parameter("Number of results to skip, use with limit for pagination.", required: false)] int skip)
    {
        if (string.IsNullOrWhiteSpace(query))
        {
            return "[]";
        }
        else
        {
            var searchReq = SearchRequest.For(query);

            searchReq.SortMode = SortModeEnum.Relevance;
            searchReq.UserUID = scope.CurrentUser;
            // Only search for FileEntry nodes
            searchReq.BeforeTypesFacet = new HashSet<string>
            {
                _FileEntry.Type
            };

            // Execute search
            var search = await scope.Graph.CreateSearchAsUserAsync(searchReq, searchReq.UserUID, scope.CancellationToken);

            // Process results
            var results = search.Skip(skip > 0 ? skip : 0).Take(limit > 0 ? limit : 10).AsEnumerable().Select((n) =>
            {
                var text = scope.ChatAI.GetTextFromNode(n.UID, limit: 10_000);

                // Add snippet to chat context so LLM can reference it
                var snippetID = scope.AddSnippet(uid: n.UID, text: text);

                return new
                {
                    name = n.GetString(nameof(_FileEntry.OriginalName)),
                    content = text,
                    snippetId = snippetID
                };
            }).ToArray();

            // Provide a user-friendly name for the tool execution in the UI
            scope.SetToolCallDisplayName($"Search for '{query}'");

            return results.ToJson();
        }
    }
}

return new SearchTool();