Native Custom Tools

Register app-specific React Native tools implemented in Swift or Kotlin against the native Ansight runtime.

Native custom tools let a React Native app expose a focused operation implemented in Swift or Kotlin. Use them when the operation needs native-only app state, platform APIs, or direct native dependencies. Use JavaScript Custom Tools when the handler can live safely in JavaScript.

Registration Timing

Register native custom tools after the React Native bridge has initialized Ansight. Android runtime initialization rebuilds the native tool registry from the options passed to the bridge, so tools registered too early can be cleared. If JavaScript owns initialization, expose an app-owned native method and call it after Ansight.initializeAndActivate(...).

iOS Swift Tool

The React Native iOS package depends on the native Ansight pod, so Swift app code can register executable tools with the native runtime.

import Ansight

let currentUserId = "debug-user-42"

struct CurrentUserTool: AnsightTool {
    let userId: String

    var descriptor: AnsightToolDescriptor {
        AnsightToolDescriptor(
            id: "app.current_user.native",
            name: "Native Current User",
            description: "Returns the current user id from native iOS app state.",
            category: "app",
            scope: AnsightToolScope.read.rawValue,
            keywords: "app user native ios"
        )
    }

    func execute(arguments: [String: String]) throws -> AnsightToolExecutionResult {
        .success(.object([
            "userId": .string(userId),
            "source": .string("ios")
        ]))
    }
}

try AnsightRuntime.shared.registerTool(
    CurrentUserTool(userId: currentUserId),
    replaceExisting: true
)

Android Kotlin Tool

The React Native Android package depends on the native ai.ansight:ansight-android artifact, so Kotlin app code can register executable tools with the native runtime.

import ai.ansight.runtime.AndroidToolResult
import ai.ansight.runtime.AnsightRuntime
import ai.ansight.runtime.ToolScope
import ai.ansight.runtime.androidSimpleTool
import org.json.JSONObject

val currentUserId = "debug-user-42"

val currentUserTool = androidSimpleTool(
    id = "app.current_user.native",
    name = "Native Current User",
    description = "Returns the current user id from native Android app state.",
    category = "app",
    scope = ToolScope.Read,
    keywords = "app user native android",
) { _, _ ->
    AndroidToolResult.success(
        JSONObject()
            .put("userId", currentUserId)
            .put("source", "android")
    )
}

AnsightRuntime.registerTool(currentUserTool, replaceExisting = true)

Registration API

  • iOS: AnsightRuntime.shared.registerTool(_ tool: any AnsightTool, replaceExisting: Bool = false) registers an executable native tool.
  • Android: AnsightRuntime.registerTool(tool: AndroidTool, replaceExisting: Boolean = false) registers an executable native tool.
  • Tool ids share the same global namespace as packaged suites, React Inspection tools, JavaScript custom tools, and artifact tools.
  • Registered tools are still hidden and unusable until the runtime guard allows their scope.

Specific Concerns

  • Prefer narrow, app-specific operations under an app-owned id prefix such as app..
  • Choose the correct scope: read-only diagnostics should be Read; mutation should be Write; destructive operations should be Delete.
  • Do not expose broad native scripting, arbitrary file access, secret access, or release-only production state.
  • Keep Swift/Kotlin registration idempotent by using stable ids and replaceExisting: true when app lifecycle can call registration more than once.