Tool Naming Convention¶
With multiple tool authors contributing, we needed naming consistency.
Background¶
Tool names must be globally unique because our serialization system uses the tool name as the sole lookup key. Additionally, we want to minimize LLM context by only exposing relevant tools, and keep schemas simple by avoiding platform-conditional parameters.
What we decided¶
Naming Convention¶
| Category | Format | Example |
|---|---|---|
| Universal primitive | {verbNoun} |
tap, scroll, inputText |
| Platform primitive | {platform}_{verbNoun} |
ios_clearKeychain, android_pressSystemBack |
| Org-wide | org_{verbNoun} |
org_mockServer, org_resetTestEnvironment |
| Org-wide + platform | org_{platform}_{verbNoun} |
org_ios_configureTestUser |
| App-specific | {app}_{verbNoun} |
myapp_launchAppSignedIn, payments_addFunds |
| App + platform | {app}_{platform}_{verbNoun} |
myapp_ios_scroll |
Key rules:
- Use underscores as separators (dots aren’t supported in OpenAI function names)
- Device type (phone/tablet) should NOT appear in names—use execution context instead
- Versioning: Append _v2, _v3 for breaking changes (e.g., myapp_ios_scroll_v2)
When to Use App + Platform Tools¶
Only when parameter schemas differ materially between platforms:
// Good: focused schemas
myapp_ios_launchAppSignedIn(permissions: [String], virtualCard: Bool)
myapp_android_launchAppSignedIn(permissions: [String], overlayPermission: Bool)
// Avoid: confusing conditional parameters
myapp_launchAppSignedIn(permissions: [String], virtualCard: Bool?, overlayPermission: Bool?)
Tool Metadata¶
@TrailblazeToolClass(
name = "myapp_ios_launchAppSignedIn",
isForLlm = true, // false = deprecated or implementation-detail tool
isRecordable = true,
platforms = [Platform.IOS],
)
Tools are filtered before LLM exposure based on isForLlm, target app, and current platform. The executor must also reject unsupported tool calls at runtime.
Reserved Names¶
Centrally owned and validated at build time:
- Global primitives (tap, scroll, etc.)
- Platform primitives (ios_*, android_*)
- Org-wide (org_*)
- App prefixes (myapp, payments, etc.)
Shared Implementation¶
Platform-specific tools can share logic via delegation:
class MyAppIosLaunchAppSignedIn : Tool {
override fun execute(args: Args) = sharedLaunchLogic(args, platformConfig = iosConfig)
}
What changed¶
Positive: Globally unique names, minimized LLM context, simple schemas, clear tool provenance.
Negative: Requires naming discipline and potential migration of existing tools.