mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-24 20:52:11 +00:00
Add assistant plugin deletion with eligibility checks
This commit is contained in:
parent
cba505a632
commit
521b495fa9
@ -2389,6 +2389,24 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T3571008422"] = "Assistan
|
|||||||
-- The result is ready.
|
-- The result is ready.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "The result is ready."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "The result is ready."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1318944584"] = "The assistant cannot be deleted while background work is still running."
|
||||||
|
|
||||||
|
-- Delete assistant plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1692493145"] = "Delete assistant plugin"
|
||||||
|
|
||||||
|
-- Delete Assistant Plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3637071001"] = "Delete Assistant Plugin"
|
||||||
|
|
||||||
|
-- The '{0}' assistant plugin has been successfully removed.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3815023384"] = "The '{0}' assistant plugin has been successfully removed."
|
||||||
|
|
||||||
|
-- The assistant plugin '{0}' could not be deleted: {1}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3985264168"] = "The assistant plugin '{0}' could not be deleted: {1}"
|
||||||
|
|
||||||
|
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T4033722845"] = "Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."
|
||||||
|
|
||||||
-- Show or hide the detailed security information.
|
-- Show or hide the detailed security information.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Show or hide the detailed security information."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Show or hide the detailed security information."
|
||||||
|
|
||||||
@ -7282,9 +7300,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1506922856"] = "Assistant Audit"
|
|||||||
-- Internal Plugins
|
-- Internal Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Internal Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Internal Plugins"
|
||||||
|
|
||||||
-- Delete assistant plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1692493145"] = "Delete assistant plugin"
|
|
||||||
|
|
||||||
-- Disabled Plugins
|
-- Disabled Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Disabled Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Disabled Plugins"
|
||||||
|
|
||||||
@ -7318,24 +7333,12 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3143506997"] = "The assistant plugin
|
|||||||
-- Close
|
-- Close
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Close"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Close"
|
||||||
|
|
||||||
-- Delete Assistant Plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3637071001"] = "Delete Assistant Plugin"
|
|
||||||
|
|
||||||
-- Revise assistant plugin with AI
|
-- Revise assistant plugin with AI
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Revise assistant plugin with AI"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Revise assistant plugin with AI"
|
||||||
|
|
||||||
-- The '{0}' assistant plugin has been successfully removed.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3815023384"] = "The '{0}' assistant plugin has been successfully removed."
|
|
||||||
|
|
||||||
-- Actions
|
-- Actions
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Actions"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Actions"
|
||||||
|
|
||||||
-- The assistant plugin '{0}' could not be deleted: {1}
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3985264168"] = "The assistant plugin '{0}' could not be deleted: {1}"
|
|
||||||
|
|
||||||
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4033722845"] = "Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."
|
|
||||||
|
|
||||||
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "The automatic security audit for the assistant plugin '{0}' failed. Please run it manually."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "The automatic security audit for the assistant plugin '{0}' failed. Please run it manually."
|
||||||
|
|
||||||
@ -8857,6 +8860,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1211
|
|||||||
-- Only assistant plugins can be edited.
|
-- Only assistant plugins can be edited.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Only assistant plugins can be edited."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Only assistant plugins can be edited."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1318944584"] = "The assistant cannot be deleted while background work is still running."
|
||||||
|
|
||||||
-- No Lua plugin code was generated.
|
-- No Lua plugin code was generated.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "No Lua plugin code was generated."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "No Lua plugin code was generated."
|
||||||
|
|
||||||
@ -8887,6 +8893,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T2955
|
|||||||
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "The generated assistant plugin uses the ID of an internal AI Studio plugin."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "The generated assistant plugin uses the ID of an internal AI Studio plugin."
|
||||||
|
|
||||||
|
-- Config Server managed assistant plugins cannot be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3751820312"] = "Config Server managed assistant plugins cannot be deleted."
|
||||||
|
|
||||||
|
-- Only assistants generated by the Assistant Builder can be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3940247198"] = "Only assistants generated by the Assistant Builder can be deleted."
|
||||||
|
|
||||||
-- The edited plugin is not an assistant plugin. Issue: {0}
|
-- The edited plugin is not an assistant plugin. Issue: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "The edited plugin is not an assistant plugin. Issue: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "The edited plugin is not an assistant plugin. Issue: {0}"
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,7 @@
|
|||||||
{
|
{
|
||||||
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
|
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
|
||||||
}
|
}
|
||||||
|
@this.AdditionalActions
|
||||||
</MudButtonGroup>
|
</MudButtonGroup>
|
||||||
@if (this.SecurityBadge is not null)
|
@if (this.SecurityBadge is not null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -43,6 +43,9 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment? SecurityBadge { get; set; }
|
public RenderFragment? SecurityBadge { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment? AdditionalActions { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Tools.Components Component { get; set; } = Tools.Components.NONE;
|
public Tools.Components Component { get; set; } = Tools.Components.NONE;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
|
@if (this.CanDelete)
|
||||||
|
{
|
||||||
|
<MudTooltip Text="@this.Tooltip">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.DeleteOutline"
|
||||||
|
Color="Color.Error"
|
||||||
|
Variant="Variant.Text"
|
||||||
|
Size="Size.Medium"
|
||||||
|
Disabled="@this.IsBlockedByActiveWork"
|
||||||
|
OnClick="@this.DeleteAssistantPluginAsync" />
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
using AIStudio.Dialogs;
|
||||||
|
using AIStudio.Tools.Media;
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
using AIStudio.Tools.Services;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public partial class AssistantPluginDeleteAction : MSGComponentBase
|
||||||
|
{
|
||||||
|
[Parameter, EditorRequired]
|
||||||
|
public IAvailablePlugin Plugin { get; set; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private IDialogService DialogService { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private AssistantPluginInstallService AssistantPluginInstallService { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private MediaTranscriptionService MediaTranscriptionService { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private ILogger<AssistantPluginDeleteAction> Logger { get; init; } = null!;
|
||||||
|
|
||||||
|
private bool CanDelete => AssistantPluginInstallService.CanDeleteInstalledAssistant(this.Plugin);
|
||||||
|
|
||||||
|
private bool IsBlockedByActiveWork => this.AssistantPluginInstallService.HasActiveAssistantWork(this.Plugin.Id);
|
||||||
|
|
||||||
|
private string Tooltip => this.IsBlockedByActiveWork
|
||||||
|
? this.T("The assistant cannot be deleted while background work is still running.")
|
||||||
|
: this.T("Delete assistant plugin");
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
this.ApplyFilters([], [ Event.ASSISTANT_SESSION_CHANGED, Event.ASSISTANT_SESSION_FINISHED ]);
|
||||||
|
this.MediaTranscriptionService.StateChanged += this.OnMediaTranscriptionStateChanged;
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteAssistantPluginAsync()
|
||||||
|
{
|
||||||
|
if (!this.CanDelete || this.IsBlockedByActiveWork)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
x => x.Message,
|
||||||
|
string.Format(this.T("Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."), this.Plugin.Name)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(this.T("Delete Assistant Plugin"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var result = await this.AssistantPluginInstallService.DeleteInstalledAssistantAsync(this.Plugin, CancellationToken.None);
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
this.Logger.LogError("Failed to delete assistant plugin '{PluginName}' ({PluginId}) from '{PluginDirectory}' with issue '{Issue}'.", result.PluginName, result.PluginId, result.PluginDirectory, result.Issue);
|
||||||
|
await this.MessageBus.SendError(new(Icons.Material.Filled.DeleteForever, string.Format(this.T("The assistant plugin '{0}' could not be deleted: {1}"), this.Plugin.Name, result.Issue)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Check, string.Format(this.T("The '{0}' assistant plugin has been successfully removed."), result.PluginName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMediaTranscriptionStateChanged(MediaImportOwner owner)
|
||||||
|
{
|
||||||
|
if (owner.Kind is MediaImportOwnerKind.ASSISTANT && owner.Id.EndsWith($":{this.Plugin.Id}", StringComparison.Ordinal))
|
||||||
|
_ = this.InvokeAsync(this.StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||||
|
{
|
||||||
|
if (triggeredEvent is Event.ASSISTANT_SESSION_CHANGED or Event.ASSISTANT_SESSION_FINISHED)
|
||||||
|
this.StateHasChanged();
|
||||||
|
|
||||||
|
return base.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DisposeResources()
|
||||||
|
{
|
||||||
|
this.MediaTranscriptionService.StateChanged -= this.OnMediaTranscriptionStateChanged;
|
||||||
|
base.DisposeResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
@attribute [Route(Routes.ASSISTANTS)]
|
@attribute [Route(Routes.ASSISTANTS)]
|
||||||
@using AIStudio.Dialogs.Settings
|
@using AIStudio.Dialogs.Settings
|
||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Tools.PluginSystem
|
||||||
@using AIStudio.Tools.PluginSystem.Assistants
|
@using AIStudio.Tools.PluginSystem.Assistants
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
@ -45,6 +46,7 @@
|
|||||||
{
|
{
|
||||||
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
||||||
var launchLink = assistantPlugin.StartsChatDirectly ? string.Empty : $"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}";
|
var launchLink = assistantPlugin.StartsChatDirectly ? string.Empty : $"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}";
|
||||||
|
var availablePlugin = PluginFactory.AvailablePlugins.OfType<IAvailablePlugin>().FirstOrDefault(plugin => plugin.Id == assistantPlugin.Id);
|
||||||
<AssistantBlock TSettings="NoSettingsPanel"
|
<AssistantBlock TSettings="NoSettingsPanel"
|
||||||
Name="@T(assistantPlugin.AssistantTitle)"
|
Name="@T(assistantPlugin.AssistantTitle)"
|
||||||
Description="@T(assistantPlugin.Description)"
|
Description="@T(assistantPlugin.Description)"
|
||||||
@ -53,6 +55,12 @@
|
|||||||
AssistantSessionInstanceId="@assistantPlugin.Id.ToString()"
|
AssistantSessionInstanceId="@assistantPlugin.Id.ToString()"
|
||||||
Link="@launchLink"
|
Link="@launchLink"
|
||||||
OnClick="@(() => this.StartAssistantPluginAsync(assistantPlugin))">
|
OnClick="@(() => this.StartAssistantPluginAsync(assistantPlugin))">
|
||||||
|
<AdditionalActions>
|
||||||
|
@if (availablePlugin is not null)
|
||||||
|
{
|
||||||
|
<AssistantPluginDeleteAction Plugin="@availablePlugin" />
|
||||||
|
}
|
||||||
|
</AdditionalActions>
|
||||||
<SecurityBadge>
|
<SecurityBadge>
|
||||||
<AssistantPluginSecurityCard Plugin="@assistantPlugin" Compact="@true" />
|
<AssistantPluginSecurityCard Plugin="@assistantPlugin" Compact="@true" />
|
||||||
</SecurityBadge>
|
</SecurityBadge>
|
||||||
|
|||||||
@ -115,11 +115,9 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (context is IAvailablePlugin availablePlugin && CanDeleteAssistantPlugin(availablePlugin))
|
@if (context is IAvailablePlugin availablePlugin)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="@T("Delete assistant plugin")">
|
<AssistantPluginDeleteAction Plugin="@availablePlugin" />
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.DeleteOutline" Size="Size.Medium" OnClick="@(() => this.DeleteAssistantPluginAsync(availablePlugin))"/>
|
|
||||||
</MudTooltip>
|
|
||||||
}
|
}
|
||||||
</MudButtonGroup>
|
</MudButtonGroup>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|||||||
@ -28,9 +28,6 @@ public partial class Plugins : MSGComponentBase
|
|||||||
[Inject]
|
[Inject]
|
||||||
private AssistantPluginAuditService AssistantPluginAuditService { get; init; } = null!;
|
private AssistantPluginAuditService AssistantPluginAuditService { get; init; } = null!;
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private AssistantPluginInstallService AssistantPluginInstallService { get; init; } = null!;
|
|
||||||
|
|
||||||
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(Plugins));
|
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(Plugins));
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
@ -190,8 +187,6 @@ public partial class Plugins : MSGComponentBase
|
|||||||
|
|
||||||
private static bool CanEditAssistantPlugin(IAvailablePlugin plugin) => plugin is { IsInternal: false, Type: PluginType.ASSISTANT } && !string.IsNullOrWhiteSpace(plugin.LocalPath);
|
private static bool CanEditAssistantPlugin(IAvailablePlugin plugin) => plugin is { IsInternal: false, Type: PluginType.ASSISTANT } && !string.IsNullOrWhiteSpace(plugin.LocalPath);
|
||||||
|
|
||||||
private static bool CanDeleteAssistantPlugin(IAvailablePlugin plugin) => plugin is { IsInternal: false, Type: PluginType.ASSISTANT } && !string.IsNullOrWhiteSpace(plugin.LocalPath);
|
|
||||||
|
|
||||||
private static bool CanReviseAssistantPlugin(IAvailablePlugin plugin)
|
private static bool CanReviseAssistantPlugin(IAvailablePlugin plugin)
|
||||||
{
|
{
|
||||||
var assistantPlugin = PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == plugin.Id);
|
var assistantPlugin = PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == plugin.Id);
|
||||||
@ -239,33 +234,6 @@ public partial class Plugins : MSGComponentBase
|
|||||||
await this.InvokeAsync(this.StateHasChanged);
|
await this.InvokeAsync(this.StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteAssistantPluginAsync(IAvailablePlugin plugin)
|
|
||||||
{
|
|
||||||
var dialogParameters = new DialogParameters<ConfirmDialog>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
x => x.Message,
|
|
||||||
string.Format(this.T("Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."), plugin.Name)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(this.T("Delete Assistant Plugin"), dialogParameters, DialogOptions.FULLSCREEN);
|
|
||||||
var dialogResult = await dialogReference.Result;
|
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var result = await this.AssistantPluginInstallService.DeleteInstalledAssistantAsync(plugin, CancellationToken.None);
|
|
||||||
if (!result.Success)
|
|
||||||
{
|
|
||||||
LOG.LogError($"Failed to delete assistant plugin '{result.PluginName}' ({result.PluginId}) from '{result.PluginDirectory}' with issue '{result.Issue}'.");
|
|
||||||
await this.MessageBus.SendError(new(Icons.Material.Filled.DeleteForever, string.Format(this.T("The assistant plugin '{0}' could not be deleted: {1}"), plugin.Name, result.Issue)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Check, string.Format(this.T("The '{0}' assistant plugin has been successfully removed."), result.PluginName)));
|
|
||||||
await this.InvokeAsync(this.StateHasChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsSendingMail(string sourceUrl) => sourceUrl.TrimStart().StartsWith("mailto:", StringComparison.OrdinalIgnoreCase);
|
private static bool IsSendingMail(string sourceUrl) => sourceUrl.TrimStart().StartsWith("mailto:", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private PluginAssistants? TryGetAssistantPlugin(Guid pluginId) => PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == pluginId);
|
private PluginAssistants? TryGetAssistantPlugin(Guid pluginId) => PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == pluginId);
|
||||||
|
|||||||
@ -82,6 +82,7 @@ Each assistant plugin lives in its own directory under the assistants plugin roo
|
|||||||
## Structure
|
## Structure
|
||||||
- `ASSISTANT` is the root table. It must contain `Title`, `Description`, `SystemPrompt`, `SubmitText`, `AllowProfiles`, and the nested `UI` definition.
|
- `ASSISTANT` is the root table. It must contain `Title`, `Description`, `SystemPrompt`, `SubmitText`, `AllowProfiles`, and the nested `UI` definition.
|
||||||
- `DEPLOYED_USING_CONFIG_SERVER` identifies who manages the assistant plugin. Set it to `false` for locally managed plugins. A missing field is also treated as local for compatibility with existing plugins. Enterprise-distributed plugins must set it to `true` and cannot be revised with AI in AI Studio.
|
- `DEPLOYED_USING_CONFIG_SERVER` identifies who manages the assistant plugin. Set it to `false` for locally managed plugins. A missing field is also treated as local for compatibility with existing plugins. Enterprise-distributed plugins must set it to `true` and cannot be revised with AI in AI Studio.
|
||||||
|
- `AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}` is reserved for plugins generated by the AI Studio Assistant Builder. It enables Builder-specific actions such as safe deletion and must not be added to manually authored or enterprise-distributed assistants. Newly generated Builder assistants always set `DEPLOYED_USING_CONFIG_SERVER = false` explicitly.
|
||||||
- `ASSISTANT` may optionally define direct-launch metadata for assistant tiles:
|
- `ASSISTANT` may optionally define direct-launch metadata for assistant tiles:
|
||||||
- `LaunchBehavior = "OPEN_WORKSPACE_CHAT_BY_NAME"`
|
- `LaunchBehavior = "OPEN_WORKSPACE_CHAT_BY_NAME"`
|
||||||
- `WorkspaceName = "<target workspace name>"`
|
- `WorkspaceName = "<target workspace name>"`
|
||||||
|
|||||||
@ -49,6 +49,11 @@ DEPRECATION_MESSAGE = ""
|
|||||||
-- Enterprise-managed assistants cannot be revised with AI. Keep false for locally managed plugins:
|
-- Enterprise-managed assistants cannot be revised with AI. Keep false for locally managed plugins:
|
||||||
DEPLOYED_USING_CONFIG_SERVER = false
|
DEPLOYED_USING_CONFIG_SERVER = false
|
||||||
|
|
||||||
|
-- Reserved for assistants created by the AI Studio Assistant Builder. Generated assistants use this
|
||||||
|
-- metadata so AI Studio can identify them and offer Builder-specific actions such as safe deletion.
|
||||||
|
-- Manually authored or enterprise-distributed assistants must not set this metadata:
|
||||||
|
-- AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}
|
||||||
|
|
||||||
ASSISTANT = {
|
ASSISTANT = {
|
||||||
["Title"] = "<Title of your assistant>",
|
["Title"] = "<Title of your assistant>",
|
||||||
["Description"] = "<Description presented to the users, explaining your assistant>",
|
["Description"] = "<Description presented to the users, explaining your assistant>",
|
||||||
|
|||||||
@ -2391,6 +2391,24 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T3571008422"] = "Assisten
|
|||||||
-- The result is ready.
|
-- The result is ready.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "Das Ergebnis ist fertig."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "Das Ergebnis ist fertig."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1318944584"] = "Der Assistent kann nicht gelöscht werden, solange noch Hintergrundaufgaben ausgeführt werden."
|
||||||
|
|
||||||
|
-- Delete assistant plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1692493145"] = "Assistenten-Plugin löschen"
|
||||||
|
|
||||||
|
-- Delete Assistant Plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3637071001"] = "Assistenten-Plugin löschen"
|
||||||
|
|
||||||
|
-- The '{0}' assistant plugin has been successfully removed.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3815023384"] = "Das Assistenten-Plugin „{0}“ wurde erfolgreich entfernt."
|
||||||
|
|
||||||
|
-- The assistant plugin '{0}' could not be deleted: {1}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3985264168"] = "Das Assistenten-Plugin „{0}“ konnte nicht gelöscht werden: {1}"
|
||||||
|
|
||||||
|
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T4033722845"] = "Möchtest du das Assistenten-Plug-in „{0}“ wirklich löschen? Dadurch werden die lokalen Plug-in-Dateien dauerhaft gelöscht."
|
||||||
|
|
||||||
-- Show or hide the detailed security information.
|
-- Show or hide the detailed security information.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Detaillierte Sicherheitsinformationen anzeigen oder ausblenden."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Detaillierte Sicherheitsinformationen anzeigen oder ausblenden."
|
||||||
|
|
||||||
@ -7284,9 +7302,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1506922856"] = "Assistentenprüfung"
|
|||||||
-- Internal Plugins
|
-- Internal Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Interne Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Interne Plugins"
|
||||||
|
|
||||||
-- Delete assistant plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1692493145"] = "Assistenten-Plugin löschen"
|
|
||||||
|
|
||||||
-- Disabled Plugins
|
-- Disabled Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Deaktivierte Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Deaktivierte Plugins"
|
||||||
|
|
||||||
@ -7320,24 +7335,12 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3143506997"] = "Das Assistent-Plugin
|
|||||||
-- Close
|
-- Close
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Schließen"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Schließen"
|
||||||
|
|
||||||
-- Delete Assistant Plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3637071001"] = "Assistant-Plug-in löschen"
|
|
||||||
|
|
||||||
-- Revise assistant plugin with AI
|
-- Revise assistant plugin with AI
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Assistenten-Plugin mit KI überarbeiten"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Assistenten-Plugin mit KI überarbeiten"
|
||||||
|
|
||||||
-- The '{0}' assistant plugin has been successfully removed.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3815023384"] = "Das Assistenten-Plugin „{0}“ wurde erfolgreich entfernt."
|
|
||||||
|
|
||||||
-- Actions
|
-- Actions
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Aktionen"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Aktionen"
|
||||||
|
|
||||||
-- The assistant plugin '{0}' could not be deleted: {1}
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3985264168"] = "Das Assistenten-Plugin „{0}“ konnte nicht gelöscht werden: {1}"
|
|
||||||
|
|
||||||
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4033722845"] = "Möchten Sie das Assistenten-Plugin „{0}“ wirklich löschen? Dadurch werden die lokalen Plugin-Dateien dauerhaft gelöscht."
|
|
||||||
|
|
||||||
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "Die automatische Sicherheitsprüfung für das Assistenten-Plugin „{0}“ ist fehlgeschlagen. Bitte führen Sie sie manuell aus."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "Die automatische Sicherheitsprüfung für das Assistenten-Plugin „{0}“ ist fehlgeschlagen. Bitte führen Sie sie manuell aus."
|
||||||
|
|
||||||
@ -8748,42 +8751,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T378481461"] = "Source Code
|
|||||||
-- Document
|
-- Document
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Dokument"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Dokument"
|
||||||
|
|
||||||
-- The configured transcription provider could not be created.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1235984176"] = "Der konfigurierte Transkriptionsanbieter konnte nicht erstellt werden."
|
|
||||||
|
|
||||||
-- The selected media file no longer exists.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T129859547"] = "Die ausgewählte Mediendatei ist nicht mehr vorhanden."
|
|
||||||
|
|
||||||
-- The selected media file does not contain an audio track.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T134825479"] = "Die ausgewählte Mediendatei enthält keine Audiospur."
|
|
||||||
|
|
||||||
-- The media file could not be transcribed.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden."
|
|
||||||
|
|
||||||
-- The selected file cannot be processed as media.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1707342767"] = "Die ausgewählte Datei kann nicht als Medium verarbeitet werden."
|
|
||||||
|
|
||||||
-- The audio track contains no audible signal, so there is nothing to transcribe.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1988190152"] = "Die Audiospur enthält kein hörbares Signal. Daher gibt es nichts zu transkribieren."
|
|
||||||
|
|
||||||
-- The media file is damaged or its format could not be identified.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2004316549"] = "Die Mediendatei ist beschädigt oder ihr Format konnte nicht erkannt werden."
|
|
||||||
|
|
||||||
-- This media format or audio codec is not supported.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2142564510"] = "Dieses Medienformat oder dieser Audiocodec wird nicht unterstützt."
|
|
||||||
|
|
||||||
-- No usable transcription provider is configured.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2282521655"] = "Es ist kein nutzbarer Transkriptionsanbieter konfiguriert."
|
|
||||||
|
|
||||||
-- The media file could not be prepared for transcription.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2749117459"] = "Die Mediendatei konnte nicht für die Transkription vorbereitet werden."
|
|
||||||
|
|
||||||
-- The transcription provider could not transcribe the media file.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T3091669215"] = "Der Transkriptionsanbieter konnte die Mediendatei nicht transkribieren."
|
|
||||||
|
|
||||||
-- The media pipeline ended without an output file.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T632852430"] = "Die Medienpipeline wurde beendet, ohne eine Ausgabedatei zu erzeugen."
|
|
||||||
|
|
||||||
-- The Assistant Builder context could not be loaded.
|
-- The Assistant Builder context could not be loaded.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGINGENERATIONSERVICE::T108292972"] = "Der Kontext des Assistenten-Builders konnte nicht geladen werden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGINGENERATIONSERVICE::T108292972"] = "Der Kontext des Assistenten-Builders konnte nicht geladen werden."
|
||||||
|
|
||||||
@ -8895,6 +8862,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1211
|
|||||||
-- Only assistant plugins can be edited.
|
-- Only assistant plugins can be edited.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Nur Assistant-Plugins können bearbeitet werden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Nur Assistant-Plugins können bearbeitet werden."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1318944584"] = "Der Assistent kann nicht gelöscht werden, solange noch Hintergrundaktivitäten ausgeführt werden."
|
||||||
|
|
||||||
-- No Lua plugin code was generated.
|
-- No Lua plugin code was generated.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "Es wurde kein Lua-Plugin-Code generiert."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "Es wurde kein Lua-Plugin-Code generiert."
|
||||||
|
|
||||||
@ -8925,6 +8895,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T2955
|
|||||||
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "Das generierte Assistent-Plugin verwendet die ID eines internen AI-Studio-Plugins."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "Das generierte Assistent-Plugin verwendet die ID eines internen AI-Studio-Plugins."
|
||||||
|
|
||||||
|
-- Config Server managed assistant plugins cannot be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3751820312"] = "Von einem Config-Server verwaltete Assistenten-Plugins können nicht gelöscht werden."
|
||||||
|
|
||||||
|
-- Only assistants generated by the Assistant Builder can be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3940247198"] = "Nur mit dem Assistant Builder erstellte Assistenten können gelöscht werden."
|
||||||
|
|
||||||
-- The edited plugin is not an assistant plugin. Issue: {0}
|
-- The edited plugin is not an assistant plugin. Issue: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "Das bearbeitete Plugin ist kein Assistenten-Plugin. Problem: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "Das bearbeitete Plugin ist kein Assistenten-Plugin. Problem: {0}"
|
||||||
|
|
||||||
@ -8946,6 +8922,42 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T8163
|
|||||||
-- The generated assistant plugin is invalid. Issue: {0}
|
-- The generated assistant plugin is invalid. Issue: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T939708112"] = "Das generierte Assistenten-Plugin ist ungültig. Problem: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T939708112"] = "Das generierte Assistenten-Plugin ist ungültig. Problem: {0}"
|
||||||
|
|
||||||
|
-- The configured transcription provider could not be created.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1235984176"] = "Der konfigurierte Transkriptionsanbieter konnte nicht erstellt werden."
|
||||||
|
|
||||||
|
-- The selected media file no longer exists.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T129859547"] = "Die ausgewählte Mediendatei ist nicht mehr vorhanden."
|
||||||
|
|
||||||
|
-- The selected media file does not contain an audio track.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T134825479"] = "Die ausgewählte Mediendatei enthält keine Audiospur."
|
||||||
|
|
||||||
|
-- The media file could not be transcribed.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden."
|
||||||
|
|
||||||
|
-- The selected file cannot be processed as media.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1707342767"] = "Die ausgewählte Datei kann nicht als Medium verarbeitet werden."
|
||||||
|
|
||||||
|
-- The audio track contains no audible signal, so there is nothing to transcribe.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1988190152"] = "Die Audiospur enthält kein hörbares Signal. Daher gibt es nichts zu transkribieren."
|
||||||
|
|
||||||
|
-- The media file is damaged or its format could not be identified.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2004316549"] = "Die Mediendatei ist beschädigt oder ihr Format konnte nicht erkannt werden."
|
||||||
|
|
||||||
|
-- This media format or audio codec is not supported.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2142564510"] = "Dieses Medienformat oder dieser Audiocodec wird nicht unterstützt."
|
||||||
|
|
||||||
|
-- No usable transcription provider is configured.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2282521655"] = "Es ist kein nutzbarer Transkriptionsanbieter konfiguriert."
|
||||||
|
|
||||||
|
-- The media file could not be prepared for transcription.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2749117459"] = "Die Mediendatei konnte nicht für die Transkription vorbereitet werden."
|
||||||
|
|
||||||
|
-- The transcription provider could not transcribe the media file.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T3091669215"] = "Der Transkriptionsanbieter konnte die Mediendatei nicht transkribieren."
|
||||||
|
|
||||||
|
-- The media pipeline ended without an output file.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T632852430"] = "Die Medienpipeline wurde beendet, ohne eine Ausgabedatei zu erzeugen."
|
||||||
|
|
||||||
-- Pandoc Installation
|
-- Pandoc Installation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc-Installation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc-Installation"
|
||||||
|
|
||||||
|
|||||||
@ -2391,6 +2391,24 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T3571008422"] = "Assistan
|
|||||||
-- The result is ready.
|
-- The result is ready.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "The result is ready."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T661906146"] = "The result is ready."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1318944584"] = "The assistant cannot be deleted while background work is still running."
|
||||||
|
|
||||||
|
-- Delete assistant plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T1692493145"] = "Delete assistant plugin"
|
||||||
|
|
||||||
|
-- Delete Assistant Plugin
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3637071001"] = "Delete Assistant Plugin"
|
||||||
|
|
||||||
|
-- The '{0}' assistant plugin has been successfully removed.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3815023384"] = "The '{0}' assistant plugin has been successfully removed."
|
||||||
|
|
||||||
|
-- The assistant plugin '{0}' could not be deleted: {1}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T3985264168"] = "The assistant plugin '{0}' could not be deleted: {1}"
|
||||||
|
|
||||||
|
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINDELETEACTION::T4033722845"] = "Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."
|
||||||
|
|
||||||
-- Show or hide the detailed security information.
|
-- Show or hide the detailed security information.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Show or hide the detailed security information."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTPLUGINSECURITYCARD::T1045105126"] = "Show or hide the detailed security information."
|
||||||
|
|
||||||
@ -7284,9 +7302,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1506922856"] = "Assistant Audit"
|
|||||||
-- Internal Plugins
|
-- Internal Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Internal Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T158493184"] = "Internal Plugins"
|
||||||
|
|
||||||
-- Delete assistant plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1692493145"] = "Delete assistant plugin"
|
|
||||||
|
|
||||||
-- Disabled Plugins
|
-- Disabled Plugins
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Disabled Plugins"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T1724138133"] = "Disabled Plugins"
|
||||||
|
|
||||||
@ -7320,24 +7335,12 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3143506997"] = "The assistant plugin
|
|||||||
-- Close
|
-- Close
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Close"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3448155331"] = "Close"
|
||||||
|
|
||||||
-- Delete Assistant Plugin
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3637071001"] = "Delete Assistant Plugin"
|
|
||||||
|
|
||||||
-- Revise assistant plugin with AI
|
-- Revise assistant plugin with AI
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Revise assistant plugin with AI"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3801095542"] = "Revise assistant plugin with AI"
|
||||||
|
|
||||||
-- The '{0}' assistant plugin has been successfully removed.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3815023384"] = "The '{0}' assistant plugin has been successfully removed."
|
|
||||||
|
|
||||||
-- Actions
|
-- Actions
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Actions"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3865031940"] = "Actions"
|
||||||
|
|
||||||
-- The assistant plugin '{0}' could not be deleted: {1}
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T3985264168"] = "The assistant plugin '{0}' could not be deleted: {1}"
|
|
||||||
|
|
||||||
-- Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4033722845"] = "Do you really want to delete the assistant plugin '{0}'? This will permanently delete the local plugin files."
|
|
||||||
|
|
||||||
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
-- The automatic security audit for the assistant plugin '{0}' failed. Please run it manually.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "The automatic security audit for the assistant plugin '{0}' failed. Please run it manually."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::PLUGINS::T4066679817"] = "The automatic security audit for the assistant plugin '{0}' failed. Please run it manually."
|
||||||
|
|
||||||
@ -8748,42 +8751,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T378481461"] = "Source like p
|
|||||||
-- Document
|
-- Document
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Document"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Document"
|
||||||
|
|
||||||
-- The configured transcription provider could not be created.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1235984176"] = "The configured transcription provider could not be created."
|
|
||||||
|
|
||||||
-- The selected media file no longer exists.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T129859547"] = "The selected media file no longer exists."
|
|
||||||
|
|
||||||
-- The selected media file does not contain an audio track.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T134825479"] = "The selected media file does not contain an audio track."
|
|
||||||
|
|
||||||
-- The media file could not be transcribed.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1543974632"] = "The media file could not be transcribed."
|
|
||||||
|
|
||||||
-- The selected file cannot be processed as media.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1707342767"] = "The selected file cannot be processed as media."
|
|
||||||
|
|
||||||
-- The audio track contains no audible signal, so there is nothing to transcribe.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1988190152"] = "The audio track contains no audible signal, so there is nothing to transcribe."
|
|
||||||
|
|
||||||
-- The media file is damaged or its format could not be identified.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2004316549"] = "The media file is damaged or its format could not be identified."
|
|
||||||
|
|
||||||
-- This media format or audio codec is not supported.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2142564510"] = "This media format or audio codec is not supported."
|
|
||||||
|
|
||||||
-- No usable transcription provider is configured.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2282521655"] = "No usable transcription provider is configured."
|
|
||||||
|
|
||||||
-- The media file could not be prepared for transcription.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2749117459"] = "The media file could not be prepared for transcription."
|
|
||||||
|
|
||||||
-- The transcription provider could not transcribe the media file.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T3091669215"] = "The transcription provider could not transcribe the media file."
|
|
||||||
|
|
||||||
-- The media pipeline ended without an output file.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T632852430"] = "The media pipeline ended without an output file."
|
|
||||||
|
|
||||||
-- The Assistant Builder context could not be loaded.
|
-- The Assistant Builder context could not be loaded.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGINGENERATIONSERVICE::T108292972"] = "The Assistant Builder context could not be loaded."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGINGENERATIONSERVICE::T108292972"] = "The Assistant Builder context could not be loaded."
|
||||||
|
|
||||||
@ -8895,6 +8862,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1211
|
|||||||
-- Only assistant plugins can be edited.
|
-- Only assistant plugins can be edited.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Only assistant plugins can be edited."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1288328479"] = "Only assistant plugins can be edited."
|
||||||
|
|
||||||
|
-- The assistant cannot be deleted while background work is still running.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1318944584"] = "The assistant cannot be deleted while background work is still running."
|
||||||
|
|
||||||
-- No Lua plugin code was generated.
|
-- No Lua plugin code was generated.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "No Lua plugin code was generated."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T1839013358"] = "No Lua plugin code was generated."
|
||||||
|
|
||||||
@ -8925,6 +8895,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T2955
|
|||||||
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
-- The generated assistant plugin uses the ID of an internal AI Studio plugin.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "The generated assistant plugin uses the ID of an internal AI Studio plugin."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3162363526"] = "The generated assistant plugin uses the ID of an internal AI Studio plugin."
|
||||||
|
|
||||||
|
-- Config Server managed assistant plugins cannot be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3751820312"] = "Config Server managed assistant plugins cannot be deleted."
|
||||||
|
|
||||||
|
-- Only assistants generated by the Assistant Builder can be deleted.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3940247198"] = "Only assistants generated by the Assistant Builder can be deleted."
|
||||||
|
|
||||||
-- The edited plugin is not an assistant plugin. Issue: {0}
|
-- The edited plugin is not an assistant plugin. Issue: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "The edited plugin is not an assistant plugin. Issue: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T3984111892"] = "The edited plugin is not an assistant plugin. Issue: {0}"
|
||||||
|
|
||||||
@ -8946,6 +8922,42 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T8163
|
|||||||
-- The generated assistant plugin is invalid. Issue: {0}
|
-- The generated assistant plugin is invalid. Issue: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T939708112"] = "The generated assistant plugin is invalid. Issue: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::ASSISTANTPLUGININSTALLSERVICE::T939708112"] = "The generated assistant plugin is invalid. Issue: {0}"
|
||||||
|
|
||||||
|
-- The configured transcription provider could not be created.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1235984176"] = "The configured transcription provider could not be created."
|
||||||
|
|
||||||
|
-- The selected media file no longer exists.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T129859547"] = "The selected media file no longer exists."
|
||||||
|
|
||||||
|
-- The selected media file does not contain an audio track.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T134825479"] = "The selected media file does not contain an audio track."
|
||||||
|
|
||||||
|
-- The media file could not be transcribed.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1543974632"] = "The media file could not be transcribed."
|
||||||
|
|
||||||
|
-- The selected file cannot be processed as media.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1707342767"] = "The selected file cannot be processed as media."
|
||||||
|
|
||||||
|
-- The audio track contains no audible signal, so there is nothing to transcribe.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T1988190152"] = "The audio track contains no audible signal, so there is nothing to transcribe."
|
||||||
|
|
||||||
|
-- The media file is damaged or its format could not be identified.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2004316549"] = "The media file is damaged or its format could not be identified."
|
||||||
|
|
||||||
|
-- This media format or audio codec is not supported.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2142564510"] = "This media format or audio codec is not supported."
|
||||||
|
|
||||||
|
-- No usable transcription provider is configured.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2282521655"] = "No usable transcription provider is configured."
|
||||||
|
|
||||||
|
-- The media file could not be prepared for transcription.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T2749117459"] = "The media file could not be prepared for transcription."
|
||||||
|
|
||||||
|
-- The transcription provider could not transcribe the media file.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T3091669215"] = "The transcription provider could not transcribe the media file."
|
||||||
|
|
||||||
|
-- The media pipeline ended without an output file.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T632852430"] = "The media pipeline ended without an output file."
|
||||||
|
|
||||||
-- Pandoc Installation
|
-- Pandoc Installation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType
|
|||||||
public bool HasEmbeddedProfileSelection { get; private set; }
|
public bool HasEmbeddedProfileSelection { get; private set; }
|
||||||
public bool HasCustomPromptBuilder => this.buildPromptFunction is not null;
|
public bool HasCustomPromptBuilder => this.buildPromptFunction is not null;
|
||||||
public bool IsAssistantBuilderGenerated { get; private set; }
|
public bool IsAssistantBuilderGenerated { get; private set; }
|
||||||
|
public bool HasDeploymentManagementMetadata { get; private set; }
|
||||||
public bool IsManagedByConfigServer { get; private set; }
|
public bool IsManagedByConfigServer { get; private set; }
|
||||||
public AssistantPluginLaunchBehavior LaunchBehavior { get; private set; }
|
public AssistantPluginLaunchBehavior LaunchBehavior { get; private set; }
|
||||||
public string LaunchWorkspaceName { get; private set; } = string.Empty;
|
public string LaunchWorkspaceName { get; private set; } = string.Empty;
|
||||||
@ -66,6 +67,7 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType
|
|||||||
message = string.Empty;
|
message = string.Empty;
|
||||||
this.HasEmbeddedProfileSelection = false;
|
this.HasEmbeddedProfileSelection = false;
|
||||||
this.IsAssistantBuilderGenerated = false;
|
this.IsAssistantBuilderGenerated = false;
|
||||||
|
this.HasDeploymentManagementMetadata = false;
|
||||||
this.IsManagedByConfigServer = false;
|
this.IsManagedByConfigServer = false;
|
||||||
this.buildPromptFunction = null;
|
this.buildPromptFunction = null;
|
||||||
this.LaunchBehavior = AssistantPluginLaunchBehavior.NONE;
|
this.LaunchBehavior = AssistantPluginLaunchBehavior.NONE;
|
||||||
@ -169,7 +171,10 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType
|
|||||||
private void TryReadDeploymentMetadata()
|
private void TryReadDeploymentMetadata()
|
||||||
{
|
{
|
||||||
if (this.State.Environment["DEPLOYED_USING_CONFIG_SERVER"].TryRead<bool>(out var deployedUsingConfigServer))
|
if (this.State.Environment["DEPLOYED_USING_CONFIG_SERVER"].TryRead<bool>(out var deployedUsingConfigServer))
|
||||||
|
{
|
||||||
|
this.HasDeploymentManagementMetadata = true;
|
||||||
this.IsManagedByConfigServer = deployedUsingConfigServer;
|
this.IsManagedByConfigServer = deployedUsingConfigServer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryReadLaunchConfiguration(LuaTable assistantTable, out string message)
|
private bool TryReadLaunchConfiguration(LuaTable assistantTable, out string message)
|
||||||
|
|||||||
@ -115,7 +115,7 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
if (!generatedAssistant.IsAssistantBuilderGenerated)
|
if (!generatedAssistant.IsAssistantBuilderGenerated)
|
||||||
return InitialFailure(TB("The generated assistant plugin must include the Assistant Builder metadata."));
|
return InitialFailure(TB("The generated assistant plugin must include the Assistant Builder metadata."));
|
||||||
|
|
||||||
if (generatedAssistant.IsManagedByConfigServer)
|
if (!generatedAssistant.HasDeploymentManagementMetadata || generatedAssistant.IsManagedByConfigServer)
|
||||||
return InitialFailure(TB("The generated assistant plugin must be marked as locally managed."));
|
return InitialFailure(TB("The generated assistant plugin must be marked as locally managed."));
|
||||||
|
|
||||||
return new(true, fullLua, parsedResponse.Plugin?.Name ?? string.Empty, string.Empty);
|
return new(true, fullLua, parsedResponse.Plugin?.Name ?? string.Empty, string.Empty);
|
||||||
@ -168,7 +168,8 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
if (plugin.IsAssistantBuilderGenerated && !revisedAssistant.IsAssistantBuilderGenerated)
|
if (plugin.IsAssistantBuilderGenerated && !revisedAssistant.IsAssistantBuilderGenerated)
|
||||||
return RevisionFailure(TB("The revised assistant plugin must keep the Assistant Builder metadata."));
|
return RevisionFailure(TB("The revised assistant plugin must keep the Assistant Builder metadata."));
|
||||||
|
|
||||||
if (revisedAssistant.IsManagedByConfigServer)
|
if (revisedAssistant.IsManagedByConfigServer ||
|
||||||
|
plugin.IsAssistantBuilderGenerated && !revisedAssistant.HasDeploymentManagementMetadata)
|
||||||
return RevisionFailure(TB("The revised assistant plugin must remain locally managed."));
|
return RevisionFailure(TB("The revised assistant plugin must remain locally managed."));
|
||||||
|
|
||||||
return new(true, revisedLua, parsedResponse.Plugin?.Name ?? plugin.Name, string.Empty);
|
return new(true, revisedLua, parsedResponse.Plugin?.Name ?? plugin.Name, string.Empty);
|
||||||
@ -364,7 +365,7 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
{
|
{
|
||||||
var companionLua = FormatCompanionLuaFiles(plugin);
|
var companionLua = FormatCompanionLuaFiles(plugin);
|
||||||
var builderMetadataRule = plugin.IsAssistantBuilderGenerated
|
var builderMetadataRule = plugin.IsAssistantBuilderGenerated
|
||||||
? "- Keep AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}."
|
? "- Keep AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1} and set DEPLOYED_USING_CONFIG_SERVER = false explicitly."
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
return $$"""
|
return $$"""
|
||||||
Revise an existing locally managed AI Studio Lua assistant plugin.
|
Revise an existing locally managed AI Studio Lua assistant plugin.
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
using AIStudio.Tools.AssistantSessions;
|
||||||
|
using AIStudio.Tools.Media;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
using AIStudio.Tools.PluginSystem.Assistants;
|
using AIStudio.Tools.PluginSystem.Assistants;
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ public sealed class AssistantPluginInstallService
|
|||||||
|
|
||||||
private readonly ILogger<AssistantPluginInstallService> logger;
|
private readonly ILogger<AssistantPluginInstallService> logger;
|
||||||
private readonly SettingsManager settingsManager;
|
private readonly SettingsManager settingsManager;
|
||||||
|
private readonly AssistantSessionService assistantSessionService;
|
||||||
|
private readonly MediaTranscriptionService mediaTranscriptionService;
|
||||||
private readonly SemaphoreSlim installSemaphore = new(1, 1);
|
private readonly SemaphoreSlim installSemaphore = new(1, 1);
|
||||||
|
|
||||||
private static AssistantPluginInstallResult Error(string issue) => new(false, Guid.Empty, string.Empty, string.Empty, false, issue);
|
private static AssistantPluginInstallResult Error(string issue) => new(false, Guid.Empty, string.Empty, string.Empty, false, issue);
|
||||||
@ -34,13 +38,39 @@ public sealed class AssistantPluginInstallService
|
|||||||
|
|
||||||
private static AssistantPluginUpdateResult UpdateError(IPluginMetadata plugin, string pluginDirectory, string issue) => new(false, plugin.Id, plugin.Name, pluginDirectory, issue);
|
private static AssistantPluginUpdateResult UpdateError(IPluginMetadata plugin, string pluginDirectory, string issue) => new(false, plugin.Id, plugin.Name, pluginDirectory, issue);
|
||||||
|
|
||||||
public AssistantPluginInstallService(ILogger<AssistantPluginInstallService> logger, SettingsManager settingsManager)
|
public AssistantPluginInstallService(
|
||||||
|
ILogger<AssistantPluginInstallService> logger,
|
||||||
|
SettingsManager settingsManager,
|
||||||
|
AssistantSessionService assistantSessionService,
|
||||||
|
MediaTranscriptionService mediaTranscriptionService)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.settingsManager = settingsManager;
|
this.settingsManager = settingsManager;
|
||||||
|
this.assistantSessionService = assistantSessionService;
|
||||||
|
this.mediaTranscriptionService = mediaTranscriptionService;
|
||||||
this.logger.LogInformation("The assistant plugin install service has been initialized.");
|
this.logger.LogInformation("The assistant plugin install service has been initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether a local plugin is an Assistant Builder generated assistant that users may delete.
|
||||||
|
/// </summary>
|
||||||
|
public static bool CanDeleteInstalledAssistant(IAvailablePlugin plugin) => string.IsNullOrWhiteSpace(GetAssistantDeletionEligibilityIssue(plugin));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether an assistant still owns running or canceling background work.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasActiveAssistantWork(Guid pluginId)
|
||||||
|
{
|
||||||
|
var instanceId = pluginId.ToString();
|
||||||
|
if (this.assistantSessionService.GetSnapshots().Any(snapshot => snapshot.IsActive && string.Equals(snapshot.Key.InstanceId, instanceId, StringComparison.Ordinal)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var ownerIdSuffix = $":{instanceId}";
|
||||||
|
return this.mediaTranscriptionService.GetSnapshots().Any(snapshot =>
|
||||||
|
snapshot is { IsBusy: true, Owner.Kind: MediaImportOwnerKind.ASSISTANT } &&
|
||||||
|
snapshot.Owner.Id.EndsWith(ownerIdSuffix, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether generated Lua assistant plugin code can be loaded and installed.
|
/// Checks whether generated Lua assistant plugin code can be loaded and installed.
|
||||||
/// The plugin is written to a temporary staging directory and validated through the
|
/// The plugin is written to a temporary staging directory and validated through the
|
||||||
@ -232,32 +262,28 @@ public sealed class AssistantPluginInstallService
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
public async Task<AssistantPluginDeleteResult> DeleteInstalledAssistantAsync(IAvailablePlugin plugin, CancellationToken token)
|
public async Task<AssistantPluginDeleteResult> DeleteInstalledAssistantAsync(IAvailablePlugin plugin, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (plugin.Type is not PluginType.ASSISTANT)
|
var eligibilityIssue = GetAssistantDeletionEligibilityIssue(plugin);
|
||||||
return DeleteError(plugin, plugin.LocalPath, TB("Only assistant plugins can be deleted."));
|
if (!string.IsNullOrEmpty(eligibilityIssue))
|
||||||
|
return DeleteError(plugin, plugin.LocalPath, eligibilityIssue);
|
||||||
|
|
||||||
if (plugin.IsInternal)
|
if (this.HasActiveAssistantWork(plugin.Id))
|
||||||
return DeleteError(plugin, plugin.LocalPath, TB("Internal assistant plugins cannot be deleted."));
|
return DeleteError(plugin, plugin.LocalPath, TB("The assistant cannot be deleted while background work is still running."));
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(plugin.LocalPath))
|
|
||||||
return DeleteError(plugin, string.Empty, TB("The assistant plugin has no local directory."));
|
|
||||||
|
|
||||||
if (!TryGetAssistantPluginsRoot(out var assistantPluginsRoot, out var rootIssue))
|
|
||||||
return DeleteError(plugin, plugin.LocalPath, rootIssue);
|
|
||||||
|
|
||||||
var pluginDirectory = plugin.LocalPath;
|
|
||||||
if (!IsPathInsideDirectory(assistantPluginsRoot, pluginDirectory) || IsSameDirectory(assistantPluginsRoot, pluginDirectory))
|
|
||||||
return DeleteError(plugin, pluginDirectory, TB("The assistant plugin directory is outside the local assistant plugin directory."));
|
|
||||||
|
|
||||||
if (!Directory.Exists(pluginDirectory))
|
|
||||||
return DeleteError(plugin, pluginDirectory, TB("The assistant plugin directory does not exist."));
|
|
||||||
|
|
||||||
await this.installSemaphore.WaitAsync(token);
|
await this.installSemaphore.WaitAsync(token);
|
||||||
|
var pluginDirectory = plugin.LocalPath;
|
||||||
var backupDirectory = string.Empty;
|
var backupDirectory = string.Empty;
|
||||||
var wasEnabled = false;
|
var wasEnabled = false;
|
||||||
var removedAudits = new List<PluginAssistantAudit>();
|
var removedAudits = new List<PluginAssistantAudit>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
eligibilityIssue = GetAssistantDeletionEligibilityIssue(plugin);
|
||||||
|
if (!string.IsNullOrEmpty(eligibilityIssue))
|
||||||
|
return DeleteError(plugin, pluginDirectory, eligibilityIssue);
|
||||||
|
|
||||||
|
if (this.HasActiveAssistantWork(plugin.Id))
|
||||||
|
return DeleteError(plugin, pluginDirectory, TB("The assistant cannot be deleted while background work is still running."));
|
||||||
|
|
||||||
backupDirectory = CreateDeleteBackupDirectory(plugin);
|
backupDirectory = CreateDeleteBackupDirectory(plugin);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(backupDirectory)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(backupDirectory)!);
|
||||||
Directory.Move(pluginDirectory, backupDirectory);
|
Directory.Move(pluginDirectory, backupDirectory);
|
||||||
@ -486,6 +512,41 @@ public sealed class AssistantPluginInstallService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetAssistantDeletionEligibilityIssue(IAvailablePlugin plugin)
|
||||||
|
{
|
||||||
|
if (plugin.Type is not PluginType.ASSISTANT)
|
||||||
|
return TB("Only assistant plugins can be deleted.");
|
||||||
|
|
||||||
|
if (plugin.IsInternal)
|
||||||
|
return TB("Internal assistant plugins cannot be deleted.");
|
||||||
|
|
||||||
|
if (plugin.IsManagedByConfigServer)
|
||||||
|
return TB("Config Server managed assistant plugins cannot be deleted.");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(plugin.LocalPath))
|
||||||
|
return TB("The assistant plugin has no local directory.");
|
||||||
|
|
||||||
|
var assistantPlugin = PluginFactory.RunningPlugins
|
||||||
|
.OfType<PluginAssistants>()
|
||||||
|
.FirstOrDefault(candidate => candidate.Id == plugin.Id && IsSameDirectory(candidate.PluginPath, plugin.LocalPath));
|
||||||
|
|
||||||
|
if (assistantPlugin is null || assistantPlugin.IsInternal || !assistantPlugin.IsAssistantBuilderGenerated)
|
||||||
|
return TB("Only assistants generated by the Assistant Builder can be deleted.");
|
||||||
|
|
||||||
|
if (assistantPlugin.IsManagedByConfigServer)
|
||||||
|
return TB("Config Server managed assistant plugins cannot be deleted.");
|
||||||
|
|
||||||
|
if (!TryGetAssistantPluginsRoot(out var assistantPluginsRoot, out var rootIssue))
|
||||||
|
return rootIssue;
|
||||||
|
|
||||||
|
if (!IsPathInsideDirectory(assistantPluginsRoot, plugin.LocalPath) || IsSameDirectory(assistantPluginsRoot, plugin.LocalPath))
|
||||||
|
return TB("The assistant plugin directory is outside the local assistant plugin directory.");
|
||||||
|
|
||||||
|
return Directory.Exists(plugin.LocalPath)
|
||||||
|
? string.Empty
|
||||||
|
: TB("The assistant plugin directory does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
private void TryDeleteStagingDirectory(string stagingDirectory)
|
private void TryDeleteStagingDirectory(string stagingDirectory)
|
||||||
{
|
{
|
||||||
TryDeleteDirectory(stagingDirectory, "assistant plugin staging", this.logger);
|
TryDeleteDirectory(stagingDirectory, "assistant plugin staging", this.logger);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user