Integration

Tool Calling — Agent Actions

Register any function as a tool. The agent decides when to call it — your code does the work.

Three approaches

ApproachWhere definedBest for
registerTools JS at runtime Tools that need closures, live state, or complex logic
Tool Manifest Dashboard (JSON) Simple client actions or server calls, configured without a deploy
Server Tools (OpenAPI) Dashboard (URL) Calling your existing REST API endpoints directly

1 — registerTools (programmatic)

Call window.widgent('registerTools', [...]) after init(). Each tool is a JS object with a name, description, JSON Schema parameters, and an async handler.

window.widgent('registerTools', [
  {
    name: 'navigate_to',
    description: 'Navigate the user to a specific page in the app.',
    parameters: {
      type: 'object',
      properties: {
        path: { type: 'string', description: 'The URL path to navigate to.' }
      },
      required: ['path']
    },
    handler: async ({ path }) => {
      window.location.href = path;
      return { success: true, path };
    }
  },
  {
    name: 'get_account_info',
    description: 'Return the current user account balance and plan.',
    parameters: { type: 'object', properties: {} },
    handler: async () => {
      const data = await fetch('/api/account').then(r => r.json());
      return data;  // returned to the LLM as tool output
    }
  }
]);

The agent sees your description and decides when to call the tool. The handler return value is sent back to the LLM as the tool result.

2 — Tool Manifest (dashboard JSON)

Define tools as JSON in the Dashboard → Tools tab. No code deploy needed to add or modify tools.

Client tool — runs a named function on window
{
  "type": "client",
  "name": "navigate_to",
  "description": "Navigate the user to a specific page",
  "parameters": {
    "type": "object",
    "properties": { "path": { "type": "string" } },
    "required": ["path"]
  },
  "handler": "myApp.router.push",
  "mockResponse": { "status": "success" }
}
Server tool — calls your backend endpoint
{
  "type": "server",
  "name": "search_docs",
  "description": "Search the product knowledge base",
  "parameters": {
    "type": "object",
    "properties": { "query": { "type": "string" } },
    "required": ["query"]
  },
  "url": "https://api.example.com/search",
  "method": "POST",
  "mockResponse": { "results": [{ "title": "Example result", "url": "/docs/example" }] }
}

For server tools that need auth, pass a toolToken at init time — it's forwarded with every call, never stored by Widgent:

window.widgent.init({
  productId: 'YOUR_PRODUCT_ID',
  serviceKey: 'YOUR_SERVICE_KEY',
  toolTokens: {
    search_docs: 'Bearer sk-...'
  }
});

mockResponse — safe testing

Every tool in the manifest can have a mockResponse. In test sessions (Dashboard → Test tab), the LLM receives mockResponse instead of calling the real handler. This lets you test agent behavior without side effects.

Tool writing tips

  • Name clearlycreate_invoice beats action1. The LLM reads the name.
  • Describe the effect — "Creates a new invoice and returns the invoice ID." Tell the LLM what happens.
  • Return structured data — The LLM uses your return value to formulate the next response. Return JSON, not strings.
  • Keep tools focused — One action per tool. Compose in the agent, not in the handler.