Inference Logoinference.sh

Tool Builder

Fluent API for defining agent tools.

The tool builder provides a type-safe, readable way to define tools for your agents. Tools are the actions agents can take—from simple calculations to calling external APIs.


Schema Types

Build parameter schemas with these helpers:

HelperTypeExample
string(desc?)Stringstring("User's name")
number(desc?)Floatnumber("Temperature")
integer(desc?)Integerinteger("Count")
boolean(desc?)Booleanboolean("Is active")
enum_of(values, desc?)Enumenum_of(["a", "b"], "Choice")
array(items, desc?)Arrayarray(string("Tag"))
obj(props, desc?)Objectobj({"x": number()})
optional(schema)Optionaloptional(string("Notes"))

Python

python
1from inferencesh import (2    string, number, integer, boolean,3    enum_of, array, obj, optional4)5 6name = string("User's full name")7age = integer("Age in years")8score = number("Score between 0 and 1")9active = boolean("Whether the user is active")10 11# Enum12priority = enum_of(["low", "medium", "high"], "Priority level")13 14# Arrays15tags = array(string("Tag name"), "List of tags")16scores = array(number(), "List of scores")17 18# Objects19address = obj({20    "street": string("Street address"),21    "city": string("City"),22    "zip": optional(string("ZIP code")),23}, "Mailing address")24 25# Optional wrapper26notes = optional(string("Additional notes"))

JavaScript

typescript
1import {2  string, number, integer, boolean,3  enumOf, array, object, optional4} from '@inferencesh/sdk';5 6// Simple types7const name = string('User\'s full name');8const age = integer('Age in years');9const score = number('Score between 0 and 1');10const active = boolean('Whether the user is active');11 12// Enum13const priority = enumOf(['low', 'medium', 'high'], 'Priority level');14 15// Arrays16const tags = array(string('Tag name'), 'List of tags');17const scores = array(number(), 'List of scores');18 19// Objects20const address = object({21  street: string('Street address'),22  city: string('City'),23  zip: optional(string('ZIP code')),24}, 'Mailing address');25 26// Optional wrapper27const notes = optional(string('Additional notes'));

Client Tools

Client tools execute in your code. The agent calls them, you run them, and return results.

Basic Tool

Python:

python
1from inferencesh import tool, string2 3greet = (4    tool("greet")5    .describe("Greets a user by name")6    .param("name", string("Name to greet"))7    .build()8)

JavaScript:

typescript
1const greet = tool('greet')2  .describe('Greets a user by name')3  .param('name', string('Name to greet'))4  .build();

Tool with Display Name

Python:

python
1scan_ui = (2    tool("scan_accessibility_tree")3    .display("Scan UI")  # Friendly name shown to users4    .describe("Scans the UI and returns accessibility tree")5    .build()6)

JavaScript:

typescript
1const scanUI = tool('scan_accessibility_tree')2  .display('Scan UI')3  .describe('Scans the UI and returns accessibility tree')4  .build();

Tool with Multiple Parameters

Python:

python
1from inferencesh import tool, string, integer, boolean, enum_of, optional2 3search = (4    tool("search")5    .describe("Search for items")6    .param("query", string("Search query"))7    .param("limit", optional(integer("Max results (default 10)")))8    .param("sort", optional(enum_of(["relevance", "date", "name"], "Sort order")))9    .param("include_archived", optional(boolean("Include archived items")))10    .build()11)

JavaScript:

typescript
1const search = tool('search')2  .describe('Search for items')3  .param('query', string('Search query'))4  .param('limit', optional(integer('Max results (default 10)')))5  .param('sort', optional(enumOf(['relevance', 'date', 'name'], 'Sort order')))6  .param('includeArchived', optional(boolean('Include archived items')))7  .build();

Human-in-the-Loop

Require user approval before execution:

Python:

python
1delete_file = (2    tool("delete_file")3    .describe("Permanently delete a file")4    .param("path", string("File path to delete"))5    .require_approval()  # User must approve6    .build()7)

JavaScript:

typescript
1const deleteFile = tool('delete_file')2  .describe('Permanently delete a file')3  .param('path', string('File path to delete'))4  .requireApproval()5  .build();

App Tools

Call another inference.sh app. Executed server-side.

Python:

python
1from inferencesh import app_tool, string, optional, integer2 3# Basic app tool4generate = (5    app_tool("generate_image", "infsh/flux-schnell@latest")6    .describe("Generate an image from text")7    .param("prompt", string("Image description"))8    .build()9)10 11# With optional parameters12generate_hq = (13    app_tool("generate_hq", "infsh/flux-dev@latest")14    .describe("Generate high-quality image")15    .param("prompt", string("Image description"))16    .param("width", optional(integer("Width in pixels")))17    .param("height", optional(integer("Height in pixels")))18    .param("steps", optional(integer("Inference steps")))19    .require_approval()  # Costs more credits20    .build()21)

JavaScript:

typescript
1import { appTool, string, optional, integer } from '@inferencesh/sdk';2 3const generate = appTool('generate_image', 'infsh/flux-schnell@latest')4  .describe('Generate an image from text')5  .param('prompt', string('Image description'))6  .build();7 8const generateHQ = appTool('generate_hq', 'infsh/flux-dev@latest')9  .describe('Generate high-quality image')10  .param('prompt', string('Image description'))11  .param('width', optional(integer('Width in pixels')))12  .param('height', optional(integer('Height in pixels')))13  .param('steps', optional(integer('Inference steps')))14  .requireApproval()15  .build();

Agent Tools

Delegate to another agent. Useful for specialized sub-agents.

Python:

python
1from inferencesh import agent_tool, string, enum_of2 3code_reviewer = (4    agent_tool("review_code", "my-org/code-reviewer@v2")5    .describe("Review code for bugs and best practices")6    .param("code", string("Code to review"))7    .param("language", enum_of(8        ["python", "javascript", "go", "rust"],9        "Programming language"10    ))11    .build()12)

JavaScript:

typescript
1import { agentTool, string, enumOf } from '@inferencesh/sdk';2 3const codeReviewer = agentTool('review_code', 'my-org/code-reviewer@v2')4  .describe('Review code for bugs and best practices')5  .param('code', string('Code to review'))6  .param('language', enumOf(7    ['python', 'javascript', 'go', 'rust'],8    'Programming language'9  ))10  .build();

Webhook Tools

Call external HTTP endpoints. Great for integrations.

Python:

python
1from inferencesh import webhook_tool, string, optional, boolean2 3# Basic webhook4notify_slack = (5    webhook_tool("slack", "https://hooks.slack.com/services/T.../B.../xxx")6    .describe("Send a Slack notification")7    .param("channel", string("Channel name"))8    .param("message", string("Message text"))9    .param("urgent", optional(boolean("Mark as urgent")))10    .build()11)12 13# With authentication14api_call = (15    webhook_tool("call_api", "https://api.example.com/action")16    .describe("Call external API")17    .secret("API_SECRET_KEY")  # Uses your stored secret18    .param("action", string("Action to perform"))19    .build()20)

JavaScript:

typescript
1import { webhookTool, string, optional, boolean } from '@inferencesh/sdk';2 3const notifySlack = webhookTool('slack', 'https://hooks.slack.com/services/T.../B.../xxx')4  .describe('Send a Slack notification')5  .param('channel', string('Channel name'))6  .param('message', string('Message text'))7  .param('urgent', optional(boolean('Mark as urgent')))8  .build();9 10const apiCall = webhookTool('call_api', 'https://api.example.com/action')11  .describe('Call external API')12  .secret('API_SECRET_KEY')13  .param('action', string('Action to perform'))14  .build();

Internal Tools

Configure built-in agent capabilities.

ToolDescription
planCreate and update task plans
memoryStore and retrieve information
widgetGenerate UI components
finishComplete task (sub-agents only)

Python:

python
1from inferencesh import internal_tools2 3# Enable specific tools4config = internal_tools().plan().memory().build()5 6# Enable all7config = internal_tools().all().build()8 9# Disable all10config = internal_tools().none().build()11 12# Mix: enable some, disable others13config = (14    internal_tools()15    .memory(True)16    .plan(True)17    .widget(False)18    .finish(False)19    .build()20)

JavaScript:

typescript
1import { internalTools } from '@inferencesh/sdk';2 3// Enable specific tools4const config = internalTools().plan().memory().build();5 6// Enable all7const config = internalTools().all().build();8 9// Disable all10const config = internalTools().none().build();

Tool Output Format

When you call .build(), you get a tool definition object:

json
1{2  "name": "search",3  "display_name": "Search Files",4  "description": "Search for files matching a pattern",5  "type": "client",6  "require_approval": false,7  "client": {8    "input_schema": {9      "type": "object",10      "properties": {11        "pattern": {12          "type": "string",13          "description": "Glob pattern to match"14        },15        "recursive": {16          "type": "boolean",17          "description": "Search subdirectories"18        }19      },20      "required": ["pattern"]21    }22  }23}

This follows the JSON Schema standard for tool definitions.


Full Example

A complete set of tools for a file management agent:

Python:

python
1from inferencesh import (2    tool, app_tool, webhook_tool, internal_tools,3    string, integer, boolean, enum_of, array, obj, optional4)5 6# Client tools7list_files = (8    tool("list_files")9    .display("List Files")10    .describe("List files in a directory")11    .param("path", string("Directory path"))12    .param("pattern", optional(string("Filter pattern")))13    .build()14)15 16read_file = (17    tool("read_file")18    .describe("Read file contents")19    .param("path", string("File path"))20    .param("encoding", optional(enum_of(["utf-8", "ascii", "binary"], "Encoding")))21    .build()22)23 24write_file = (25    tool("write_file")26    .describe("Write content to a file")27    .param("path", string("File path"))28    .param("content", string("Content to write"))29    .require_approval()  # Dangerous operation30    .build()31)32 33# App tool for image processing34resize_image = (35    app_tool("resize", "infsh/image-resize@latest")36    .describe("Resize an image")37    .param("image", string("Image URL or path"))38    .param("width", integer("Target width"))39    .param("height", integer("Target height"))40    .build()41)42 43# Webhook for notifications44notify_complete = (45    webhook_tool("notify", "https://api.myapp.com/notify")46    .describe("Notify when task is complete")47    .secret("MYAPP_API_KEY")48    .param("message", string("Notification message"))49    .param("recipients", array(string("Email"), "People to notify"))50    .build()51)52 53# Combine for agent54all_tools = [list_files, read_file, write_file, resize_image, notify_complete]55internals = internal_tools().memory().plan().build()

What's Next?

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.