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:
| Helper | Type | Example |
|---|---|---|
string(desc?) | String | string("User's name") |
number(desc?) | Float | number("Temperature") |
integer(desc?) | Integer | integer("Count") |
boolean(desc?) | Boolean | boolean("Is active") |
enum_of(values, desc?) | Enum | enum_of(["a", "b"], "Choice") |
array(items, desc?) | Array | array(string("Tag")) |
obj(props, desc?) | Object | obj({"x": number()}) |
optional(schema) | Optional | optional(string("Notes")) |
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
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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.
| Tool | Description |
|---|---|
plan | Create and update task plans |
memory | Store and retrieve information |
widget | Generate UI components |
finish | Complete task (sub-agents only) |
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:
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:
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:
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?
- Agent API — Using the Agent class
- Running Apps — Direct app execution
- Streaming — Real-time updates