mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-06-27 14:56:27 +00:00
Fixed some bugs.
This commit is contained in:
parent
8fd7e18113
commit
2ad591f117
@ -194,6 +194,10 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
||||
|
||||
private async Task Start()
|
||||
{
|
||||
await this.RefreshProviderSelectionFromConfigurationAsync();
|
||||
if (this.ProviderSettings == Settings.Provider.NONE)
|
||||
return;
|
||||
|
||||
using (this.CancellationTokenSource = new())
|
||||
{
|
||||
await this.SubmitAction();
|
||||
@ -275,11 +279,18 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
||||
return chatId;
|
||||
}
|
||||
|
||||
private Task RefreshProviderSelectionFromConfigurationAsync()
|
||||
{
|
||||
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(this.Component, this.ProviderSettings.Id);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual void ResetProviderAndProfileSelection()
|
||||
{
|
||||
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
|
||||
this.CurrentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
|
||||
this.CurrentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component);
|
||||
this.selectedToolIds = this.SettingsManager.GetDefaultToolIds(this.Component);
|
||||
}
|
||||
|
||||
protected Task SelectedToolIdsChanged(HashSet<string> updatedToolIds)
|
||||
@ -336,7 +347,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
||||
this.ChatThread.SelectedProvider = this.ProviderSettings.Id;
|
||||
this.ChatThread.RuntimeComponent = this.Component;
|
||||
this.ChatThread.RuntimeSelectedToolIds = this.SettingsManager.IsToolSelectionVisible(this.Component)
|
||||
? ToolSelectionRules.NormalizeSelection(this.selectedToolIds)
|
||||
? this.SettingsManager.FilterToolIdsForProvider(this.ProviderSettings, this.selectedToolIds)
|
||||
: [];
|
||||
}
|
||||
|
||||
|
||||
@ -3031,9 +3031,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1725856265
|
||||
-- Icon
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1759955728"] = "Icon"
|
||||
|
||||
-- Configure global settings for each tool. Tool defaults for chat and assistants are configured in the corresponding feature settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T176751696"] = "Configure global settings for each tool. Tool defaults for chat and assistants are configured in the corresponding feature settings."
|
||||
|
||||
-- This tool still needs to be configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1958939818"] = "This tool still needs to be configured."
|
||||
|
||||
@ -3049,11 +3046,14 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T2828607242
|
||||
-- Minimum provider confidence
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3461070436"] = "Minimum provider confidence"
|
||||
|
||||
-- Configure global settings for each tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3728248397"] = "Configure global settings for each tool."
|
||||
|
||||
-- Tool Settings
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3730473128"] = "Tool Settings"
|
||||
|
||||
-- State
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T502047894"] = "State"
|
||||
-- Status
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T6222351"] = "Status"
|
||||
|
||||
-- No transcription provider configured yet.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T1079350363"] = "No transcription provider configured yet."
|
||||
@ -3160,21 +3160,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1351725609"] = "This tool
|
||||
-- Tool changes are locked while a response is running. Your current selection is shown below and applies again from the next message once the run is finished.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1688023907"] = "Tool changes are locked while a response is running. Your current selection is shown below and applies again from the next message once the run is finished."
|
||||
|
||||
-- Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1944689297"] = "Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages."
|
||||
|
||||
-- Enabling this tool also enables Read Web Page.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3023833839"] = "Enabling this tool also enables Read Web Page."
|
||||
|
||||
-- Required settings are missing. Configure this tool before enabling it.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3119156561"] = "Required settings are missing. Configure this tool before enabling it."
|
||||
|
||||
-- The selected provider or model does not support tool calling.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3364063757"] = "The selected provider or model does not support tool calling."
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3448155331"] = "Close"
|
||||
|
||||
-- Tool calling for this provider is not implemented yet.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3776963202"] = "Tool calling for this provider is not implemented yet."
|
||||
|
||||
-- No tools are available in this context.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3904490680"] = "No tools are available in this context."
|
||||
|
||||
@ -8008,9 +8005,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T40564
|
||||
-- Load a single web page and extract its main HTML content.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T204256540"] = "Load a single web page and extract its main HTML content."
|
||||
|
||||
-- Optional global truncation limit for extracted Markdown returned to the model.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2066580916"] = "Optional global truncation limit for extracted Markdown returned to the model."
|
||||
|
||||
-- Allowed private hosts must be host names only, without scheme or path.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2196457612"] = "Allowed private hosts must be host names only, without scheme or path."
|
||||
|
||||
@ -8032,6 +8026,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Read Web Page
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3612587998"] = "Read Web Page"
|
||||
|
||||
-- Optional global truncation limit for extracted characters returned to the model.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T364016543"] = "Optional global truncation limit for extracted characters returned to the model."
|
||||
|
||||
-- The web page was not loaded because private or VPN web pages require a High-confidence provider.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3856267430"] = "The web page was not loaded because private or VPN web pages require a High-confidence provider."
|
||||
|
||||
|
||||
@ -78,7 +78,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
private Guid loadedParameterWorkspaceId = Guid.Empty;
|
||||
private Guid foregroundChatId = Guid.Empty;
|
||||
private int workspaceHeaderSyncVersion;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
|
||||
// Unfortunately, we need the input field reference to blur the focus away. Without
|
||||
// this, we cannot clear the input field.
|
||||
@ -104,7 +103,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Apply the filters for the message bus:
|
||||
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE, Event.CHAT_STREAMING_DONE, Event.AI_JOB_CHANGED, Event.AI_JOB_FINISHED, Event.CHAT_GENERATION_CHANGED ]);
|
||||
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE, Event.CHAT_STREAMING_DONE, Event.AI_JOB_CHANGED, Event.AI_JOB_FINISHED, Event.CHAT_GENERATION_CHANGED, Event.CONFIGURATION_CHANGED ]);
|
||||
|
||||
// Configure the spellchecking for the user input:
|
||||
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
||||
@ -577,6 +576,8 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
private async Task SendMessage(bool reuseLastUserPrompt = false)
|
||||
{
|
||||
await this.RefreshProviderSelectionFromConfigurationAsync();
|
||||
|
||||
if (!this.IsProviderSelected)
|
||||
return;
|
||||
|
||||
@ -695,34 +696,17 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
}
|
||||
|
||||
this.Logger.LogDebug($"Start processing user input using provider '{this.Provider.InstanceName}' with model '{this.Provider.Model}'.");
|
||||
// TODO: await this.AIJobService.TryStartChatGenerationAsync(new ChatGenerationRequest
|
||||
//{
|
||||
// ChatThread = this.ChatThread!,
|
||||
// AIText = aiText,
|
||||
// LastUserPrompt = lastUserPrompt,
|
||||
// ProviderSettings = this.Provider,
|
||||
// IsForeground = true,
|
||||
//});
|
||||
using (this.cancellationTokenSource = new CancellationTokenSource())
|
||||
this.StateHasChanged();
|
||||
this.ChatThread!.RuntimeComponent = Tools.Components.CHAT;
|
||||
this.ChatThread.RuntimeSelectedToolIds = this.SettingsManager.FilterToolIdsForProvider(this.Provider, this.selectedToolIds);
|
||||
await this.AIJobService.TryStartChatGenerationAsync(new ChatGenerationRequest
|
||||
{
|
||||
this.StateHasChanged();
|
||||
this.ChatThread!.RuntimeComponent = Tools.Components.CHAT;
|
||||
this.ChatThread.RuntimeSelectedToolIds = ToolSelectionRules.NormalizeSelection(this.selectedToolIds);
|
||||
|
||||
// Use the selected provider to get the AI response.
|
||||
// By awaiting this line, we wait for the entire
|
||||
// content to be streamed.
|
||||
this.ChatThread = await aiText.CreateFromProviderAsync(this.Provider.CreateProvider(), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
this.cancellationTokenSource = null;
|
||||
|
||||
// Save the chat:
|
||||
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
||||
{
|
||||
await this.SaveThread();
|
||||
}
|
||||
|
||||
ChatThread = this.ChatThread,
|
||||
AIText = aiText,
|
||||
LastUserPrompt = lastUserPrompt,
|
||||
ProviderSettings = this.Provider,
|
||||
IsForeground = true,
|
||||
});
|
||||
await this.SyncForegroundChatAsync();
|
||||
this.StateHasChanged();
|
||||
}
|
||||
@ -801,7 +785,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
//
|
||||
this.hasUnsavedChanges = false;
|
||||
this.ComposerState.Clear();
|
||||
this.selectedToolIds = this.SettingsManager.GetDefaultToolIds(Tools.Components.CHAT);
|
||||
this.selectedToolIds = ToolSelectionRules.NormalizeSelection(this.SettingsManager.GetDefaultToolIds(Tools.Components.CHAT));
|
||||
|
||||
//
|
||||
// Reset the LLM provider considering the user's settings:
|
||||
@ -948,6 +932,19 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
this.StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task RefreshProviderSelectionFromConfigurationAsync()
|
||||
{
|
||||
var updatedProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT, this.Provider.Id);
|
||||
var providerChanged = updatedProvider != this.Provider;
|
||||
if (providerChanged)
|
||||
this.Provider = updatedProvider;
|
||||
|
||||
if (!providerChanged)
|
||||
return;
|
||||
|
||||
await this.ProviderChanged.InvokeAsync(this.Provider);
|
||||
}
|
||||
|
||||
private async Task ResetState()
|
||||
{
|
||||
@ -1091,6 +1088,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
break;
|
||||
|
||||
case Event.CONFIGURATION_CHANGED:
|
||||
await this.RefreshProviderSelectionFromConfigurationAsync();
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -186,5 +186,6 @@ public partial class SettingsPanelProviders : SettingsPanelProviderBase
|
||||
{
|
||||
this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme[llmProvider] = level;
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Build" HeaderText="@T("Tool Settings")">
|
||||
<MudText Typo="Typo.body1" Class="mb-4">
|
||||
@T("Configure global settings for each tool. Tool defaults for chat and assistants are configured in the corresponding feature settings.")
|
||||
@T("Configure global settings for each tool.")
|
||||
</MudText>
|
||||
|
||||
<MudTable Items="@this.items" Hover="@true" Dense="@true">
|
||||
@ -13,7 +13,7 @@
|
||||
<MudTh>@T("Name")</MudTh>
|
||||
<MudTh>@T("Description")</MudTh>
|
||||
<MudTh>@T("Minimum provider confidence")</MudTh>
|
||||
<MudTh>@T("State")</MudTh>
|
||||
<MudTh>@T("Status")</MudTh>
|
||||
<MudTh>@T("Settings")</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
</CardHeaderContent>
|
||||
</MudCardHeader>
|
||||
<MudCardContent Style="min-width: 28em; max-height: 60vh; max-width: 48vw; overflow: auto;">
|
||||
<MudText Typo="Typo.body1" Class="mb-3">
|
||||
@T("Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages.")
|
||||
</MudText>
|
||||
@if (!this.SupportsTools)
|
||||
{
|
||||
<MudText Typo="Typo.body1">@this.UnsupportedToolsMessage</MudText>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using AIStudio.Dialogs.Settings;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools;
|
||||
using AIStudio.Tools.ToolCallingSystem;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@ -49,22 +48,15 @@ public partial class ToolSelection : MSGComponentBase
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
private bool SupportsTools =>
|
||||
this.LLMProvider != AIStudio.Settings.Provider.NONE &&
|
||||
(this.LLMProvider.GetModelCapabilities().Contains(Capability.CHAT_COMPLETION_API) ||
|
||||
this.LLMProvider.GetModelCapabilities().Contains(Capability.RESPONSES_API)) &&
|
||||
this.LLMProvider.GetModelCapabilities().Contains(Capability.FUNCTION_CALLING);
|
||||
private ToolCallingAvailability ToolCallingAvailability => this.LLMProvider.GetToolCallingAvailability();
|
||||
|
||||
private bool IsAnthropicProvider => this.LLMProvider != AIStudio.Settings.Provider.NONE &&
|
||||
this.LLMProvider.UsedLLMProvider is LLMProviders.ANTHROPIC;
|
||||
private bool SupportsTools => this.ToolCallingAvailability.IsAvailable;
|
||||
|
||||
private string ToolButtonTooltip => this.SupportsTools
|
||||
? this.T("Select tools")
|
||||
: this.UnsupportedToolsMessage;
|
||||
|
||||
private string UnsupportedToolsMessage => this.IsAnthropicProvider
|
||||
? this.T("Tool calling for this provider is not implemented yet.")
|
||||
: this.T("The selected model does not support tool calling.");
|
||||
private string UnsupportedToolsMessage => this.ToolCallingAvailability.Message;
|
||||
|
||||
private ConfidenceLevel ProviderConfidence => this.LLMProvider == AIStudio.Settings.Provider.NONE
|
||||
? ConfidenceLevel.NONE
|
||||
|
||||
@ -1927,7 +1927,7 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1350385882"] = "Ja, ent
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1434043348"] = "Fehlgeschlagen"
|
||||
|
||||
-- Tool Calls ({0})
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1493057571"] = "Tool-Aufrufe"
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1493057571"] = "Werkzeugaufrufe"
|
||||
|
||||
-- Executed
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1564757972"] = "Ausgeführt"
|
||||
@ -1945,10 +1945,10 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Ja, ent
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1848978959"] = "Anzahl der Quellen"
|
||||
|
||||
-- Show {0} tool calls
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1981771421"] = "{0} Toolaufrufe anzeigen"
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1981771421"] = "{0} Werkzeugaufrufe anzeigen"
|
||||
|
||||
-- Show tool call for {0}
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2004842583"] = "Tool-Aufruf für {0}"
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2004842583"] = "Werkzeugaufruf für {0}"
|
||||
|
||||
-- Do you really want to edit this message? In order to edit this message, the AI response will be deleted.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Möchten Sie diese Nachricht wirklich bearbeiten? Um die Nachricht zu bearbeiten, wird die Antwort der KI gelöscht."
|
||||
@ -1995,6 +1995,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4224149521"] = "Verstan
|
||||
-- Export Chat to Microsoft Word
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T861873672"] = "Chat in Microsoft Word exportieren"
|
||||
|
||||
-- No arguments
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T931993614"] = "Keine Argumente"
|
||||
|
||||
-- The selected model '{0}' is no longer available from '{1}' (provider={2}). Please adapt your provider settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTTEXT::T3267850764"] = "Das ausgewählte Modell '{0}' ist bei '{1}' (Anbieter={2}) nicht mehr verfügbar. Bitte passen Sie Ihre Anbietereinstellungen an."
|
||||
|
||||
@ -3030,9 +3033,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1725856265
|
||||
-- Icon
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1759955728"] = "Symbol"
|
||||
|
||||
-- Configure global settings for each tool. Tool defaults for chat and assistants are configured in the corresponding feature settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T176751696"] = "Globale Einstellungen für jedes Tool konfigurieren. Standardwerte für Tools für Chats und Assistenten werden in den entsprechenden Funktionseinstellungen konfiguriert."
|
||||
|
||||
-- This tool still needs to be configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1958939818"] = "Dieses Werkzeug muss noch konfiguriert werden."
|
||||
|
||||
@ -3048,11 +3048,14 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T2828607242
|
||||
-- Minimum provider confidence
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3461070436"] = "Minimale Anbieterzuverlässigkeit"
|
||||
|
||||
-- Configure global settings for each tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3728248397"] = "Konfiguriere globale Einstellungen für jedes Werkzeug."
|
||||
|
||||
-- Tool Settings
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3730473128"] = "Werkzeugeinstellungen"
|
||||
|
||||
-- State
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T502047894"] = "Status"
|
||||
-- Status
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T6222351"] = "Status"
|
||||
|
||||
-- No transcription provider configured yet.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T1079350363"] = "Es ist bisher kein Anbieter für Transkriptionen konfiguriert."
|
||||
@ -3145,7 +3148,7 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3494508870"]
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3729156356"] = "Sie haben {0} Werkzeuge ausgewählt."
|
||||
|
||||
-- No tools selected.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3934845540"] = "Keine Tools ausgewählt."
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3934845540"] = "Keine Werkzeuge ausgewählt."
|
||||
|
||||
-- Default tools for chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T907403808"] = "Standardwerkzeuge für den Chat"
|
||||
@ -3159,14 +3162,14 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1351725609"] = "Dieses We
|
||||
-- Tool changes are locked while a response is running. Your current selection is shown below and applies again from the next message once the run is finished.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1688023907"] = "Werkzeugänderungen sind gesperrt, während eine Antwort ausgeführt wird. Ihre aktuelle Auswahl wird unten angezeigt und gilt nach Abschluss der Ausführung ab der nächsten Nachricht wieder."
|
||||
|
||||
-- Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1944689297"] = "Werkzeuge ermöglichen es dem LLM, gezielte zusätzliche Aktionen auszuführen, wie z. B. Websuchen oder das Lesen von Webseiten."
|
||||
|
||||
-- Enabling this tool also enables Read Web Page.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3023833839"] = "Das Aktivieren dieses Werkzeugs aktiviert auch „Webseite lesen“."
|
||||
|
||||
-- Required settings are missing. Configure this tool before enabling it.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3119156561"] = "Erforderliche Einstellungen fehlen. Konfigurieren Sie dieses Tool, bevor Sie es aktivieren."
|
||||
|
||||
-- The selected provider or model does not support tool calling.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3364063757"] = "Der ausgewählte Anbieter oder das ausgewählte Modell unterstützt keine Tool-Aufrufe."
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3119156561"] = "Erforderliche Einstellungen fehlen. Konfigurieren Sie dieses Werkzeug, bevor Sie es aktivieren."
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3448155331"] = "Schließen"
|
||||
@ -3181,7 +3184,7 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T4097602620"] = "Dieses We
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T749664565"] = "Werkzeugauswahl"
|
||||
|
||||
-- Select tools
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T998515990"] = "Tools auswählen"
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T998515990"] = "Werkzeuge auswählen"
|
||||
|
||||
-- You'll interact with the AI systems using your voice. To achieve this, we want to integrate voice input (speech-to-text) and output (text-to-speech). However, later on, it should also have a natural conversation flow, i.e., seamless conversation.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::VISION::T1015366320"] = "Sie werden mit den KI-Systemen über ihre Stimme interagieren. Dafür möchten wir Spracheingabe (Sprache-zu-Text) und Sprachausgabe (Text-zu-Sprache) integrieren. Später soll außerdem ein natürlicher Gesprächsfluss möglich sein, also eine nahtlose Unterhaltung."
|
||||
@ -5793,6 +5796,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T3730473128"]
|
||||
-- The selected tool could not be loaded.
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T3907843187"] = "Das ausgewählte Werkzeug konnte nicht geladen werden."
|
||||
|
||||
-- {0} Default: {1}
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T403490413"] = "{0} Standard: {1}"
|
||||
|
||||
-- Cancel
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T900713019"] = "Abbrechen"
|
||||
|
||||
@ -6399,12 +6405,12 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2989678330"] = "Kopiert den Fing
|
||||
-- Changelog
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3017574265"] = "Änderungsprotokoll"
|
||||
|
||||
-- Vector store
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3046399223"] = "Vektordatenbank"
|
||||
|
||||
-- External HTTPS custom root certificates are configured but not active.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3021325354"] = "Externe benutzerdefinierte Stammzertifikate sind konfiguriert, aber nicht aktiv."
|
||||
|
||||
-- Vector store
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3046399223"] = "Vektordatenbank"
|
||||
|
||||
-- Enterprise configuration ID:
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3092349641"] = "Unternehmenskonfigurations-ID:"
|
||||
|
||||
@ -6757,7 +6763,7 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3014737766"] = "Wir haben ve
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3049689432"] = "Wir haben versucht, mit dem LLM-Anbieter „{0}“ (Typ={1}) zu kommunizieren. Selbst nach {2} erneuten Versuchen gab es weiterhin Probleme mit der Anfrage. Die Meldung des Anbieters lautet: „{3}“."
|
||||
|
||||
-- The tool calling request failed with status code {0}. See the logs for details.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3117779001"] = "Die Tool-Aufrufanfrage ist mit dem Statuscode {0} fehlgeschlagen. Details finden Sie in den Logs."
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3117779001"] = "Die Werkzeuganfrage ist mit dem Statuscode {0} fehlgeschlagen. Details finden Sie in den Logs."
|
||||
|
||||
-- Tried to communicate with the LLM provider '{0}'. There were some problems with the request. The provider message is: '{1}'
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3573577433"] = "Es wurde versucht, mit dem LLM-Anbieter '{0}' zu kommunizieren. Dabei sind Probleme bei der Anfrage aufgetreten. Die Meldung des Anbieters lautet: '{1}'"
|
||||
@ -6828,9 +6834,6 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T3424652889"] = "Un
|
||||
-- no model selected
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "Kein Modell ausgewählt"
|
||||
|
||||
-- The tool calling request failed with status code {0}. See the logs for details.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::OPENAI::PROVIDEROPENAI::T3117779001"] = "Die Anfrage zum Aufruf des Tools ist mit dem Statuscode {0} fehlgeschlagen. Details findest du in den Protokollen."
|
||||
|
||||
-- We could not load models from '{0}'. The account or API key does not have the required permissions.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODELLOADFAILUREREASONEXTENSIONS::T1143085203"] = "Wir konnten keine Modelle von '{0}' laden. Das Konto oder der API-Schlüssel verfügt nicht über die erforderlichen Berechtigungen."
|
||||
|
||||
@ -6852,6 +6855,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODELLOADFAILUREREASONEXTENSIONS::T37333904
|
||||
-- We could not load models from '{0}' due to an unknown error.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODELLOADFAILUREREASONEXTENSIONS::T3907712809"] = "Wir konnten die Modelle aus '{0}' aufgrund eines unbekannten Fehlers nicht laden."
|
||||
|
||||
-- The tool calling request failed with status code {0}. See the logs for details.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::OPENAI::PROVIDEROPENAI::T3117779001"] = "Die Anfrage zum Aufruf des Werkzeugs ist mit dem Statuscode {0} fehlgeschlagen. Details findest du in den Protokollen."
|
||||
|
||||
-- It looks like you do not have any API credits left with OpenAI. Please add credits to your account and try again.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::OPENAI::PROVIDEROPENAI::T757371511"] = "Anscheinend haben Sie bei OpenAI kein API-Guthaben mehr. Bitte fügen Sie Ihrem Konto Guthaben hinzu und versuchen Sie es erneut."
|
||||
|
||||
@ -7998,15 +8004,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T35170
|
||||
-- Tool description
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T4056470505"] = "Werkzeugbeschreibung"
|
||||
|
||||
-- Optional global truncation limit for extracted Markdown returned to the model.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2066580916"] = "Optionales globales Kürzungslimit für extrahiertes Markdown, das an das Modell zurückgegeben wird."
|
||||
-- Load a single web page and extract its main HTML content.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T204256540"] = "Eine einzelne Webseite laden und deren Haupt-HTML-Inhalt extrahieren."
|
||||
|
||||
-- Allowed private hosts must be host names only, without scheme or path.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2196457612"] = "Zulässige private Hosts dürfen nur Hostnamen enthalten, ohne Schema oder Pfad."
|
||||
|
||||
-- Optional host allowlist for private or VPN web pages. Separate host patterns with commas, such as example.de, *.example.de. Allowed private hosts require a High-confidence provider.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T237631450"] = "Optionale Host-Zulassungsliste für private oder VPN-Webseiten. Trennen Sie Host-Muster mit Kommas, zum Beispiel example.de, *.example.de. Zugelassene private Hosts erfordern einen Anbieter mit hoher Vertrauensstufe."
|
||||
|
||||
-- Maximum Content Characters
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2801581200"] = "Maximale Inhaltszeichen"
|
||||
|
||||
@ -8025,9 +8028,15 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Read Web Page
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3612587998"] = "Webseite lesen"
|
||||
|
||||
-- Optional global truncation limit for extracted characters returned to the model.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T364016543"] = "Optionale globale Begrenzung für extrahierte Zeichen, die an das Modell zurückgegeben werden."
|
||||
|
||||
-- The web page was not loaded because private or VPN web pages require a High-confidence provider.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3856267430"] = "Die Webseite wurde nicht geladen, da private Webseiten oder Webseiten über ein VPN einen Anbieter mit hoher Vertrauensstufe erfordern."
|
||||
|
||||
-- Optional host allowlist for private or VPN web pages. For security reasons, private or VPN web pages aren't allowed to be read by default. Separate host patterns with commas, such as example.de, *.example.de. Allowed private hosts require a high-confidence provider. For allowed internal hosts, AI Studio also tries the operating system's default sign-in automatically when the server responds with integrated authentication.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T854695329"] = "Optionale Host-Allowlist für private oder VPN-Webseiten. Aus Sicherheitsgründen ist der Zugriff auf private oder VPN-Webseiten standardmäßig nicht erlaubt. Trennen Sie Host-Muster durch Kommas, z. B. example.de, *.example.de. Für erlaubte private Hosts ist ein Anbieter mit hohem Vertrauensniveau erforderlich. Bei erlaubten internen Hosts versucht AI Studio automatisch die Standardanmeldung des Betriebssystems, wenn der Server mit integrierter Authentifizierung antwortet."
|
||||
|
||||
-- Maximum Results
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1273024715"] = "Maximale Anzahl an Ergebnissen"
|
||||
|
||||
@ -8074,7 +8083,7 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3967748757"] = "Optionale SafeSearch-Richtlinie, die bei entsprechender Konfiguration an SearXNG gesendet wird."
|
||||
|
||||
-- Default categories and default engines cannot both be set for the web search tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Standardkategorien und Standard-Engines können für das Websuch-Tool nicht gleichzeitig festgelegt werden."
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Standardkategorien und Standard-Engines können für die Websuche nicht gleichzeitig festgelegt werden."
|
||||
|
||||
-- Optional comma-separated default engines. Do not set this together with default categories.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4108908537"] = "Optionale, durch Kommas getrennte Standard-Engines. Nicht zusammen mit Standardkategorien festlegen."
|
||||
@ -8082,6 +8091,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- The setting '{0}' must be a positive integer.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4199432074"] = "Die Einstellung „{0}“ muss eine positive ganze Zahl sein."
|
||||
|
||||
-- Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T764865565"] = "Im Internet mit einer konfigurierten SearXNG-Instanz suchen und Kandidaten-URLs für das Modell zurückgeben. Verwende „Webseite lesen“ auf relevanten Ergebnis-URLs, bevor du faktische oder detaillierte Webfragen beantwortest."
|
||||
|
||||
-- The configured SearXNG URL must start with http:// or https://.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T944878454"] = "Die konfigurierte SearXNG-URL muss mit http:// oder https:// beginnen."
|
||||
|
||||
|
||||
@ -1914,21 +1914,42 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CHATROLEEXTENSIONS::T601166687"] = "AI"
|
||||
-- Edit Message
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message"
|
||||
|
||||
-- Result
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347088452"] = "Result"
|
||||
|
||||
-- Do you really want to remove this message?
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?"
|
||||
|
||||
-- Yes, remove the AI response and edit it
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1350385882"] = "Yes, remove the AI response and edit it"
|
||||
|
||||
-- Failed
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1434043348"] = "Failed"
|
||||
|
||||
-- Tool Calls ({0})
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1493057571"] = "Tool Calls ({0})"
|
||||
|
||||
-- Executed
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1564757972"] = "Executed"
|
||||
|
||||
-- Yes, regenerate it
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1603883875"] = "Yes, regenerate it"
|
||||
|
||||
-- No result
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1684269223"] = "No result"
|
||||
|
||||
-- Yes, remove it
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Yes, remove it"
|
||||
|
||||
-- Number of sources
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1848978959"] = "Number of sources"
|
||||
|
||||
-- Show {0} tool calls
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1981771421"] = "Show {0} tool calls"
|
||||
|
||||
-- Show tool call for {0}
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2004842583"] = "Show tool call for {0}"
|
||||
|
||||
-- Do you really want to edit this message? In order to edit this message, the AI response will be deleted.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Do you really want to edit this message? In order to edit this message, the AI response will be deleted."
|
||||
|
||||
@ -1938,6 +1959,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2093355991"] = "Removes
|
||||
-- Regenerate Message
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2308444540"] = "Regenerate Message"
|
||||
|
||||
-- Arguments
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2738624831"] = "Arguments"
|
||||
|
||||
-- Number of attachments
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3018847255"] = "Number of attachments"
|
||||
|
||||
@ -1947,9 +1971,15 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3175548294"] = "Cannot
|
||||
-- Edit
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3267849393"] = "Edit"
|
||||
|
||||
-- Unknown
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3424652889"] = "Unknown"
|
||||
|
||||
-- Regenerate
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3587744975"] = "Regenerate"
|
||||
|
||||
-- Blocked
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3816336467"] = "Blocked"
|
||||
|
||||
-- Do you really want to regenerate this message?
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Do you really want to regenerate this message?"
|
||||
|
||||
@ -1959,9 +1989,15 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove
|
||||
-- No, keep it
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4188329028"] = "No, keep it"
|
||||
|
||||
-- No tool calls
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4224149521"] = "No tool calls"
|
||||
|
||||
-- Export Chat to Microsoft Word
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T861873672"] = "Export Chat to Microsoft Word"
|
||||
|
||||
-- No arguments
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T931993614"] = "No arguments"
|
||||
|
||||
-- The selected model '{0}' is no longer available from '{1}' (provider={2}). Please adapt your provider settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTTEXT::T3267850764"] = "The selected model '{0}' is no longer available from '{1}' (provider={2}). Please adapt your provider settings."
|
||||
|
||||
@ -2178,15 +2214,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T252
|
||||
-- Select a minimum confidence level
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T2579793544"] = "Select a minimum confidence level"
|
||||
|
||||
-- You have selected 1 preview feature.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMULTISELECT::T1384241824"] = "You have selected 1 preview feature."
|
||||
|
||||
-- No preview features selected.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMULTISELECT::T2809641588"] = "No preview features selected."
|
||||
|
||||
-- You have selected {0} preview features.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMULTISELECT::T3513450626"] = "You have selected {0} preview features."
|
||||
|
||||
-- Preselected provider
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T1469984996"] = "Preselected provider"
|
||||
|
||||
@ -2997,6 +3024,39 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T900237
|
||||
-- Export configuration
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T975426229"] = "Export configuration"
|
||||
|
||||
-- Settings
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1258653480"] = "Settings"
|
||||
|
||||
-- Description
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1725856265"] = "Description"
|
||||
|
||||
-- Icon
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1759955728"] = "Icon"
|
||||
|
||||
-- This tool still needs to be configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T1958939818"] = "This tool still needs to be configured."
|
||||
|
||||
-- Missing required settings: {0}
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T2588115579"] = "Missing required settings: {0}"
|
||||
|
||||
-- Name
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T266367750"] = "Name"
|
||||
|
||||
-- No minimum confidence level chosen
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T2828607242"] = "No minimum confidence level chosen"
|
||||
|
||||
-- Minimum provider confidence
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3461070436"] = "Minimum provider confidence"
|
||||
|
||||
-- Configure global settings for each tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3728248397"] = "Configure global settings for each tool."
|
||||
|
||||
-- Tool Settings
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T3730473128"] = "Tool Settings"
|
||||
|
||||
-- Status
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTOOLS::T6222351"] = "Status"
|
||||
|
||||
-- No transcription provider configured yet.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T1079350363"] = "No transcription provider configured yet."
|
||||
|
||||
@ -3066,6 +3126,66 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::THIRDPARTYCOMPONENT::T1392042694"] = "Ope
|
||||
-- License:
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::THIRDPARTYCOMPONENT::T1908172666"] = "License:"
|
||||
|
||||
-- Tool selection is hidden
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T2096103917"] = "Tool selection is hidden"
|
||||
|
||||
-- You have selected 1 tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T2493128368"] = "You have selected 1 tool."
|
||||
|
||||
-- Choose which tools should be preselected for new runs of this assistant.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T2696618758"] = "Choose which tools should be preselected for new runs of this assistant."
|
||||
|
||||
-- Default tools for this assistant
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3253667950"] = "Default tools for this assistant"
|
||||
|
||||
-- Tool selection is visible
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3384582069"] = "Tool selection is visible"
|
||||
|
||||
-- Show tool selection in this assistant?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3494508870"] = "Show tool selection in this assistant?"
|
||||
|
||||
-- You have selected {0} tools.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3729156356"] = "You have selected {0} tools."
|
||||
|
||||
-- No tools selected.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T3934845540"] = "No tools selected."
|
||||
|
||||
-- Default tools for chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T907403808"] = "Default tools for chat"
|
||||
|
||||
-- Choose which tools should be preselected for new chats.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLDEFAULTSCONFIGURATION::T948842182"] = "Choose which tools should be preselected for new chats."
|
||||
|
||||
-- This tool is currently required because Web Search is enabled.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1351725609"] = "This tool is currently required because Web Search is enabled."
|
||||
|
||||
-- Tool changes are locked while a response is running. Your current selection is shown below and applies again from the next message once the run is finished.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1688023907"] = "Tool changes are locked while a response is running. Your current selection is shown below and applies again from the next message once the run is finished."
|
||||
|
||||
-- Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T1944689297"] = "Tools allow the LLM to perform targeted additional actions such as web searches or reading web pages."
|
||||
|
||||
-- Enabling this tool also enables Read Web Page.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3023833839"] = "Enabling this tool also enables Read Web Page."
|
||||
|
||||
-- Required settings are missing. Configure this tool before enabling it.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3119156561"] = "Required settings are missing. Configure this tool before enabling it."
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3448155331"] = "Close"
|
||||
|
||||
-- No tools are available in this context.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T3904490680"] = "No tools are available in this context."
|
||||
|
||||
-- This tool requires provider confidence {0}. The selected provider has {1}.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T4097602620"] = "This tool requires provider confidence {0}. The selected provider has {1}."
|
||||
|
||||
-- Tool Selection
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T749664565"] = "Tool Selection"
|
||||
|
||||
-- Select tools
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TOOLSELECTION::T998515990"] = "Select tools"
|
||||
|
||||
-- You'll interact with the AI systems using your voice. To achieve this, we want to integrate voice input (speech-to-text) and output (text-to-speech). However, later on, it should also have a natural conversation flow, i.e., seamless conversation.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::VISION::T1015366320"] = "You'll interact with the AI systems using your voice. To achieve this, we want to integrate voice input (speech-to-text) and output (text-to-speech). However, later on, it should also have a natural conversation flow, i.e., seamless conversation."
|
||||
|
||||
@ -5667,6 +5787,21 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3547
|
||||
-- Preselect e-mail options?
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832719342"] = "Preselect e-mail options?"
|
||||
|
||||
-- Save
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T1294818664"] = "Save"
|
||||
|
||||
-- Tool Settings
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T3730473128"] = "Tool Settings"
|
||||
|
||||
-- The selected tool could not be loaded.
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T3907843187"] = "The selected tool could not be loaded."
|
||||
|
||||
-- {0} Default: {1}
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T403490413"] = "{0} Default: {1}"
|
||||
|
||||
-- Cancel
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::TOOLSETTINGSDIALOG::T900713019"] = "Cancel"
|
||||
|
||||
-- Save
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SHORTCUTDIALOG::T1294818664"] = "Save"
|
||||
|
||||
@ -6270,11 +6405,12 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2989678330"] = "Copies the root
|
||||
-- Changelog
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3017574265"] = "Changelog"
|
||||
|
||||
-- Vector store
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3046399223"] = "Vector store"
|
||||
-- External HTTPS custom root certificates are configured but not active.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3021325354"] = "External HTTPS custom root certificates are configured but not active."
|
||||
|
||||
-- Vector store
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3046399223"] = "Vector store"
|
||||
|
||||
-- Enterprise configuration ID:
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T3092349641"] = "Enterprise configuration ID:"
|
||||
|
||||
@ -6626,6 +6762,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3014737766"] = "We tried to
|
||||
-- We tried to communicate with the LLM provider '{0}' (type={1}). Even after {2} retries, there were some problems with the request. The provider message is: '{3}'.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3049689432"] = "We tried to communicate with the LLM provider '{0}' (type={1}). Even after {2} retries, there were some problems with the request. The provider message is: '{3}'."
|
||||
|
||||
-- The tool calling request failed with status code {0}. See the logs for details.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3117779001"] = "The tool calling request failed with status code {0}. See the logs for details."
|
||||
|
||||
-- Tried to communicate with the LLM provider '{0}'. There were some problems with the request. The provider message is: '{1}'
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3573577433"] = "Tried to communicate with the LLM provider '{0}'. There were some problems with the request. The provider message is: '{1}'"
|
||||
|
||||
@ -6716,6 +6855,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODELLOADFAILUREREASONEXTENSIONS::T37333904
|
||||
-- We could not load models from '{0}' due to an unknown error.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODELLOADFAILUREREASONEXTENSIONS::T3907712809"] = "We could not load models from '{0}' due to an unknown error."
|
||||
|
||||
-- The tool calling request failed with status code {0}. See the logs for details.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::OPENAI::PROVIDEROPENAI::T3117779001"] = "The tool calling request failed with status code {0}. See the logs for details."
|
||||
|
||||
-- It looks like you do not have any API credits left with OpenAI. Please add credits to your account and try again.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::OPENAI::PROVIDEROPENAI::T757371511"] = "It looks like you do not have any API credits left with OpenAI. Please add credits to your account and try again."
|
||||
|
||||
@ -7856,6 +7998,108 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4174900468"] = "Sources pro
|
||||
-- Sources provided by the AI
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4261248356"] = "Sources provided by the AI"
|
||||
|
||||
-- Tool
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T3517012711"] = "Tool"
|
||||
|
||||
-- Tool description
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T4056470505"] = "Tool description"
|
||||
|
||||
-- Load a single web page and extract its main HTML content.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T204256540"] = "Load a single web page and extract its main HTML content."
|
||||
|
||||
-- Allowed private hosts must be host names only, without scheme or path.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2196457612"] = "Allowed private hosts must be host names only, without scheme or path."
|
||||
|
||||
-- Maximum Content Characters
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2801581200"] = "Maximum Content Characters"
|
||||
|
||||
-- Optional HTTP timeout for loading a web page in seconds.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2941521561"] = "Optional HTTP timeout for loading a web page in seconds."
|
||||
|
||||
-- Allowed private host '{0}' is not valid.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3089707139"] = "Allowed private host '{0}' is not valid."
|
||||
|
||||
-- Allowed Private Hosts
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3415515539"] = "Allowed Private Hosts"
|
||||
|
||||
-- Timeout Seconds
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3567699845"] = "Timeout Seconds"
|
||||
|
||||
-- Read Web Page
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3612587998"] = "Read Web Page"
|
||||
|
||||
-- Optional global truncation limit for extracted characters returned to the model.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T364016543"] = "Optional global truncation limit for extracted characters returned to the model."
|
||||
|
||||
-- The web page was not loaded because private or VPN web pages require a High-confidence provider.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3856267430"] = "The web page was not loaded because private or VPN web pages require a High-confidence provider."
|
||||
|
||||
-- Optional host allowlist for private or VPN web pages. For security reasons, private or VPN web pages aren't allowed to be read by default. Separate host patterns with commas, such as example.de, *.example.de. Allowed private hosts require a high-confidence provider. For allowed internal hosts, AI Studio also tries the operating system's default sign-in automatically when the server responds with integrated authentication.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T854695329"] = "Optional host allowlist for private or VPN web pages. For security reasons, private or VPN web pages aren't allowed to be read by default. Separate host patterns with commas, such as example.de, *.example.de. Allowed private hosts require a high-confidence provider. For allowed internal hosts, AI Studio also tries the operating system's default sign-in automatically when the server responds with integrated authentication."
|
||||
|
||||
-- Maximum Results
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1273024715"] = "Maximum Results"
|
||||
|
||||
-- Optional comma-separated default categories. Do not set this together with default engines.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1342681591"] = "Optional comma-separated default categories. Do not set this together with default engines."
|
||||
|
||||
-- Default Safe Search
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1343180281"] = "Default Safe Search"
|
||||
|
||||
-- Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1739312423"] = "Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint."
|
||||
|
||||
-- A SearXNG URL is required.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1746583720"] = "A SearXNG URL is required."
|
||||
|
||||
-- Default Engines
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1865580137"] = "Default Engines"
|
||||
|
||||
-- Optional fallback language code when the model does not provide a language.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1868101906"] = "Optional fallback language code when the model does not provide a language."
|
||||
|
||||
-- Default Categories
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2053347010"] = "Default Categories"
|
||||
|
||||
-- Default Language
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2526826120"] = "Default Language"
|
||||
|
||||
-- The configured SearXNG URL is not a valid absolute URL.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3038368943"] = "The configured SearXNG URL is not a valid absolute URL."
|
||||
|
||||
-- Optional HTTP timeout for the search request in seconds.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3078115445"] = "Optional HTTP timeout for the search request in seconds."
|
||||
|
||||
-- Timeout Seconds
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3567699845"] = "Timeout Seconds"
|
||||
|
||||
-- Optional default maximum number of results returned to the model when the model does not provide a limit.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3603838271"] = "Optional default maximum number of results returned to the model when the model does not provide a limit."
|
||||
|
||||
-- Web Search
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3815068443"] = "Web Search"
|
||||
|
||||
-- Optional safe search policy sent to SearXNG when configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3967748757"] = "Optional safe search policy sent to SearXNG when configured."
|
||||
|
||||
-- Default categories and default engines cannot both be set for the web search tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Default categories and default engines cannot both be set for the web search tool."
|
||||
|
||||
-- Optional comma-separated default engines. Do not set this together with default categories.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4108908537"] = "Optional comma-separated default engines. Do not set this together with default categories."
|
||||
|
||||
-- The setting '{0}' must be a positive integer.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4199432074"] = "The setting '{0}' must be a positive integer."
|
||||
|
||||
-- Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T764865565"] = "Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions."
|
||||
|
||||
-- The configured SearXNG URL must start with http:// or https://.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T944878454"] = "The configured SearXNG URL must start with http:// or https://."
|
||||
|
||||
-- SearXNG URL
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T993547568"] = "SearXNG URL"
|
||||
|
||||
-- Pandoc Installation
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T185447014"] = "Pandoc Installation"
|
||||
|
||||
|
||||
@ -997,10 +997,33 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
var currentAssistantContent = chatThread.Blocks.LastOrDefault(x => x.Role is ChatRole.AI)?.Content as ContentText;
|
||||
currentAssistantContent?.ToolInvocations.Clear();
|
||||
|
||||
async Task ResetToolRuntimeStatusAsync()
|
||||
{
|
||||
if (currentAssistantContent is null)
|
||||
return;
|
||||
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
async Task ShowToolRuntimeStatusAsync(IEnumerable<string> toolNames)
|
||||
{
|
||||
if (currentAssistantContent is null)
|
||||
return;
|
||||
|
||||
currentAssistantContent.ToolRuntimeStatus = new ToolRuntimeStatus
|
||||
{
|
||||
IsRunning = true,
|
||||
ToolNames = toolNames.ToList(),
|
||||
};
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
TextMessage systemPrompt;
|
||||
if (toolRegistry is not null && toolExecutor is not null)
|
||||
{
|
||||
var runnableTools = await toolRegistry.GetRunnableToolsAsync(
|
||||
this.CreateSettingsProvider(chatModel),
|
||||
chatThread.RuntimeComponent,
|
||||
chatThread.RuntimeSelectedToolIds,
|
||||
this.Provider.GetModelCapabilities(chatModel),
|
||||
@ -1031,14 +1054,13 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
var responseMessage = response?.Choices.FirstOrDefault()?.Message;
|
||||
if (responseMessage is null)
|
||||
{
|
||||
currentAssistantContent!.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
await ResetToolRuntimeStatusAsync();
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (responseMessage.ToolCalls.Count == 0)
|
||||
{
|
||||
currentAssistantContent!.ToolRuntimeStatus = new();
|
||||
await ResetToolRuntimeStatusAsync();
|
||||
if (!string.IsNullOrWhiteSpace(responseMessage.Content))
|
||||
yield return new ContentStreamChunk(responseMessage.Content, []);
|
||||
else if (toolCallCount > 0)
|
||||
@ -1047,14 +1069,8 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
yield break;
|
||||
}
|
||||
|
||||
currentAssistantContent!.ToolRuntimeStatus = new ToolRuntimeStatus
|
||||
{
|
||||
IsRunning = true,
|
||||
ToolNames = responseMessage.ToolCalls
|
||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Function.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Function.Name)
|
||||
.ToList(),
|
||||
};
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
await ShowToolRuntimeStatusAsync(responseMessage.ToolCalls
|
||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Function.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Function.Name));
|
||||
|
||||
internalMessages.Add(new AssistantToolCallMessage
|
||||
{
|
||||
@ -1068,7 +1084,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
if (toolCallCount > ToolSelectionRules.MAX_TOOL_CALLS)
|
||||
{
|
||||
var limitMessage = ToolSelectionRules.GetMaxToolCallsLimitMessage();
|
||||
currentAssistantContent.ToolInvocations.Add(new ToolInvocationTrace
|
||||
currentAssistantContent?.ToolInvocations.Add(new ToolInvocationTrace
|
||||
{
|
||||
Order = toolCallCount,
|
||||
ToolId = toolCall.Function.Name,
|
||||
@ -1078,8 +1094,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
StatusMessage = limitMessage,
|
||||
Result = limitMessage,
|
||||
});
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
await ResetToolRuntimeStatusAsync();
|
||||
yield return new ContentStreamChunk(limitMessage, []);
|
||||
yield break;
|
||||
}
|
||||
@ -1093,7 +1108,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
toolCallCount,
|
||||
token);
|
||||
|
||||
currentAssistantContent.ToolInvocations.Add(trace);
|
||||
currentAssistantContent?.ToolInvocations.Add(trace);
|
||||
internalMessages.Add(new ToolResultMessage
|
||||
{
|
||||
Content = toolContent,
|
||||
@ -1102,7 +1117,8 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
});
|
||||
}
|
||||
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
if (currentAssistantContent is not null)
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,6 +1156,13 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
yield return content;
|
||||
}
|
||||
|
||||
private AIStudio.Settings.Provider CreateSettingsProvider(Model chatModel) => new()
|
||||
{
|
||||
UsedLLMProvider = this.Provider,
|
||||
Model = chatModel,
|
||||
InstanceName = this.InstanceName,
|
||||
};
|
||||
|
||||
private async Task<ChatCompletionResponse?> ExecuteChatCompletionRequest(
|
||||
ChatCompletionAPIRequest requestDto,
|
||||
string requestPath,
|
||||
|
||||
@ -176,6 +176,12 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
IReadOnlyList<(ToolDefinition Definition, IToolImplementation Implementation)> runnableTools = toolRegistry is null
|
||||
? []
|
||||
: await toolRegistry.GetRunnableToolsAsync(
|
||||
new AIStudio.Settings.Provider
|
||||
{
|
||||
UsedLLMProvider = this.Provider,
|
||||
Model = chatModel,
|
||||
InstanceName = this.InstanceName,
|
||||
},
|
||||
chatThread.RuntimeComponent,
|
||||
chatThread.RuntimeSelectedToolIds,
|
||||
modelCapabilities,
|
||||
@ -334,23 +340,14 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
var response = await this.ExecuteResponsesRequest(requestDto, requestedSecret, token);
|
||||
if (response is null)
|
||||
{
|
||||
if (currentAssistantContent is not null)
|
||||
{
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
await ResetToolRuntimeStatusAsync(currentAssistantContent);
|
||||
yield break;
|
||||
}
|
||||
|
||||
var functionCalls = response.GetFunctionCalls();
|
||||
if (functionCalls.Count == 0)
|
||||
{
|
||||
if (currentAssistantContent is not null)
|
||||
{
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
await ResetToolRuntimeStatusAsync(currentAssistantContent);
|
||||
|
||||
var textOutput = response.GetTextOutput();
|
||||
if (!string.IsNullOrWhiteSpace(textOutput))
|
||||
@ -361,17 +358,8 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (currentAssistantContent is not null)
|
||||
{
|
||||
currentAssistantContent.ToolRuntimeStatus = new ToolRuntimeStatus
|
||||
{
|
||||
IsRunning = true,
|
||||
ToolNames = functionCalls
|
||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Name)
|
||||
.ToList(),
|
||||
};
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
await ShowToolRuntimeStatusAsync(currentAssistantContent, functionCalls
|
||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Name));
|
||||
|
||||
foreach (var functionCallItem in response.GetRawFunctionCallItems())
|
||||
internalItems.Add(functionCallItem);
|
||||
@ -393,12 +381,7 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
Result = limitMessage,
|
||||
});
|
||||
|
||||
if (currentAssistantContent is not null)
|
||||
{
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
await ResetToolRuntimeStatusAsync(currentAssistantContent);
|
||||
yield return new ContentStreamChunk(limitMessage, []);
|
||||
yield break;
|
||||
}
|
||||
@ -425,6 +408,28 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ResetToolRuntimeStatusAsync(ContentText? currentAssistantContent)
|
||||
{
|
||||
if (currentAssistantContent is null)
|
||||
return;
|
||||
|
||||
currentAssistantContent.ToolRuntimeStatus = new();
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
private static async Task ShowToolRuntimeStatusAsync(ContentText? currentAssistantContent, IEnumerable<string> toolNames)
|
||||
{
|
||||
if (currentAssistantContent is null)
|
||||
return;
|
||||
|
||||
currentAssistantContent.ToolRuntimeStatus = new ToolRuntimeStatus
|
||||
{
|
||||
IsRunning = true,
|
||||
ToolNames = toolNames.ToList(),
|
||||
};
|
||||
await currentAssistantContent.StreamingEvent();
|
||||
}
|
||||
|
||||
private async Task<ResponsesResponse?> ExecuteResponsesRequest(ResponsesAPIRequest requestDto, RequestedSecret requestedSecret, CancellationToken token)
|
||||
{
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, "responses");
|
||||
|
||||
@ -766,7 +766,7 @@ public static partial class ManagedConfiguration
|
||||
return false;
|
||||
|
||||
var successful = false;
|
||||
var configuredValue = configMeta.Default;
|
||||
var configuredValue = CloneStringDictionary(configMeta.Default);
|
||||
|
||||
// Step 1 -- try to read the Lua value (we expect a table) out of the Lua table:
|
||||
if (settings.TryGetValue(SettingsManager.ToSettingName(propertyExpression), out var configuredLuaList) &&
|
||||
@ -803,7 +803,9 @@ public static partial class ManagedConfiguration
|
||||
if(dryRun)
|
||||
return successful;
|
||||
|
||||
return HandleParsedValue(configPluginId, dryRun, successful, configMeta, configuredValue);
|
||||
var settingName = SettingName(propertyExpression);
|
||||
var managedMode = ReadManagedConfigurationMode(propertyExpression, settings);
|
||||
return HandleParsedDictionaryValue(configPluginId, dryRun, successful, configMeta, configuredValue, managedMode, settingName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -925,6 +927,67 @@ public static partial class ManagedConfiguration
|
||||
return successful;
|
||||
}
|
||||
|
||||
private static bool HandleParsedDictionaryValue<TClass>(
|
||||
Guid configPluginId,
|
||||
bool dryRun,
|
||||
bool successful,
|
||||
ConfigMeta<TClass, IDictionary<string, string>> configMeta,
|
||||
IDictionary<string, string> configuredValue,
|
||||
ManagedConfigurationMode managedMode,
|
||||
string settingName)
|
||||
{
|
||||
if (dryRun)
|
||||
return successful;
|
||||
|
||||
switch (successful)
|
||||
{
|
||||
case true when managedMode is ManagedConfigurationMode.LOCKED:
|
||||
ClearEditableDefaultState(settingName);
|
||||
configMeta.ClearEditableDefaultConfiguration();
|
||||
configMeta.SetValue(CloneStringDictionary(configuredValue));
|
||||
configMeta.LockConfiguration(configPluginId);
|
||||
break;
|
||||
|
||||
case true when managedMode is ManagedConfigurationMode.EDITABLE_DEFAULT:
|
||||
var currentValueSerialized = SerializeManagedStringDictionaryValue(configMeta.GetValue());
|
||||
var configuredValueSerialized = SerializeManagedStringDictionaryValue(configuredValue);
|
||||
|
||||
string lastAppliedValue;
|
||||
if (!TryGetEditableDefaultState(settingName, out var editableDefaultState))
|
||||
{
|
||||
configMeta.SetValue(CloneStringDictionary(configuredValue));
|
||||
lastAppliedValue = configuredValueSerialized;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastAppliedValue = editableDefaultState.LastAppliedValue;
|
||||
if (string.Equals(currentValueSerialized, lastAppliedValue, StringComparison.Ordinal))
|
||||
{
|
||||
configMeta.SetValue(CloneStringDictionary(configuredValue));
|
||||
lastAppliedValue = configuredValueSerialized;
|
||||
}
|
||||
}
|
||||
|
||||
SetEditableDefaultState(settingName, configPluginId, lastAppliedValue);
|
||||
configMeta.UnlockConfiguration();
|
||||
configMeta.SetEditableDefaultConfiguration(configPluginId);
|
||||
break;
|
||||
|
||||
case false when configMeta.IsLocked && configMeta.LockedByConfigPluginId == configPluginId:
|
||||
configMeta.ResetLockedConfiguration();
|
||||
break;
|
||||
|
||||
case false when configMeta.ManagedMode is ManagedConfigurationMode.EDITABLE_DEFAULT
|
||||
&& TryGetEditableDefaultState(settingName, out var editableDefaultStateToRemove)
|
||||
&& editableDefaultStateToRemove.ConfigPluginId == configPluginId:
|
||||
configMeta.ClearEditableDefaultConfiguration();
|
||||
ClearEditableDefaultState(settingName);
|
||||
break;
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
private static ManagedConfigurationMode ReadManagedConfigurationMode<TClass, TValue>(
|
||||
Expression<Func<TClass, TValue>> propertyExpression,
|
||||
LuaTable settings)
|
||||
@ -950,4 +1013,12 @@ public static partial class ManagedConfiguration
|
||||
|
||||
_ => value.ToString() ?? string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> CloneStringDictionary(IDictionary<string, string> values) => new(values, StringComparer.Ordinal);
|
||||
|
||||
private static string SerializeManagedStringDictionaryValue(IDictionary<string, string> values) => string.Join(
|
||||
"\n",
|
||||
values
|
||||
.OrderBy(pair => pair.Key, StringComparer.Ordinal)
|
||||
.Select(pair => $"{pair.Key}={pair.Value}"));
|
||||
}
|
||||
|
||||
@ -387,17 +387,17 @@ public static partial class ManagedConfiguration
|
||||
if (!TryGet(configSelection, propertyExpression, out var configMeta))
|
||||
return false;
|
||||
|
||||
if (configMeta.LockedByConfigPluginId == Guid.Empty || !configMeta.IsLocked)
|
||||
return false;
|
||||
|
||||
var plugin = availablePlugins.FirstOrDefault(x => x.Id == configMeta.LockedByConfigPluginId);
|
||||
if (plugin is null)
|
||||
if (configMeta.LockedByConfigPluginId != Guid.Empty && configMeta.IsLocked)
|
||||
{
|
||||
configMeta.ResetLockedConfiguration();
|
||||
return true;
|
||||
var plugin = availablePlugins.FirstOrDefault(x => x.Id == configMeta.LockedByConfigPluginId);
|
||||
if (plugin is null)
|
||||
{
|
||||
configMeta.ResetLockedConfiguration();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return CleanupEditableDefaultState(configMeta, SettingName(propertyExpression), [..availablePlugins]);
|
||||
}
|
||||
|
||||
private static string Path<TClass, TValue>(Expression<Func<Data, TClass>> configSelection, Expression<Func<TClass, TValue>> propertyExpression)
|
||||
@ -453,4 +453,4 @@ public static partial class ManagedConfiguration
|
||||
configMeta.ClearEditableDefaultConfiguration();
|
||||
return ClearEditableDefaultState(settingName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@ namespace AIStudio.Settings;
|
||||
/// </summary>
|
||||
public sealed class SettingsManager
|
||||
{
|
||||
public readonly record struct ToolMinimumProviderConfidenceResolution(ConfidenceLevel ConfidenceLevel, string Source);
|
||||
|
||||
private const string SETTINGS_FILENAME = "settings.json";
|
||||
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
||||
@ -392,6 +394,46 @@ public sealed class SettingsManager
|
||||
return [];
|
||||
}
|
||||
|
||||
public HashSet<string> FilterToolIdsForProvider(AIStudio.Settings.Provider provider, IEnumerable<string> selectedToolIds)
|
||||
{
|
||||
var toolCallingAvailability = provider.GetToolCallingAvailability();
|
||||
if (!toolCallingAvailability.IsAvailable)
|
||||
return [];
|
||||
|
||||
var modelCapabilities = provider.GetModelCapabilities();
|
||||
var supportsRequiredApis =
|
||||
modelCapabilities.Contains(Capability.CHAT_COMPLETION_API) ||
|
||||
modelCapabilities.Contains(Capability.RESPONSES_API);
|
||||
if (!supportsRequiredApis || !modelCapabilities.Contains(Capability.FUNCTION_CALLING))
|
||||
return [];
|
||||
|
||||
var providerConfidence = provider.UsedLLMProvider.GetConfidence(this).Level;
|
||||
var filtered = ToolSelectionRules.NormalizeSelection(selectedToolIds);
|
||||
|
||||
var changed = true;
|
||||
while (changed)
|
||||
{
|
||||
changed = false;
|
||||
foreach (var toolId in filtered.ToList())
|
||||
{
|
||||
var minimumToolConfidence = this.GetMinimumProviderConfidenceForTool(toolId);
|
||||
if (ToolSelectionRules.IsProviderConfidenceAllowed(providerConfidence, minimumToolConfidence))
|
||||
continue;
|
||||
|
||||
filtered.Remove(toolId);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (filtered.Contains(ToolSelectionRules.WEB_SEARCH_TOOL_ID) && !filtered.Contains(ToolSelectionRules.READ_WEB_PAGE_TOOL_ID))
|
||||
{
|
||||
filtered.Remove(ToolSelectionRules.WEB_SEARCH_TOOL_ID);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public bool IsToolSelectionVisible(AIStudio.Tools.Components component) => component switch
|
||||
{
|
||||
AIStudio.Tools.Components.CHAT => true,
|
||||
@ -410,18 +452,31 @@ public sealed class SettingsManager
|
||||
this.ConfigurationData.Tools.VisibleToolSelectionComponents.Remove(key);
|
||||
}
|
||||
|
||||
public ConfidenceLevel GetMinimumProviderConfidenceForTool(string toolId)
|
||||
public ToolMinimumProviderConfidenceResolution GetMinimumProviderConfidenceResolutionForTool(string toolId)
|
||||
{
|
||||
if (ManagedConfiguration.TryGet(x => x.Tools, x => x.MinimumProviderConfidenceByToolId, out var configMeta) && configMeta.IsLocked)
|
||||
{
|
||||
var managedValues = configMeta.GetValue();
|
||||
if (managedValues.TryGetValue(toolId, out var configuredManagedLevel) &&
|
||||
Enum.TryParse<ConfidenceLevel>(configuredManagedLevel, true, out var managedConfidenceLevel) &&
|
||||
managedConfidenceLevel is not ConfidenceLevel.UNKNOWN)
|
||||
{
|
||||
return new(managedConfidenceLevel, "managed config");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.ConfigurationData.Tools.MinimumProviderConfidenceByToolId.TryGetValue(toolId, out var configuredLevel) &&
|
||||
Enum.TryParse<ConfidenceLevel>(configuredLevel, true, out var confidenceLevel) &&
|
||||
confidenceLevel is not ConfidenceLevel.UNKNOWN)
|
||||
{
|
||||
return confidenceLevel;
|
||||
return new(confidenceLevel, "stored override");
|
||||
}
|
||||
|
||||
return ToolSelectionRules.GetDefaultMinimumProviderConfidence(toolId);
|
||||
return new(ToolSelectionRules.GetDefaultMinimumProviderConfidence(toolId), "default fallback");
|
||||
}
|
||||
|
||||
public ConfidenceLevel GetMinimumProviderConfidenceForTool(string toolId) => this.GetMinimumProviderConfidenceResolutionForTool(toolId).ConfidenceLevel;
|
||||
|
||||
public void SetMinimumProviderConfidenceForTool(string toolId, ConfidenceLevel confidenceLevel)
|
||||
{
|
||||
var defaultLevel = ToolSelectionRules.GetDefaultMinimumProviderConfidence(toolId);
|
||||
|
||||
@ -46,6 +46,16 @@ public static class ExternalHttpClientTimeout
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public static void ConfigureSocketsHttpHandler(SocketsHttpHandler handler, string host, ExternalHttpTrustPolicy trustPolicy)
|
||||
{
|
||||
var customRootCertificateCache = GetCustomRootCertificateCache();
|
||||
if (!customRootCertificateCache.State.IsUsable)
|
||||
return;
|
||||
|
||||
handler.SslOptions.RemoteCertificateValidationCallback = (_, certificate, chain, sslPolicyErrors) =>
|
||||
ValidateServerCertificateWithCustomRootCertificates(host, certificate, chain, sslPolicyErrors, customRootCertificateCache, trustPolicy);
|
||||
}
|
||||
|
||||
public static ExternalHttpCustomRootCertificateState CustomRootCertificateState => GetCustomRootCertificateCache().State;
|
||||
|
||||
public static string GetTimeoutDescription()
|
||||
@ -336,6 +346,23 @@ public static class ExternalHttpClientTimeout
|
||||
SslPolicyErrors sslPolicyErrors,
|
||||
CustomRootCertificateCache customRootCertificateCache,
|
||||
ExternalHttpTrustPolicy trustPolicy)
|
||||
{
|
||||
return ValidateServerCertificateWithCustomRootCertificates(
|
||||
ReadRequestHost(request),
|
||||
certificate,
|
||||
originalChain,
|
||||
sslPolicyErrors,
|
||||
customRootCertificateCache,
|
||||
trustPolicy);
|
||||
}
|
||||
|
||||
private static bool ValidateServerCertificateWithCustomRootCertificates(
|
||||
string host,
|
||||
X509Certificate? certificate,
|
||||
X509Chain? originalChain,
|
||||
SslPolicyErrors sslPolicyErrors,
|
||||
CustomRootCertificateCache customRootCertificateCache,
|
||||
ExternalHttpTrustPolicy trustPolicy)
|
||||
{
|
||||
if (sslPolicyErrors is SslPolicyErrors.None)
|
||||
return true;
|
||||
@ -343,7 +370,6 @@ public static class ExternalHttpClientTimeout
|
||||
if (sslPolicyErrors is not SslPolicyErrors.RemoteCertificateChainErrors || certificate is null)
|
||||
return false;
|
||||
|
||||
var host = ReadRequestHost(request);
|
||||
if (trustPolicy is ExternalHttpTrustPolicy.SYSTEM_TRUST_ONLY)
|
||||
{
|
||||
LOGGER.Value.LogError($"Rejected external HTTPS certificate for '{HostForLog(host)}' because this request requires system trust only. Configured custom root certificates are not allowed for this request.");
|
||||
@ -378,7 +404,7 @@ public static class ExternalHttpClientTimeout
|
||||
|
||||
var isValid = customChain.Build(serverCertificate);
|
||||
if (isValid)
|
||||
LogCustomRootCertificateAccepted(request);
|
||||
LogCustomRootCertificateAccepted(host);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
@ -436,10 +462,11 @@ public static class ExternalHttpClientTimeout
|
||||
|
||||
private static void LogCustomRootCertificateAccepted(HttpRequestMessage request)
|
||||
{
|
||||
var host = ReadRequestHost(request);
|
||||
LOGGER.Value.LogWarning($"Accepted an external HTTPS certificate for '{host}' using configured custom root certificates.");
|
||||
LogCustomRootCertificateAccepted(ReadRequestHost(request));
|
||||
}
|
||||
|
||||
private static void LogCustomRootCertificateAccepted(string host) => LOGGER.Value.LogWarning($"Accepted an external HTTPS certificate for '{host}' using configured custom root certificates.");
|
||||
|
||||
private static string ReadRequestHost(HttpRequestMessage request)
|
||||
{
|
||||
var host = request.RequestUri?.IdnHost;
|
||||
@ -465,4 +492,4 @@ public static class ExternalHttpClientTimeout
|
||||
string CacheKey,
|
||||
X509Certificate2Collection Certificates,
|
||||
ExternalHttpCustomRootCertificateState State);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,34 +50,22 @@ public sealed class HTMLParser
|
||||
int timeoutSeconds = 30,
|
||||
Func<Uri, CancellationToken, Task<IReadOnlyList<IPAddress>>>? resolveUrlAddressesAsync = null,
|
||||
int maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES,
|
||||
ExternalWebAuthenticationMode authenticationMode = ExternalWebAuthenticationMode.NONE)
|
||||
ExternalWebAuthenticationMode authenticationMode = ExternalWebAuthenticationMode.NONE,
|
||||
ExternalHttpTrustPolicy trustPolicy = ExternalHttpTrustPolicy.ALLOW_CUSTOM_ROOTS_WHEN_HOST_WHITELISTED)
|
||||
{
|
||||
using var handler = new SocketsHttpHandler
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli,
|
||||
AllowAutoRedirect = false,
|
||||
};
|
||||
if (authenticationMode is ExternalWebAuthenticationMode.OS_DEFAULT_CREDENTIALS)
|
||||
handler.Credentials = CreateDefaultCredentialCache(url);
|
||||
|
||||
if (resolveUrlAddressesAsync is not null)
|
||||
{
|
||||
// The callback binds the request to a vetted target IP; a proxy would change the endpoint being connected to.
|
||||
handler.UseProxy = false;
|
||||
handler.ConnectCallback = async (context, connectionToken) => await ConnectToResolvedAddressAsync(context, resolveUrlAddressesAsync, connectionToken);
|
||||
}
|
||||
|
||||
using var httpClient = new HttpClient(handler)
|
||||
{
|
||||
Timeout = Timeout.InfiniteTimeSpan,
|
||||
};
|
||||
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(token);
|
||||
timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
var cookieContainer = new CookieContainer();
|
||||
|
||||
var currentUrl = url;
|
||||
for (var redirectCount = 0; redirectCount <= MAX_REDIRECTS; redirectCount++)
|
||||
{
|
||||
ValidateHttpOrHttpsUrl(currentUrl);
|
||||
using var handler = CreateHandler(currentUrl, resolveUrlAddressesAsync, authenticationMode, trustPolicy, cookieContainer);
|
||||
using var httpClient = new HttpClient(handler)
|
||||
{
|
||||
Timeout = Timeout.InfiniteTimeSpan,
|
||||
};
|
||||
|
||||
using var request = CreateRequest(currentUrl);
|
||||
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token);
|
||||
@ -116,6 +104,35 @@ public sealed class HTMLParser
|
||||
throw new HttpRequestException($"The server returned more than {MAX_REDIRECTS} redirects for '{url}'.");
|
||||
}
|
||||
|
||||
private static SocketsHttpHandler CreateHandler(
|
||||
Uri url,
|
||||
Func<Uri, CancellationToken, Task<IReadOnlyList<IPAddress>>>? resolveUrlAddressesAsync,
|
||||
ExternalWebAuthenticationMode authenticationMode,
|
||||
ExternalHttpTrustPolicy trustPolicy,
|
||||
CookieContainer cookieContainer)
|
||||
{
|
||||
var handler = new SocketsHttpHandler
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli,
|
||||
AllowAutoRedirect = false,
|
||||
UseCookies = true,
|
||||
CookieContainer = cookieContainer,
|
||||
};
|
||||
ExternalHttpClientTimeout.ConfigureSocketsHttpHandler(handler, url.Host, trustPolicy);
|
||||
|
||||
if (authenticationMode is ExternalWebAuthenticationMode.OS_DEFAULT_CREDENTIALS)
|
||||
handler.Credentials = CreateDefaultCredentialCache(url);
|
||||
|
||||
if (resolveUrlAddressesAsync is not null)
|
||||
{
|
||||
// The callback binds the request to a vetted target IP; a proxy would change the endpoint being connected to.
|
||||
handler.UseProxy = false;
|
||||
handler.ConnectCallback = async (context, connectionToken) => await ConnectToResolvedAddressAsync(context, resolveUrlAddressesAsync, connectionToken);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
private static CredentialCache CreateDefaultCredentialCache(Uri url)
|
||||
{
|
||||
var credentialCache = new CredentialCache();
|
||||
|
||||
@ -56,7 +56,7 @@ public sealed class ReadWebPageTool(HTMLParser htmlParser, ILogger<ReadWebPageTo
|
||||
public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch
|
||||
{
|
||||
"timeoutSeconds" => TB("Optional HTTP timeout for loading a web page in seconds."),
|
||||
"maxContentCharacters" => TB("Optional global truncation limit for extracted Markdown returned to the model."),
|
||||
"maxContentCharacters" => TB("Optional global truncation limit for extracted characters returned to the model."),
|
||||
ALLOWED_PRIVATE_HOSTS_SETTING => TB("Optional host allowlist for private or VPN web pages. For security reasons, private or VPN web pages aren't allowed to be read by default. Separate host patterns with commas, such as example.de, *.example.de. Allowed private hosts require a high-confidence provider. For allowed internal hosts, AI Studio also tries the operating system's default sign-in automatically when the server responds with integrated authentication."),
|
||||
_ => TB(fieldDefinition.Description),
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using AIStudio.Tools;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
|
||||
namespace AIStudio.Tools.ToolCallingSystem.ToolCallingImplementations;
|
||||
@ -167,16 +168,14 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
if (!string.IsNullOrWhiteSpace(safeSearch))
|
||||
queryParameters.Add(new KeyValuePair<string, string>("safesearch", safeSearch));
|
||||
|
||||
using var httpClient = new HttpClient
|
||||
{
|
||||
Timeout = Timeout.InfiniteTimeSpan,
|
||||
};
|
||||
using var httpClient = ExternalHttpClientTimeout.CreateHttpClient(searchUri, ExternalHttpTrustPolicy.ALLOW_CUSTOM_ROOTS_WHEN_HOST_WHITELISTED);
|
||||
httpClient.Timeout = Timeout.InfiniteTimeSpan;
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, BuildRequestUri(searchUri, queryParameters));
|
||||
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(token);
|
||||
timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
|
||||
using var response = await SendAsync(httpClient, request, timeoutCts.Token, timeoutSeconds, token);
|
||||
var responseBody = await ReadContentAsStringWithLimitAsync(response.Content, MAX_RESPONSE_BYTES, token);
|
||||
var responseBody = await ReadContentAsStringWithLimitAsync(response.Content, MAX_RESPONSE_BYTES, timeoutCts.Token);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseDetails = string.IsNullOrWhiteSpace(responseBody) ? string.Empty : $" Response body: {responseBody[..Math.Min(responseBody.Length, 400)]}";
|
||||
|
||||
@ -23,7 +23,7 @@ public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogge
|
||||
try
|
||||
{
|
||||
using var document = JsonDocument.Parse(string.IsNullOrWhiteSpace(argumentsJson) ? "{}" : argumentsJson);
|
||||
formattedArguments = FormatArguments(document.RootElement, runnableTool.Implementation?.SensitiveTraceArgumentNames ?? EmptySensitiveTraceArgumentNames.INSTANCE);
|
||||
formattedArguments = FormatArguments(document.RootElement, runnableTool.Implementation?.SensitiveTraceArgumentNames ?? EmptySensitiveTraceArgumentNames.INSTANCE);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@ -113,6 +113,7 @@ public sealed class ToolRegistry
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<(ToolDefinition Definition, IToolImplementation Implementation)>> GetRunnableToolsAsync(
|
||||
AIStudio.Settings.Provider provider,
|
||||
AIStudio.Tools.Components component,
|
||||
IEnumerable<string> selectedToolIds,
|
||||
IReadOnlyCollection<Capability> modelCapabilities,
|
||||
@ -120,31 +121,61 @@ public sealed class ToolRegistry
|
||||
bool isToolSelectionVisible)
|
||||
{
|
||||
if (!isToolSelectionVisible)
|
||||
{
|
||||
this.logger.LogInformation("Tool calling is skipped for component '{Component}' because tool selection is not visible.", component);
|
||||
return [];
|
||||
}
|
||||
|
||||
var toolCallingAvailability = provider.GetToolCallingAvailability();
|
||||
if (!toolCallingAvailability.IsAvailable)
|
||||
{
|
||||
this.logger.LogInformation("Tool calling is unavailable for provider '{Provider}' with model '{ModelId}': {Reason}", provider.InstanceName, provider.Model.Id, toolCallingAvailability.Message);
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!modelCapabilities.Contains(Capability.FUNCTION_CALLING) ||
|
||||
(!modelCapabilities.Contains(Capability.CHAT_COMPLETION_API) && !modelCapabilities.Contains(Capability.RESPONSES_API)))
|
||||
{
|
||||
this.logger.LogInformation("Tool calling is unavailable for provider '{Provider}' with model '{ModelId}' because the model lacks the required API or function-calling capability.", provider.InstanceName, provider.Model.Id);
|
||||
return [];
|
||||
}
|
||||
|
||||
var selectedToolIdSet = ToolSelectionRules.NormalizeSelection(selectedToolIds);
|
||||
this.logger.LogInformation("Resolving runnable tools for provider '{Provider}' with model '{ModelId}'. Selected tool IDs: [{ToolIds}].", provider.InstanceName, provider.Model.Id, string.Join(", ", selectedToolIdSet.OrderBy(x => x, StringComparer.Ordinal)));
|
||||
|
||||
var definitions = this.GetDefinitionsForComponent(component).Where(x => selectedToolIdSet.Contains(x.Id)).ToList();
|
||||
var result = new List<(ToolDefinition, IToolImplementation)>(definitions.Count);
|
||||
foreach (var definition in definitions)
|
||||
{
|
||||
if (!this.implementationsByKey.TryGetValue(definition.ImplementationKey, out var implementation))
|
||||
{
|
||||
this.logger.LogInformation("Skipping tool '{ToolId}' because no implementation is registered.", definition.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
var configurationState = await this.toolSettingsService.GetConfigurationStateAsync(definition, implementation);
|
||||
if (!configurationState.IsConfigured)
|
||||
{
|
||||
this.logger.LogInformation("Skipping tool '{ToolId}' because it is not configured.", definition.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
var resolution = this.settingsManager.GetMinimumProviderConfidenceResolutionForTool(definition.Id);
|
||||
var minimumToolConfidence = resolution.ConfidenceLevel;
|
||||
this.logger.LogInformation("Tool '{ToolId}' uses minimum provider confidence '{ConfidenceLevel}' from {Source}.", definition.Id, minimumToolConfidence, resolution.Source);
|
||||
|
||||
var minimumToolConfidence = this.settingsManager.GetMinimumProviderConfidenceForTool(definition.Id);
|
||||
if (!ToolSelectionRules.IsProviderConfidenceAllowed(providerConfidence, minimumToolConfidence))
|
||||
{
|
||||
this.logger.LogInformation("Skipping tool '{ToolId}' because provider confidence '{ProviderConfidence}' is below the required minimum '{MinimumConfidence}'.", definition.Id, providerConfidence, minimumToolConfidence);
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add((definition, implementation));
|
||||
}
|
||||
|
||||
foreach (var selectedToolId in selectedToolIdSet.Where(selectedToolId => definitions.All(definition => !definition.Id.Equals(selectedToolId, StringComparison.Ordinal))))
|
||||
this.logger.LogInformation("Skipping tool '{ToolId}' because it is not selected in this component or not available in this context.", selectedToolId);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public static class ToolSelectionRules
|
||||
|
||||
return $"""
|
||||
Tool usage policy:
|
||||
{policyLines}
|
||||
{string.Join(Environment.NewLine + Environment.NewLine, policyLines)}
|
||||
""";
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user