mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-24 20:52:11 +00:00
using the parsed config to allow or forbid to revise the assistant with ai
This commit is contained in:
parent
9d5322dd1b
commit
d9098d288f
@ -74,7 +74,7 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
|||||||
private static readonly AssistantSessionStateKey<string> SECURITY_MESSAGE_STATE_KEY = new(nameof(securityMessage));
|
private static readonly AssistantSessionStateKey<string> SECURITY_MESSAGE_STATE_KEY = new(nameof(securityMessage));
|
||||||
private static readonly AssistantSessionStateKey<bool> IS_SECURITY_BLOCKED_STATE_KEY = new(nameof(isSecurityBlocked));
|
private static readonly AssistantSessionStateKey<bool> IS_SECURITY_BLOCKED_STATE_KEY = new(nameof(isSecurityBlocked));
|
||||||
|
|
||||||
private bool CanReviseCurrentAssistant => this.assistantPlugin is { IsInternal: false, IsAssistantBuilderGenerated: true } && !string.IsNullOrWhiteSpace(this.assistantPlugin.PluginPath);
|
private bool CanReviseCurrentAssistant => this.assistantPlugin is { IsInternal: false, IsManagedByConfigServer: false } && !string.IsNullOrWhiteSpace(this.assistantPlugin.PluginPath);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void CaptureCustomAssistantSessionState(AssistantSessionStateWriter state)
|
protected override void CaptureCustomAssistantSessionState(AssistantSessionStateWriter state)
|
||||||
|
|||||||
@ -87,7 +87,7 @@ public partial class AssistantPluginRevisionDialog : MSGComponentBase
|
|||||||
|
|
||||||
if (!CanReviseAssistantPlugin(this.availablePlugin, this.assistantPlugin))
|
if (!CanReviseAssistantPlugin(this.availablePlugin, this.assistantPlugin))
|
||||||
{
|
{
|
||||||
this.issue = T("Only local assistants generated by the Assistant Builder can be revised with AI.");
|
this.issue = T("Only locally managed assistant plugins can be revised with AI.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,9 +225,9 @@ public partial class AssistantPluginRevisionDialog : MSGComponentBase
|
|||||||
private void Cancel() => this.MudDialog.Cancel();
|
private void Cancel() => this.MudDialog.Cancel();
|
||||||
|
|
||||||
private static bool CanReviseAssistantPlugin(IAvailablePlugin availablePlugin, PluginAssistants assistantPlugin) =>
|
private static bool CanReviseAssistantPlugin(IAvailablePlugin availablePlugin, PluginAssistants assistantPlugin) =>
|
||||||
availablePlugin is { IsInternal: false, Type: PluginType.ASSISTANT } &&
|
availablePlugin is { IsInternal: false, IsManagedByConfigServer: false, Type: PluginType.ASSISTANT } &&
|
||||||
!string.IsNullOrWhiteSpace(availablePlugin.LocalPath) &&
|
!string.IsNullOrWhiteSpace(availablePlugin.LocalPath) &&
|
||||||
assistantPlugin.IsAssistantBuilderGenerated;
|
assistantPlugin is { IsInternal: false, IsManagedByConfigServer: false };
|
||||||
|
|
||||||
private static void UpsertAudit(IList<PluginAssistantAudit> audits, PluginAssistantAudit audit)
|
private static void UpsertAudit(IList<PluginAssistantAudit> audits, PluginAssistantAudit audit)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -195,9 +195,9 @@ public partial class Plugins : MSGComponentBase
|
|||||||
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);
|
||||||
return plugin is { IsInternal: false, Type: PluginType.ASSISTANT } &&
|
return plugin is { IsInternal: false, IsManagedByConfigServer: false, Type: PluginType.ASSISTANT } &&
|
||||||
!string.IsNullOrWhiteSpace(plugin.LocalPath) &&
|
!string.IsNullOrWhiteSpace(plugin.LocalPath) &&
|
||||||
assistantPlugin?.IsAssistantBuilderGenerated is true;
|
assistantPlugin?.IsManagedByConfigServer is false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OpenAssistantPluginEditorDialogAsync(IAvailablePlugin plugin)
|
private async Task OpenAssistantPluginEditorDialogAsync(IAvailablePlugin plugin)
|
||||||
|
|||||||
@ -105,12 +105,19 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
return InitialFailure(issue);
|
return InitialFailure(issue);
|
||||||
|
|
||||||
var fullLua = parsedResponse.FullLua.Trim();
|
var fullLua = parsedResponse.FullLua.Trim();
|
||||||
if (!fullLua.Contains(request.PluginId.ToString(), StringComparison.OrdinalIgnoreCase))
|
var generatedPlugin = await PluginFactory.Load(null, fullLua, token);
|
||||||
|
if (generatedPlugin is not PluginAssistants generatedAssistant || !generatedAssistant.IsValid)
|
||||||
|
return InitialFailure(TB("The generated assistant plugin is not a valid assistant plugin."));
|
||||||
|
|
||||||
|
if (generatedAssistant.Id != request.PluginId)
|
||||||
return InitialFailure(TB("The generated assistant plugin must use the assigned plugin ID."));
|
return InitialFailure(TB("The generated assistant plugin must use the assigned plugin ID."));
|
||||||
|
|
||||||
if (!ContainsAssistantBuilderMetadata(fullLua))
|
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)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,8 +129,8 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
string testContext,
|
string testContext,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (!plugin.IsAssistantBuilderGenerated)
|
if (plugin is { IsInternal: true } or { IsManagedByConfigServer: true })
|
||||||
return RevisionFailure(TB("Only assistants generated by the Assistant Builder can be revised with AI."));
|
return RevisionFailure(TB("Only locally managed assistant plugins can be revised with AI."));
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(currentLua))
|
if (string.IsNullOrWhiteSpace(currentLua))
|
||||||
return RevisionFailure(TB("The current plugin.lua content is empty."));
|
return RevisionFailure(TB("The current plugin.lua content is empty."));
|
||||||
@ -151,12 +158,19 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
return RevisionFailure(issue);
|
return RevisionFailure(issue);
|
||||||
|
|
||||||
var revisedLua = parsedResponse.FullLua.Trim();
|
var revisedLua = parsedResponse.FullLua.Trim();
|
||||||
if (!revisedLua.Contains(plugin.Id.ToString(), StringComparison.OrdinalIgnoreCase))
|
var parsedRevision = await PluginFactory.Load(plugin.PluginPath, revisedLua, token);
|
||||||
|
if (parsedRevision is not PluginAssistants revisedAssistant || !revisedAssistant.IsValid)
|
||||||
|
return RevisionFailure(TB("The revised assistant plugin is not a valid assistant plugin."));
|
||||||
|
|
||||||
|
if (revisedAssistant.Id != plugin.Id)
|
||||||
return RevisionFailure(TB("The revised assistant plugin must keep the same plugin ID."));
|
return RevisionFailure(TB("The revised assistant plugin must keep the same plugin ID."));
|
||||||
|
|
||||||
if (!ContainsAssistantBuilderMetadata(revisedLua))
|
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)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +260,7 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
TARGET_GROUPS = {"EVERYONE"}
|
TARGET_GROUPS = {"EVERYONE"}
|
||||||
IS_MAINTAINED = true
|
IS_MAINTAINED = true
|
||||||
DEPRECATION_MESSAGE = ""
|
DEPRECATION_MESSAGE = ""
|
||||||
|
DEPLOYED_USING_CONFIG_SERVER = false
|
||||||
AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}
|
AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}
|
||||||
</fixed_metadata_defaults>
|
</fixed_metadata_defaults>
|
||||||
|
|
||||||
@ -263,6 +278,7 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
- The JSON "plugin" object describes the top-level Lua plugin metadata such as NAME, DESCRIPTION, and CATEGORIES.
|
- The JSON "plugin" object describes the top-level Lua plugin metadata such as NAME, DESCRIPTION, and CATEGORIES.
|
||||||
- The JSON "assistant" object describes the ASSISTANT table metadata such as Title, Description, SystemPrompt, SubmitText, and AllowProfiles.
|
- The JSON "assistant" object describes the ASSISTANT table metadata such as Title, Description, SystemPrompt, SubmitText, and AllowProfiles.
|
||||||
- The plugin must include all required top-level metadata and the ASSISTANT table.
|
- The plugin must include all required top-level metadata and the ASSISTANT table.
|
||||||
|
- The plugin must include DEPLOYED_USING_CONFIG_SERVER = false.
|
||||||
- The plugin must include AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}.
|
- The plugin must include AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}.
|
||||||
- The ASSISTANT table must include Title, Description, SystemPrompt, SubmitText, AllowProfiles, and UI.
|
- The ASSISTANT table must include Title, Description, SystemPrompt, SubmitText, AllowProfiles, and UI.
|
||||||
- UI.Type must be "FORM".
|
- UI.Type must be "FORM".
|
||||||
@ -347,8 +363,11 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
string responseSchema)
|
string responseSchema)
|
||||||
{
|
{
|
||||||
var companionLua = FormatCompanionLuaFiles(plugin);
|
var companionLua = FormatCompanionLuaFiles(plugin);
|
||||||
|
var builderMetadataRule = plugin.IsAssistantBuilderGenerated
|
||||||
|
? "- Keep AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}."
|
||||||
|
: string.Empty;
|
||||||
return $$"""
|
return $$"""
|
||||||
Revise an existing AI Studio Lua assistant plugin.
|
Revise an existing locally managed AI Studio Lua assistant plugin.
|
||||||
Generate a complete replacement for plugin.lua from the current plugin.lua and the user's requested change.
|
Generate a complete replacement for plugin.lua from the current plugin.lua and the user's requested change.
|
||||||
|
|
||||||
<plugin_context>
|
<plugin_context>
|
||||||
@ -391,7 +410,8 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
- Encode "full_lua" as a normal JSON string: use \" for quotes and \n for line breaks. Do not double-escape Lua quotes or line breaks as \\\" or \\n.
|
- Encode "full_lua" as a normal JSON string: use \" for quotes and \n for line breaks. Do not double-escape Lua quotes or line breaks as \\\" or \\n.
|
||||||
- Keep ID = "{{plugin.Id}}" exactly. Do not create a new plugin ID.
|
- Keep ID = "{{plugin.Id}}" exactly. Do not create a new plugin ID.
|
||||||
- Keep TYPE = "ASSISTANT".
|
- Keep TYPE = "ASSISTANT".
|
||||||
- Keep AI_STUDIO_ASSISTANT_BUILDER = {Generated = true, SchemaVersion = 1}.
|
- Keep the assistant locally managed. DEPLOYED_USING_CONFIG_SERVER must not be true.
|
||||||
|
{{builderMetadataRule}}
|
||||||
- Preserve existing behavior unless the requested change explicitly modifies it.
|
- Preserve existing behavior unless the requested change explicitly modifies it.
|
||||||
- Apply the requested change directly to plugin.lua; do not describe how to change it.
|
- Apply the requested change directly to plugin.lua; do not describe how to change it.
|
||||||
- Do not create companion files, new require(...) dependencies, hidden behavior, or obfuscated behavior.
|
- Do not create companion files, new require(...) dependencies, hidden behavior, or obfuscated behavior.
|
||||||
@ -515,8 +535,6 @@ public sealed class AssistantPluginGenerationService(ILogger<AssistantPluginGene
|
|||||||
|
|
||||||
private static bool ProviderIsUsable(ProviderSettings provider) => provider != ProviderSettings.NONE && provider.UsedLLMProvider is not LLMProviders.NONE;
|
private static bool ProviderIsUsable(ProviderSettings provider) => provider != ProviderSettings.NONE && provider.UsedLLMProvider is not LLMProviders.NONE;
|
||||||
|
|
||||||
private static bool ContainsAssistantBuilderMetadata(string lua) => lua.Contains("AI_STUDIO_ASSISTANT_BUILDER", StringComparison.Ordinal);
|
|
||||||
|
|
||||||
private static string SerializeUntrustedPromptData(object value) => JsonSerializer.Serialize(value, UNTRUSTED_PROMPT_JSON_OPTIONS);
|
private static string SerializeUntrustedPromptData(object value) => JsonSerializer.Serialize(value, UNTRUSTED_PROMPT_JSON_OPTIONS);
|
||||||
|
|
||||||
private static string ValueOrNone(string value) => string.IsNullOrWhiteSpace(value)
|
private static string ValueOrNone(string value) => string.IsNullOrWhiteSpace(value)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user