All nodes/AI/Agents
Widget tools
An agent extension: exposes to the LLM all JS functions declared in the widget embed code (flowWidget.defineFunction) as tools. When the model calls a tool, the visitor's browser runs the bound JS and returns the result. Works only in widget mode.
Type in the graph: widget_tools
Tool
Try it
Minimal working workflow
- Execute + Data
- Extension
- LLM
- Memory
- Execute + Data + Streaming
Runs as pasted
When to use it
This node is for a chat that lives as a widget on your site and a model that has to do something on the visitor’s page: read the cart, fill a field, open a modal, scroll to a block. What separates it from Widget Function is who decides: there you place a step in the graph and call one specific function, here the model picks what to call and when.
How it works
The node declares no tools of its own. It takes the list of functions the page announced through
flowWidget.defineFunction (the {name, description, parameters} shape) and offers each of them
to the model as a tool. The handler stays in the browser — the workflow only ever sees the
declaration.
Names are normalized before the model sees them: lower-cased, everything except letters, digits,
_ and - replaced by _, cut to 64 characters. So Get Cart is called as get_cart; if two
declarations collapse into one name, the second gets a numeric suffix.
A call is a round trip: the request goes to the browser, your handler runs, the result comes back to the workflow. The node waits no longer than the Timeout (30 seconds by default, 300 maximum). Allowed functions is an allow-list of original declared names; an empty list means “all of them”.
When no browser is there — the tab was closed, the run did not come from a widget, the answer did not arrive in time — the model gets a text error rather than a node failure, and can answer the user itself. Further calls in the same run fail immediately instead of parking another timeout.
Common mistakes
- Testing it from the editor’s test run, over the API or in Telegram. There are no declared functions and no browser there: the model only gets an error. Test it on a page with the widget.
- Declaring a function with no description. The model chooses a tool by its description; without one it either never calls the function or calls it at the wrong moment.
- Omitting
parameters. A declaration without an object schema is advertised as a function with no arguments, so nothing can be passed to it. - Putting the normalized name in the allow-list. The list is matched against the name you
wrote in
defineFunction. - A handler slower than the timeout. Heavy work is better started on the page and reported back in a later turn than kept waiting inside one call.
Inputs
—
Outputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Agentoutput | Extensionlink_extension | — |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
Allowed functionsallowed_functions | array<string> | — | Optional allow-list of client function names to expose to the LLM. Leave empty to expose every function declared by the widget. |
Timeout (seconds)timeout_seconds | integer | 30 | How long to wait for the browser to return a tool result before failing. |