From a0c2c652ad6b19bc8578c81efa622ffba5feaeb8 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 22 Sep 2026 13:12:14 +0200 Subject: [PATCH] Document how chat templates carry tools and data sources --- .../Plugins/assistants/README.md | 5 ++++- .../Plugins/assistants/plugin.lua | 8 +++++++- documentation/Enterprise IT.md | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/MindWork AI Studio/Plugins/assistants/README.md b/app/MindWork AI Studio/Plugins/assistants/README.md index 443a89b8..311c952d 100644 --- a/app/MindWork AI Studio/Plugins/assistants/README.md +++ b/app/MindWork AI Studio/Plugins/assistants/README.md @@ -147,10 +147,13 @@ ASSISTANT = { - `OPEN_TEMPORARY_CHAT` must not carry a `WorkspaceName`. A name next to it stops the plugin from loading rather than being ignored, so a leftover or mistyped name cannot silently turn a workspace launcher into a disappearing one. - Omitted optional IDs use the chat defaults active when the tile is opened. An explicit empty GUID selects no profile or no chat template; an empty provider or data-source GUID is invalid. - `ProviderId` overrides both the chat-specific and app-wide default provider. It must name a provider that is permitted for chats at the required confidence level. -- Explicit data sources are enabled and manually preselected, automatic source selection is disabled, and the normal automatic-validation setting is retained. Every referenced source must currently be available and permitted for the effective provider. +- Explicit data sources are enabled and manually preselected, automatic source selection is disabled, and the normal automatic-validation setting is retained. Every referenced source must currently be available and permitted for the effective provider. This describes a launcher whose chat template brings no data source options of its own; see the rule below for the case where it does. - Invalid or unavailable references stop the launch with an error before a workspace or chat is created. - A selected chat template supplies the chat system prompt, profile allowance, predefined user prompt, attachments, and cloned example conversation. A launcher `SystemPrompt`, if retained in an older plugin, is ignored, so there is never a second competing system prompt. - When the selected chat template does not allow profiles, the template wins: the launcher `ProfileId` is dropped and the chat starts without a profile. This matches the disabled profile selection such a template produces in the chat. +- A chat template may preselect tools and data sources as well. When it does, it decides them alone: the launcher `ToolIds` and `DataSourceIds` are dropped, and AI Studio writes a warning into the log naming both sides. The rule is the same for tools and for data sources, so there is only one to remember. +- The reason the template wins as a whole rather than field by field is a difference in what the two can express. A launcher can only ever say "these sources, picked by hand", while a chat template carries the whole data source options and can also say "let an agent pick the sources for each message". A mix of both would be something neither of them asked for. +- The data sources of a chat template are checked exactly like the ones of a launcher: a source which no longer exists, or which is not permitted for the effective provider, stops the launch before a workspace or chat is created. The message then names the chat template as the cause, not the launcher. A template which leaves the choice to an agent names no source and is therefore not checked here; that decision is made per message in the chat. - The predefined user prompt and the attachments of the selected chat template are placed into the chat input, unless the user already has an unsent draft there. ### Editing a launcher in AI Studio diff --git a/app/MindWork AI Studio/Plugins/assistants/plugin.lua b/app/MindWork AI Studio/Plugins/assistants/plugin.lua index 21d57742..54a28f2e 100644 --- a/app/MindWork AI Studio/Plugins/assistants/plugin.lua +++ b/app/MindWork AI Studio/Plugins/assistants/plugin.lua @@ -454,12 +454,18 @@ ASSISTANT = { ["ProviderId"] = "", ["ProfileId"] = "", ["ChatTemplateId"] = "", + -- Optional: the data sources the chat starts with. A chat template chosen above may bring + -- data source options of its own. It then decides them alone, the IDs named here are dropped, + -- and AI Studio writes a warning into the log. Only a chat template can also say that the AI + -- picks the sources for each message, which is why it wins as a whole instead of field by + -- field. ["DataSourceIds"] = { "", }, -- Optional: the tools preselected when the chat opens. Users may change the selection -- in the chat afterwards, and every tool has to meet the confidence requirements of the - -- provider in use. A tool ID unknown to the installation is ignored. + -- provider in use. A tool ID unknown to the installation is ignored. The same rule as for the + -- data sources applies here: a chat template which names tools of its own wins over this list. -- Tool IDs include: web_search, read_web_page ["ToolIds"] = { "", diff --git a/documentation/Enterprise IT.md b/documentation/Enterprise IT.md index abd2d0c5..e3c5131b 100644 --- a/documentation/Enterprise IT.md +++ b/documentation/Enterprise IT.md @@ -685,6 +685,25 @@ This does not change the SearXNG or Staan settings, the general Web Search setti You can combine both fragments in the same plugin: their table initializations preserve earlier entries, and only a later assignment to an identical key replaces its value. A later whole-table assignment such as `CONFIG["SETTINGS"]["DataTools.LockedToolSettings"] = { ... }` replaces those entries, so place exports after it or merge them manually. This behavior applies within one plugin; across separate configuration plugins, the winning plugin replaces the whole managed table as described in [Settings that hold a list or a table](#settings-that-hold-a-list-or-a-table). +## Chat templates with tools and data sources + +A chat template also decides the tools and the data sources a chat started with it begins with. Configure and export the template in the app as usual; its fragment belongs in your plugin after the `CONFIG["CHAT_TEMPLATES"] = {}` initialization. + +The data source IDs in that fragment are **carried over unchanged**, unlike the template ID, which is new with every export: they point at the data sources of your organization. Check them against your `CONFIG["DATA_SOURCES"]` -- an ID that resolves to nothing is ignored, and a chat with that template then starts without that source. + +Writing such a template by hand means knowing that saying nothing and saying none are two different statements: + +| What the template says | What a chat started with it does | +|---|---| +| no `ToolIds` at all | starts with the tools the user has set as their chat default | +| `ToolIds` present but empty | starts with no tool at all, whatever that default says | +| no `DataSourceOptions` at all | starts with the data source options the user has set as their chat default | +| `DataSourceOptions` present | starts with exactly those, including the choice to let an agent pick the sources | + +Writing the `DataSourceOptions` table at all is already the statement that this template wants data sources, so `DisableDataSources` starts at `false` inside it, unlike everywhere else in the app. + +When an [assistant plugin](../app/MindWork%20AI%20Studio/Plugins/assistants/README.md) opens a chat directly and its chat template names tools or data sources, that template decides them alone; what the launcher names is dropped with a warning in the log. Its README explains the rule and how such sources are checked. + ## Letting users provide their own API key Sometimes you want to hand out a preconfigured provider -- a fixed host, model, and instance name