mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-09-27 00:13:38 +00:00
Keep context-activated tools out of every tool selection
This commit is contained in:
parent
a9825520f4
commit
df257714f2
@ -0,0 +1,23 @@
|
||||
namespace AIStudio.Tools.ToolCallingSystem;
|
||||
|
||||
/// <summary>
|
||||
/// How a tool comes to be offered to a model.
|
||||
/// </summary>
|
||||
public enum ToolActivation
|
||||
{
|
||||
/// <summary>
|
||||
/// Offered when it was selected: by the user, a chat template, a policy, or an assistant.
|
||||
/// </summary>
|
||||
SELECTION,
|
||||
|
||||
/// <summary>
|
||||
/// Offered whenever the chat calls for it, without anybody selecting it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For a tool whose use is already decided somewhere else. Semantic Search is such a tool: the
|
||||
/// user picks the data sources of a chat, and a second switch for searching them would only be
|
||||
/// a way to contradict the first one. Such a tool never appears in a selection, and it decides
|
||||
/// on each request whether it has anything to offer.
|
||||
/// </remarks>
|
||||
CONTEXT,
|
||||
}
|
||||
@ -12,6 +12,11 @@ public sealed class ToolDefinition
|
||||
|
||||
public ToolVisibilityDefinition VisibleIn { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the tool waits to be selected, or offers itself whenever the chat calls for it.
|
||||
/// </summary>
|
||||
public ToolActivation Activation { get; init; } = ToolActivation.SELECTION;
|
||||
|
||||
public ToolSettingsSchema SettingsSchema { get; init; } = new();
|
||||
|
||||
public string SystemPromptInstructions { get; init; } = string.Empty;
|
||||
|
||||
@ -269,9 +269,19 @@ public sealed class ToolRegistry
|
||||
return filtered;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tools somebody can select in this component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Every selection in the app is built from this list: the one below the message field, the
|
||||
/// defaults, the templates, and the tools the AI picks for a new assistant. A tool which offers
|
||||
/// itself from the context of a chat is left out, because selecting it would change nothing.
|
||||
/// The tool list of the app settings asks for all definitions instead, so an organization can
|
||||
/// still switch such a tool off or set the trust it requires.
|
||||
/// </remarks>
|
||||
public async Task<IReadOnlyList<ToolCatalogItem>> GetCatalogAsync(Components component)
|
||||
{
|
||||
var definitions = this.GetDefinitionsForComponent(component);
|
||||
var definitions = this.GetDefinitionsForComponent(component).Where(x => x.Activation is ToolActivation.SELECTION);
|
||||
return await this.GetCatalogAsync(definitions);
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ public static class ToolSelectionRules
|
||||
public const string WEB_SEARCH_TOOL_ID = "web_search";
|
||||
public const string READ_WEB_PAGE_TOOL_ID = "read_web_page";
|
||||
public const string SEARCH_CONFLUENCE_TOOL_ID = "search_confluence";
|
||||
public const string SEMANTIC_SEARCH_TOOL_ID = "semantic_search";
|
||||
|
||||
/// <summary>
|
||||
/// Turns a set of selected tool IDs into the set which actually runs.
|
||||
@ -19,6 +20,10 @@ public static class ToolSelectionRules
|
||||
/// ToolRegistry still drops it when it is switched off or the provider's confidence is too
|
||||
/// low, and Read Web Page reaches a wiki on a private or VPN address only when its host is
|
||||
/// allowed there.<br/><br/>
|
||||
/// It also removes the tools nobody selects. Semantic Search offers itself whenever the data
|
||||
/// sources of a chat call for it, see ToolActivation.CONTEXT; kept in a selection, it would
|
||||
/// appear on the security card of a plugin and in its audit without the selection having any
|
||||
/// say in whether it runs.<br/><br/>
|
||||
/// Every place which shows or stores a selection normalizes it, the tool selection fields
|
||||
/// included. That way a chat, a template, a policy, or an assistant plugin shows the tools
|
||||
/// which will actually run, and the audit of a plugin judges exactly those.
|
||||
@ -29,6 +34,7 @@ public static class ToolSelectionRules
|
||||
if (normalized.Contains(SEARCH_CONFLUENCE_TOOL_ID))
|
||||
normalized.Add(READ_WEB_PAGE_TOOL_ID);
|
||||
|
||||
normalized.Remove(SEMANTIC_SEARCH_TOOL_ID);
|
||||
return normalized;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ public sealed class ToolSelectionRulesTests
|
||||
private const string SEARCH_CONFLUENCE = ToolSelectionRules.SEARCH_CONFLUENCE_TOOL_ID;
|
||||
private const string READ_WEB_PAGE = ToolSelectionRules.READ_WEB_PAGE_TOOL_ID;
|
||||
private const string WEB_SEARCH = ToolSelectionRules.WEB_SEARCH_TOOL_ID;
|
||||
private const string SEMANTIC_SEARCH = ToolSelectionRules.SEMANTIC_SEARCH_TOOL_ID;
|
||||
|
||||
[Test]
|
||||
public void SearchConfluenceBringsReadWebPageAlong()
|
||||
@ -30,6 +31,12 @@ public sealed class ToolSelectionRulesTests
|
||||
Assert.That(ToolSelectionRules.NormalizeSelection([toolId]), Is.EquivalentTo(new[] { toolId }), "Only Search Confluence depends on another tool. Read Web Page in particular does not pull the search in.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SemanticSearchIsNeverPartOfASelection()
|
||||
{
|
||||
Assert.That(ToolSelectionRules.NormalizeSelection([SEMANTIC_SEARCH, WEB_SEARCH]), Is.EquivalentTo(new[] { WEB_SEARCH }), "Semantic Search offers itself from the data sources of a chat. A template or a plugin naming it would put a tool on the security card that the selection has no say over.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NormalizingTwiceChangesNothing()
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user