Tool calling for small on-device LLMs that don't support tool calling A developer built prompt-based tool calling for small on-device LLMs running in the browser via transformers.js or WebLLM, which return text only and lack a tool-calling API, after LangChain's tool-calling agents refused local models with the error "bind_tools() must be implemented." The approach renders OpenAI-style tool definitions into a system prompt and asks models to reply in JSON blocks, then parses the output with a list of regex patterns covering tag drift, Mistral's [TOOL_CALLS] arrays, Llama's syntax, fenced JSON, nested stringified arguments, reasoning blocks and truncated replies. The parser pairs those patterns with a strict filter so the agent accepts the formats small models actually emit without executing tools that were never offered. You attach a few tools to an AI agent, pick a small model that runs on your own machine, and press run. With a cloud model this is routine. With a model running in the browser, the agent refuses to start. In AWFlow you can build agents: an LLM node with tools attached search the page, call a sub-workflow, query a vector store . With OpenAI or Anthropic you pass tool schemas and get structured tool calls back. With a model running in the browser transformers.js or WebLLM , you don’t. Those runtimes give you text in and text out. LangChain’s tool-calling agents check for bindTools and refuse local models outright: Error: bind tools must be implemented So I implemented it with prompt-based tool calling. Prompting the model is the easy part. The interesting part is parsing what it actually sends back , because every model family answers in the format it was trained on, whatever you asked for. How the agent itself is wired the graph, the loop, the pause is covered in LangChain and LangGraph in the browser https://awflow.io/blog/langchain-and-langgraph-in-the-browser-how-an-ai-agent-builds-your-workflow . This post zooms into one piece of it: tool calls on models that have no tool-calling API. Describe the tools in the prompt The tools are converted to OpenAI-style definitions name, description, JSON Schema parameters and rendered into a system-prompt section, one JSON object per line: Tools You can call the following tools. Each is described as JSON name, description, JSON Schema parameters : {"name":"search page","description":"Find text on the current page","parameters":{...}} {"name":"save row","description":"Append a row to the sheet","parameters":{...}} To call a tool, reply with exactly this, one block per call, and nothing else: