Custom Tools

Register narrow app-specific native Android tools for local development operations that the packaged suites do not cover.

Custom tools let app code expose a focused local development operation through the same guarded remote-tool protocol as the packaged suites.

Register a Tool

import ai.ansight.runtime.AndroidToolResult
import ai.ansight.runtime.AnsightOptions
import ai.ansight.runtime.ToolPolicy
import ai.ansight.runtime.androidSimpleTool
import org.json.JSONObject

val tool = androidSimpleTool(
    id = "app.current_user",
    name = "Current User",
    description = "Returns the current debug user id.",
    category = "app",
    policy = ToolPolicy.Read,
    keywords = "app user debug",
) { _, _ ->
    AndroidToolResult.success(
        JSONObject().put("userId", session.currentUserId)
    )
}

val options = AnsightOptions.createBuilder()
    .addTool(tool)
    .withReadOnlyToolAccess()
    .build()

Dynamic Availability

Tools are available by default. When execution depends on current app state, use FunctionAndroidTool or implement AndroidTool.availability(...) so discovery can explain the prerequisite before a call:

import ai.ansight.runtime.FunctionAndroidTool
import ai.ansight.runtime.ToolAvailability
import ai.ansight.runtime.ToolDefinition

val tool = FunctionAndroidTool(
    definition = ToolDefinition(
        id = "app.current_user",
        name = "Current User",
        description = "Returns the current debug user id.",
        category = "app",
        policy = ToolPolicy.Read,
        keywords = "app user debug",
    ),
    availabilityHandler = {
        if (session.isSignedIn) {
            ToolAvailability.Available
        } else {
            ToolAvailability.unavailable(
                reasonCode = "user_not_signed_in",
                reason = "No debug user is signed in.",
                requiredState = "Signed-in debug session",
                remediation = "Open the account fixture and sign in.",
                retryable = true,
            )
        }
    },
) { _, _ ->
    AndroidToolResult.success(JSONObject().put("userId", session.currentUserId))
}

The catalog publishes this under runtime and sets executable accordingly. Availability is evaluated again immediately before execution, preventing a stale catalog entry from bypassing the prerequisite.

Registration API

  • addTool(...): adds one tool to options before runtime initialization.
  • addTools(...): adds multiple tools to options before runtime initialization.
  • registerTool(...): registers a tool at runtime.
  • isToolRegistered(...): checks whether a tool id is currently registered.

Specific Concerns

  • Prefer narrow, app-specific operations.
  • Choose the correct policy: ToolPolicy.Read, ToolPolicy.Write, or ToolPolicy.Critical.
  • Do not expose broad scripting, arbitrary file access, or secret access through custom tools.
  • Registered tools are still hidden and unusable until the runtime guard allows their policy.

Tool Definition Checklist

  • Stable tool id, usually under an app-owned prefix such as app.
  • Clear name and description
  • Category and keywords that match the workflow
  • Correct policy
  • Explicit argument validation and failure messages
  • Structured JSON result payloads for callers
  • Dynamic availability with a stable reason code, required state, remediation, and retryability when execution has runtime prerequisites