BrowserStack AI Evals
Evaluation

Tools

Register and compile LLM tool schemas across TypeScript, Python, and Java SDKs.

Tools

Tools are versioned LLM function definitions stored in BrowserStack AI Evals. The SDK lets you create, fetch, compile, and update tools programmatically, then pass them directly to LLM API calls.

Setup

import { AISDK } from '@browserstack/ai-sdk';

const testOps = new AISDK({
  publicKey: process.env.AISDK_PUBLIC_KEY,
  secretKey: process.env.AISDK_SECRET_KEY,
});

const tools = testOps.tools;

Create a Tool

const toolInstance = await tools.create({
  name: 'search_web',
  description: 'Search the web for up-to-date information on a topic.',
  parameters: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'The search query.' },
      maxResults: { type: 'integer', description: 'Maximum results to return.', default: 5 },
    },
    required: ['query'],
  },
  isRunnable: true,
  labels: ['production'],
});

console.log(toolInstance.id, toolInstance.version);

Get and Compile a Tool

The second argument selects the provider format ("openai" by default). Supported providers: "openai", "anthropic", "gemini".

// Get latest version (OpenAI format, default)
const result = await tools.get('search_web');

// Get in Anthropic format
const result = await tools.get('search_web', 'anthropic');

// Get by version
const result = await tools.get('search_web', undefined, { version: 2 });

// Get by label
const result = await tools.get('search_web', undefined, { label: 'production' });

ProviderToolResult.compile() returns a provider-agnostic tool definition ready to pass to an LLM SDK:

const result = await tools.get('search_web');
const compiled = result.compile();

const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'What happened in the news today?' }],
  tools: [compiled as any],
  tool_choice: 'auto',
});

List Tools

const listing = await tools.list(
  20,             // limit
  undefined,      // cursor for pagination
  'production'    // optional label filter
);

for (const tool of listing.data) {
  console.log(tool.name, 'v' + tool.version);
}

if (listing.meta.nextCursor) {
  const next = await tools.list(20, listing.meta.nextCursor);
}

Update a Tool

Updating creates a new version:

const updated = await tools.update({
  name: 'search_web',
  description: 'Search the web for current information.',
  parameters: {
    type: 'object',
    properties: {
      query: { type: 'string' },
      maxResults: { type: 'integer', default: 10 },
      language: { type: 'string', default: 'en' },
    },
    required: ['query'],
  },
  labels: ['production'],
  commitMessage: 'Add language parameter',
});

console.log('New version:', updated.version);

Static Methods

All methods are also available as static calls without an instance:

import { Tool } from '@browserstack/ai-sdk';

const toolInstance = await Tool.create({ name: 'my-tool', description: '...' });
const result = await Tool.get('my-tool');
const listing = await Tool.list(10);

Create a Tool

import os
from browserstack_ai_sdk import Tool

tool_instance = Tool.create(
    name="get_weather",
    description="Get the current weather for a given location.",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "City and state, e.g. 'San Francisco, CA'",
            },
            "unit": {
                "type": "string",
                "enum": ["celsius", "fahrenheit"],
            },
        },
        "required": ["location"],
    },
    labels=["production"],
    commit_message="Initial version",
)

print(tool_instance.name)     # "get_weather"
print(tool_instance.id)       # registry ID
print(tool_instance.version)  # 1

create() Parameters

ParameterTypeDefaultDescription
namestrrequiredTool name (alphanumeric, hyphens, underscores)
descriptionstrrequiredHuman-readable description
parametersdict{}JSON Schema for tool parameters
sample_outputdictNoneExample output for documentation
is_runnableboolNoneWhether the tool can be executed
labelslist[str]NoneLabels (e.g., ["production"])
commit_messagestrNoneVersion commit message

Fetch and Compile a Tool

from browserstack_ai_sdk import Tool

# Fetch with default provider (OpenAI format)
tool = Tool.get("get_weather")

# Fetch for a specific provider
tool = Tool.get("get_weather", provider="openai")

# Fetch a specific version
tool = Tool.get("get_weather", version=2)

# Fetch by label
tool = Tool.get("get_weather", label="production")

ProviderToolResult.compile() resolves Mustache placeholders and strips internal metadata:

from browserstack_ai_sdk import Tool
import openai

tool = Tool.get("search_products", provider="openai")
compiled = tool.compile()

client = openai.OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Find me a good laptop."}],
    tools=[compiled],
    tool_choice="auto",
)

List and Update Tools

from browserstack_ai_sdk import Tool

# List tools
response = Tool.list(limit=20)
for tool_data in response.get("data", []):
    print(tool_data["name"])

# Filter by label
response = Tool.list(label="production")

# Update (creates a new version)
updated = Tool.update(
    name="get_weather",
    description="Get the current weather and 5-day forecast for a location.",
    parameters={
        "type": "object",
        "properties": {
            "location": {"type": "string"},
            "days": {"type": "integer", "minimum": 1, "maximum": 5},
        },
        "required": ["location"],
    },
    labels=["production"],
    commit_message="Add forecast support",
)
print(updated.version)  # 2

ToolList (from Prompts)

When you fetch a prompt that has an attached tool list, prompt.tools is a ToolList:

from browserstack_ai_sdk import Prompt
import openai

prompt = Prompt.get("my-prompt-with-tools", type="chat")

compiled_tools = prompt.tools.compile(strings={"env": "production"})

client = openai.OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=prompt.compile(user_message="What tools do you have?"),
    tools=compiled_tools,
    tool_choice="auto",
)

Via AISDK Instance

import os
from browserstack_ai_sdk import AISDK

client = AISDK(
    public_key=os.environ["AISDK_PUBLIC_KEY"],
    secret_key=os.environ["AISDK_SECRET_KEY"],
)

tool = client.tools.get("get_weather", provider="openai")
compiled = tool.compile()

Tool management via the Java SDK is coming soon. Track progress in our SDK changelog.