Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/MindWork AI Studio/Assistants/I18N/allTexts.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7516,6 +7516,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANT
-- Button
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANTCOMPONENTTYPEEXTENSIONS::T864557713"] = "Button"

-- The ASSISTANT table contains an invalid LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T109828905"] = "The ASSISTANT table contains an invalid LaunchBehavior value."

-- The ASSISTANT table contains an unsupported LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1194373781"] = "The ASSISTANT table contains an unsupported LaunchBehavior value."

-- Failed to parse the UI render tree from the ASSISTANT lua table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1318499252"] = "Failed to parse the UI render tree from the ASSISTANT lua table."

Expand All @@ -7531,12 +7537,18 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T2
-- The ASSISTANT lua table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3017816936"] = "The ASSISTANT lua table does not exist or is not a valid table."

-- The ASSISTANT table contains an empty WorkspaceName for LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3233001282"] = "The ASSISTANT table contains an empty WorkspaceName for LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'."

-- The provided ASSISTANT lua table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3402798667"] = "The provided ASSISTANT lua table does not contain a valid system prompt."

-- The ASSISTANT table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3723171842"] = "The ASSISTANT table does not contain a valid system prompt."

-- The ASSISTANT table contains the LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME' but no valid WorkspaceName.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T4215554842"] = "The ASSISTANT table contains the LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME' but no valid WorkspaceName."

-- ASSISTANT.BuildPrompt exists but is not a Lua function or has invalid syntax.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T683382975"] = "ASSISTANT.BuildPrompt exists but is not a Lua function or has invalid syntax."

Expand Down
15 changes: 12 additions & 3 deletions app/MindWork AI Studio/Components/AssistantBlock.razor
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@
<MudCardActions>
<MudStack Row="@true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween" Style="width: 100%;">
<MudButtonGroup Variant="Variant.Outlined">
<MudButton Size="Size.Large" Variant="Variant.Filled" StartIcon="@this.Icon" Color="Color.Default" Href="@this.Link" Disabled="@this.Disabled">
@this.ButtonText
</MudButton>
@if (this.HasStartAction)
{
<MudButton Size="Size.Large" Variant="Variant.Filled" StartIcon="@this.Icon" Color="Color.Default" OnClick="@this.OnClick" Disabled="@this.Disabled">
@this.ButtonText
</MudButton>
}
else
{
<MudButton Size="Size.Large" Variant="Variant.Filled" StartIcon="@this.Icon" Color="Color.Default" Href="@this.Link" Disabled="@this.Disabled">
@this.ButtonText
</MudButton>
}
@if (this.HasSettingsPanel)
{
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
Expand Down
5 changes: 5 additions & 0 deletions app/MindWork AI Studio/Components/AssistantBlock.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
[Parameter]
public string Link { get; set; } = string.Empty;

[Parameter]
public EventCallback OnClick { get; set; }

[Parameter]
public bool Disabled { get; set; }

Expand Down Expand Up @@ -61,4 +64,6 @@ private async Task OpenSettingsDialog()
private bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature);

private bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel);

private bool HasStartAction => this.OnClick.HasDelegate;
}
4 changes: 3 additions & 1 deletion app/MindWork AI Studio/Pages/Assistants.razor
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@
@foreach (var assistantPlugin in this.AssistantPlugins)
{
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
var launchLink = assistantPlugin.StartsChatDirectly ? string.Empty : $"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}";
<AssistantBlock TSettings="NoSettingsPanel"
Name="@T(assistantPlugin.AssistantTitle)"
Description="@T(assistantPlugin.Description)"
Icon="@Icons.Material.Filled.FindInPage"
Disabled="@(!securityState.CanStartAssistant)"
Link="@($"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}")">
Link="@launchLink"
OnClick="@(() => this.StartAssistantPluginAsync(assistantPlugin))">
<SecurityBadge>
<AssistantPluginSecurityCard Plugin="@assistantPlugin" Compact="@true" />
</SecurityBadge>
Expand Down
51 changes: 51 additions & 0 deletions app/MindWork AI Studio/Pages/Assistants.razor.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using AIStudio.Chat;
using AIStudio.Components;
using AIStudio.Agents.AssistantAudit;
using AIStudio.Tools.PluginSystem;
Expand All @@ -12,6 +13,12 @@ public partial class Assistants : MSGComponentBase

[Inject]
private AssistantPluginAuditService AssistantPluginAuditService { get; init; } = null!;

[Inject]
private NavigationManager NavigationManager { get; init; } = null!;

[Inject]
private ILogger<Assistants> Logger { get; init; } = null!;

protected override async Task OnInitializedAsync()
{
Expand Down Expand Up @@ -81,6 +88,50 @@ private void UpsertAuditCard(PluginAssistantAudit audit)
audits.Add(audit);
}

private async Task StartAssistantPluginAsync(PluginAssistants assistantPlugin)
{
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
if (!securityState.CanStartAssistant)
return;

if (!assistantPlugin.StartsChatDirectly)
{
this.NavigationManager.NavigateTo($"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}");
return;
}

var chatThread = await this.TryCreateDirectChatThreadAsync(assistantPlugin);
if (chatThread is null)
return;

MessageBus.INSTANCE.DeferMessage(this, Event.SEND_TO_CHAT, chatThread);
this.NavigationManager.NavigateTo(Routes.CHAT);
}

private async Task<ChatThread?> TryCreateDirectChatThreadAsync(PluginAssistants assistantPlugin)
{
var workspaceId = await WorkspaceBehaviour.ResolveOrCreateWorkspaceIdByNameAsync(assistantPlugin.LaunchWorkspaceName);
if (workspaceId == Guid.Empty)
{
this.Logger.LogWarning("Assistant plugin '{PluginName}' could not resolve or create workspace '{WorkspaceName}'.", assistantPlugin.Name, assistantPlugin.LaunchWorkspaceName);
return null;
}

return new ChatThread
{
IncludeDateTime = true,
SelectedProvider = string.Empty,
SelectedProfile = string.Empty,
SelectedChatTemplate = string.Empty,
SystemPrompt = SystemPrompts.DEFAULT,
WorkspaceId = workspaceId,
ChatId = Guid.NewGuid(),
Name = assistantPlugin.AssistantTitle,
DataSourceOptions = this.SettingsManager.ConfigurationData.Chat.PreselectedDataSourceOptions.CreateCopy(),
Blocks = [],
};
}

protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
if (triggeredEvent is Event.PLUGINS_RELOADED)
Expand Down
28 changes: 28 additions & 0 deletions app/MindWork AI Studio/Plugins/assistants/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ Each assistant plugin lives in its own directory under the assistants plugin roo

## Structure
- `ASSISTANT` is the root table. It must contain `Title`, `Description`, `SystemPrompt`, `SubmitText`, `AllowProfiles`, and the nested `UI` definition.
- `ASSISTANT` may optionally define direct-launch metadata for assistant tiles:
- `LaunchBehavior = "OPEN_WORKSPACE_CHAT_BY_NAME"`
- `WorkspaceName = "<target workspace name>"`
- `UI.Type` is always `"FORM"` and `UI.Children` is a list of component tables.
- Each component table declares `Type`, an optional `Children` array, and a `Props` table that feeds the component’s parameters.

Expand All @@ -92,6 +95,8 @@ ASSISTANT = {
["SystemPrompt"] = "",
["SubmitText"] = "",
["AllowProfiles"] = true,
["LaunchBehavior"] = "OPEN_WORKSPACE_CHAT_BY_NAME",
["WorkspaceName"] = "",
["UI"] = {
["Type"] = "FORM",
["Children"] = {
Expand All @@ -101,6 +106,29 @@ ASSISTANT = {
}
```

## Direct Launch to Workspace Chat
Assistant plugins can optionally skip the normal assistant page and open a chat directly from the tile.

```lua
ASSISTANT = {
["Title"] = "Open Chat",
["Description"] = "Open a new chat in the XXX workspace.",
["SystemPrompt"] = "",
["SubmitText"] = "Start",
["AllowProfiles"] = true,
["LaunchBehavior"] = "OPEN_WORKSPACE_CHAT_BY_NAME",
["WorkspaceName"] = "XXX",
["UI"] = {
["Type"] = "FORM",
["Children"] = {}
}
}
```

- `WorkspaceName` is resolved case-insensitively after trimming.
- If the workspace does not exist yet, AI Studio creates it automatically.
- The opened chat uses the normal default chat settings of AI Studio.


#### Supported types (matching the Blazor UI components):

Expand Down
2 changes: 2 additions & 0 deletions app/MindWork AI Studio/Plugins/assistants/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ ASSISTANT = {
["SystemPrompt"] = "<prompt that fundamentally changes behaviour, personality and task focus of your assistant. Invisible to the user>", -- required
["SubmitText"] = "<label for submit button>", -- required
["AllowProfiles"] = true, -- if true, allows AiStudios profiles; required
["LaunchBehavior"] = "<NONE|OPEN_WORKSPACE_CHAT_BY_NAME>", -- optional; when set to OPEN_WORKSPACE_CHAT_BY_NAME the tile opens a chat directly
["WorkspaceName"] = "<name of the workspace to open or create>", -- optional; required for OPEN_WORKSPACE_CHAT_BY_NAME
["UI"] = {
["Type"] = "FORM",
["Children"] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7518,6 +7518,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANT
-- Button
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANTCOMPONENTTYPEEXTENSIONS::T864557713"] = "Schaltfläche"

-- The ASSISTANT table contains an invalid LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T109828905"] = "Die Tabelle ASSISTANT enthält einen ungültigen Wert für LaunchBehavior."

-- The ASSISTANT table contains an unsupported LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1194373781"] = "Die ASSISTANT-Tabelle enthält einen nicht unterstützten LaunchBehavior-Wert."

-- Failed to parse the UI render tree from the ASSISTANT lua table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1318499252"] = "Der UI-Render-Baum konnte nicht aus der ASSISTANT-Lua-Tabelle geparst werden."

Expand All @@ -7533,12 +7539,18 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T2
-- The ASSISTANT lua table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3017816936"] = "Die Lua-Tabelle **ASSISTANT** existiert nicht oder ist keine gültige Tabelle."

-- The ASSISTANT table contains an empty WorkspaceName for LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3233001282"] = "Die ASSISTANT-Tabelle enthält einen leeren Arbeitsbereichsnamen für das LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'."

-- The provided ASSISTANT lua table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3402798667"] = "Die bereitgestellte ASSISTANT-Lua-Tabelle enthält keine gültige Systemaufforderung."

-- The ASSISTANT table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3723171842"] = "Die Tabelle **ASSISTANT** enthält keine gültige Systemanweisung."

-- The ASSISTANT table contains the LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME' but no valid WorkspaceName.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T4215554842"] = "Die ASSISTANT-Tabelle enthält das LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME', aber keinen gültigen WorkspaceNamen."

-- ASSISTANT.BuildPrompt exists but is not a Lua function or has invalid syntax.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T683382975"] = "`ASSISTANT.BuildPrompt` ist vorhanden, aber keine Lua-Funktion oder hat eine ungültige Syntax."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7518,6 +7518,12 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANT
-- Button
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANTCOMPONENTTYPEEXTENSIONS::T864557713"] = "Button"

-- The ASSISTANT table contains an invalid LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T109828905"] = "The ASSISTANT table contains an invalid LaunchBehavior value."

-- The ASSISTANT table contains an unsupported LaunchBehavior value.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1194373781"] = "The ASSISTANT table contains an unsupported LaunchBehavior value."

-- Failed to parse the UI render tree from the ASSISTANT lua table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T1318499252"] = "Failed to parse the UI render tree from the ASSISTANT lua table."

Expand All @@ -7533,12 +7539,18 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T2
-- The ASSISTANT lua table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3017816936"] = "The ASSISTANT lua table does not exist or is not a valid table."

-- The ASSISTANT table contains an empty WorkspaceName for LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3233001282"] = "The ASSISTANT table contains an empty WorkspaceName for LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME'."

-- The provided ASSISTANT lua table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3402798667"] = "The provided ASSISTANT lua table does not contain a valid system prompt."

-- The ASSISTANT table does not contain a valid system prompt.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T3723171842"] = "The ASSISTANT table does not contain a valid system prompt."

-- The ASSISTANT table contains the LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME' but no valid WorkspaceName.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T4215554842"] = "The ASSISTANT table contains the LaunchBehavior 'OPEN_WORKSPACE_CHAT_BY_NAME' but no valid WorkspaceName."

-- ASSISTANT.BuildPrompt exists but is not a Lua function or has invalid syntax.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::PLUGINASSISTANTS::T683382975"] = "ASSISTANT.BuildPrompt exists but is not a Lua function or has invalid syntax."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ public DataAssistantPluginAudit() : this(null)
/// <summary>
/// If true, the security audit will be hidden from the user and done in the background
/// </summary>
public bool AutomaticallyAuditAssistants { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AutomaticallyAuditAssistants, false);
public bool AutomaticallyAuditAssistants { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AutomaticallyAuditAssistants, true);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace AIStudio.Tools.PluginSystem.Assistants;

public enum AssistantPluginLaunchBehavior
{
NONE,
OPEN_WORKSPACE_CHAT_BY_NAME,
}
Loading