Skip to main content

Tools

Tools are Java methods that the LLM can call during a conversation. When the LLM decides to use a tool, it emits a tool call request; uxopian-ai executes the corresponding method and returns the result to the LLM, which then incorporates it into its response.

How tools work

Figure: Tool execution sequence from LLM tool call to method invocation and result return.

Annotations

Tools are defined using three annotations — @ToolService is provided by uxopian-ai, @Tool and @P come from LangChain4J:

AnnotationTargetPurpose
@ToolService(tags = {...})ClassMarks the bean as a tool provider. IntegrationLoader uses this to register it. The optional tags array drives the tool whitelist — see Filtering tools by tag.
@ToolMethodMarks a method as callable by the LLM. The annotation value is the description sent to the LLM.
@PParameterDescribes a parameter. The description is sent to the LLM so it knows what value to provide.

Example:

@Service
@ToolService(tags = "alfresco")
public class MySearchService {

@Tool("Search for documents matching a query string. Returns a list of document titles.")
public List<String> searchDocuments(
@P("The search query string") String query,
@P("Maximum number of results to return") int maxResults) {
// implementation
}
}

Registration

ToolExecutor collects all beans annotated with @ToolService at ContextRefreshedEvent. For each bean, it scans public methods annotated with @Tool and registers them by name. The tool name defaults to the method name; it can be overridden with @Tool(name = "...").

If tools are disabled via tools.enabled=false (or TOOLS_ENABLED=false), the ToolExecutor skips initialization and no tools are available.

Filtering tools by tag

In 2026.0.0-ft3, @ToolService.tags() + plugins.tools.enabled-tags control which tool sets are registered at startup. This lets a single distribution ZIP ship several integrations (Alfresco, FlowerDocs, Files) while the deployer picks which ones the LLM actually sees.

  • Default value in the shipped application.yaml: flowerdocs,files — Alfresco tools are not registered unless you opt in.
  • Empty list = every @ToolService is registered.
  • A @ToolService without any tag is always registered (backward compatible for custom in-tree tools).
  • Multi-tagged tools are registered when any of their tags matches the whitelist.

See Plugin system — Filtering tools by tag for the full mechanism and test-time usage.

Function-calling model requirement

Tools require a model that supports function calling. If a prompt has requiresFunctionCallingModel: true, the LLM provider must have a model configured with functionCallSupported: true. If reasoningDisabled: true is set on a prompt, tool specifications are not sent to the LLM for that request.

Standardized ECM tool names

Since 2026.0.0-ft4, the document and metadata tools for Alfresco and FlowerDocs share a common, ECM-agnostic vocabulary, so the same prompts and goals work against either backend. The Alfresco tools were de-prefixed and the FlowerDocs data-model tool was renamed:

OperationTool name (ft4)Previous name
Get the tenant data modelgetDataModelAlfresco getAlfrescoDataModel / FlowerDocs getTaskClassAndTagClassesDescriptions
Find document IDs by namegetDocumentIdsByNamegetAlfrescoDocumentIdsByName
Read document contentgetDocumentContentgetAlfrescoDocumentContent / getFlowerDocsDocumentContent
Read document propertiesgetDocumentPropertiesgetAlfrescoDocumentProperties
Update a document propertyupdateDocumentPropertyupdateDocumentPropertyById / updateDocumentTagValueById
Execute a searchdoSearchAlfresco searchAlfrescoNodes / FlowerDocs searchDocuments

The integration tags (alfresco, flowerdocs, files) are unchanged. If you reference tool names explicitly in custom prompts or goals, update them.

Built-in tools: FlowerDocs

The flowerdocs/tool plugin (tag flowerdocs) ships tools the LLM can use to search and operate on FlowerDocs documents:

Tool nameDescription
getDataModelStep 0 prerequisite: retrieves all document classes and tag classes with their programmatic IDs
buildCriterionStringBuilds a search criterion for a text (String) tag
buildCriterionNumberBuilds a search criterion for a numeric (Long) tag
buildCriterionDateBuilds a search criterion for a date tag
buildCriterionClassBuilds a criterion to filter by document class
buildAndClause / buildOrClauseCombine criteria with logical AND / OR into a filter clause
buildAndClauseFromClauses / buildOrClauseFromClausesCombine existing filter clauses (nested logic)
doSearchExecutes the search and returns matching documents
getDocumentIdsByNameLooks up document IDs by name
getDocumentContentReturns the textual content of a document
getDocumentPropertiesReturns a document's metadata (properties, tags, author)
updateDocumentPropertyUpdates a tag / metadata value on a document
previewRevertToPreviousVersionNon-destructive preview of a version restore
revertToPreviousVersion / revertToPreviousVersionBatchRevert one / many documents to the previous version (user confirmation required)
revertToVersionRevert a document to a specific version label (user confirmation required)
prepareRedact / applyObfuscationPrepare and apply a redaction/obfuscation (requires the ARender plugin for rendering)

A typical search session calls getDataModel first, then builds criteria, wraps them in clauses, and calls doSearch.

Built-in tools: Alfresco

Added in 2026.0.0-ft3 (tag alfresco). The integrations/alfresco/tool plugin ships AFTS-backed tools across several @ToolService beans:

Search and filters (AlfrescoFilterToolService, AlfrescoSearchToolService)

Tool nameDescription
getDataModelStep 0 prerequisite: returns the tenant's light data model (common system properties + optional CMM custom types/aspects)
buildTypeFilterAFTS fragment to filter on node type (e.g. cm:content, acme:invoice)
buildPropertyContainsFilterAFTS fragment for partial text match on a property
buildPropertyEqualsFilterAFTS fragment for exact property match
buildDateRangeFilterAFTS fragment for date ranges
buildFullTextFilterAFTS fragment for full-text content search
buildFolderScopedFilterRestrict the search to a folder subtree
buildAndClause / buildOrClauseCombine fragments with logical AND / OR
buildAndClauseFromClauses / buildOrClauseFromClausesCombine existing clauses (nested logic)
doSearchExecutes the assembled AFTS query

Documents (AlfrescoDocumentToolService)

Tool nameDescription
getDocumentIdsByNameLooks up document node IDs by name
getDocumentContentReturns the textual content of a document
listFolderContentsLists files in an Alfresco folder

Metadata (AlfrescoMetadataToolService)

Tool nameDescription
getDocumentPropertiesReturns all metadata properties of a node
updateDocumentPropertyUpdates a property value on a node

Redaction (AlfrescoRedactService)

Tool nameDescription
prepareRedact / applyObfuscationPrepare and apply a redaction/obfuscation (requires the ARender plugin for rendering)

A typical Alfresco search session calls getDataModel first to learn the correct qualified names, builds filters, wraps them in clauses, and finishes with doSearch. See Integrate with Alfresco for deployment steps.

Built-in tools: Interactive choices

Since 2026.0.0-ft4, two built-in tools let the assistant present clickable choices in the chat instead of asking questions in plain text. They are always available — they are not gated by plugins.tools.enabled-tags — and require no prompt or configuration change.

Tool nameDescription
presentChoicesPresents a question with a list of option buttons (each with a label and optional description). An "Other…" option always lets the user type a free-text answer.
presentStepsChoicesPresents a guided multi-step wizard: the user answers a short sequence of questions one at a time; all answers are submitted together at the end.

When the assistant calls one of these tools, the chat and Quick Prompt components render the options as buttons. The user's selection is sent back as an ordinary follow-up message, so the conversation continues normally. These tools are also used to obtain explicit confirmation before destructive operations (such as revertToVersion or applying a redaction).

Custom chat UIs

The assistant emits the choices as a JSON block in its message content; the standard chat and Quick Prompt components parse and render it automatically. A custom UI that displays raw assistant message content should detect and handle this JSON block.

Tools and MCP

ToolExecutor also exposes tools provided by external Model Context Protocol (MCP) servers. Starting with 2026.0.0-ft3, MCP connections are managed through the admin UI rather than through mcp-server.yml: administrators register MCP endpoints from the MCP Servers panel, connections are isolated per tenant when authenticated, and identical unauthenticated connections are pooled and shared across tenants. Tools discovered from an enabled MCP server are registered alongside local tools and are callable in the same way. See Managing MCP servers in the admin UI.