When the Model Can Act

An Open WebUI response changes character when the model can call a capability instead of only returning text. The question is not simply whether a tool exists, but where it runs, what it can reach, whose identity it uses, and what happens to its result. This chapter separates Open WebUI's tool and extension types by trust and locality, then follows one tool call through discovery, authorization, parameter injection, execution, approval, and return to the conversation. The practical outcome is a way to judge action capability without treating built-in features, Python code, remote servers, terminals, and browser tools as interchangeable.

A tool call is a new boundary in the request path. The model proposes an action, but Open WebUI still has to resolve a callable capability and prepare the surrounding context. The call may use the user's identity, session, OAuth token, chat identifiers, files, or event channel. It may return ordinary text, a citation source, an image, or a file to display. The model's decision is therefore only a trigger; the platform and the target execution environment determine the consequences.

The execution spectrum

The least surprising category is the built-in tool. These capabilities are defined as part of the platform and can expose functions for tasks such as searching, querying knowledge, working with notes or memory, generating images, managing calendar items, and other workspace operations. Their implementation belongs to Open WebUI, so the platform can assemble their specifications and supply application context in a consistent way. “Built-in” does not mean “unbounded.” A built-in operation still needs the relevant feature flag, user permission, resource access, and input checks.

A second category is the database-backed Tool. An administrator or a suitably trusted user can create a Tool from Python source. Open WebUI stores the source and a set of function specifications, loads the module dynamically, and turns those specifications into model-callable functions. It can inject the current user, request, metadata, model, files, and event helpers into the callable while hiding reserved internal parameters from the model-facing specification. This makes a Tool feel like a normal function to the model while giving its code access to server-side context.

That convenience is also the most important trust fact. Dynamic loading executes the supplied Python in the server process. The loader can rewrite imports, execute the module, and, when frontmatter names required packages, invoke package installation. The security policy does not describe this as an accidental vulnerability. It says that Tools and Functions are designed to execute user-provided Python code, that Function creation is restricted to administrators, and that granting workspace.tools is equivalent to giving a user shell-level access to the server. The correct boundary is therefore the trustworthiness of the person allowed to create or control the code, not the friendliness of the chat interface.

A Function is a related but distinct extension shape. Functions can behave as pipes, filters, actions, or events. A pipe can present itself as a model-like route; a filter can change request, stream, or response data; an action can be invoked around a conversation; and an event handler can respond to application events. Functions have active and global lifecycle states. A global filter can affect many conversations, which makes its scope different from a Tool that a user selects for one request.