mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-03-29 13:51:37 +00:00
Merge branch 'main' into improve-enterprise-config
This commit is contained in:
commit
35305c168f
195
.github/workflows/build-and-release.yml
vendored
195
.github/workflows/build-and-release.yml
vendored
@ -5,15 +5,140 @@ on:
|
||||
- main
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- labeled
|
||||
- synchronize
|
||||
- reopened
|
||||
|
||||
env:
|
||||
RETENTION_INTERMEDIATE_ASSETS: 1
|
||||
RETENTION_RELEASE_ASSETS: 30
|
||||
|
||||
jobs:
|
||||
determine_run_mode:
|
||||
name: Determine run mode
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
is_release: ${{ steps.determine.outputs.is_release }}
|
||||
is_main_push: ${{ steps.determine.outputs.is_main_push }}
|
||||
is_labeled_pr: ${{ steps.determine.outputs.is_labeled_pr }}
|
||||
is_pr_build: ${{ steps.determine.outputs.is_pr_build }}
|
||||
is_internal_pr: ${{ steps.determine.outputs.is_internal_pr }}
|
||||
build_enabled: ${{ steps.determine.outputs.build_enabled }}
|
||||
artifact_retention_days: ${{ steps.determine.outputs.artifact_retention_days }}
|
||||
skip_reason: ${{ steps.determine.outputs.skip_reason }}
|
||||
|
||||
steps:
|
||||
- name: Determine run mode
|
||||
id: determine
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REF: ${{ github.ref }}
|
||||
PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ' ') }}
|
||||
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
is_release=false
|
||||
is_main_push=false
|
||||
is_labeled_pr=false
|
||||
is_pr_build=false
|
||||
is_internal_pr=false
|
||||
build_enabled=false
|
||||
artifact_retention_days=0
|
||||
skip_reason="Build disabled: event did not match main push, release tag, or labeled internal PR."
|
||||
|
||||
if [[ "$EVENT_NAME" == "pull_request" && "$PR_HEAD_REPO" == "$REPOSITORY" ]]; then
|
||||
is_internal_pr=true
|
||||
fi
|
||||
|
||||
if [[ "$REF" == refs/tags/v* ]]; then
|
||||
is_release=true
|
||||
build_enabled=true
|
||||
artifact_retention_days=${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
skip_reason=""
|
||||
elif [[ "$EVENT_NAME" == "push" && "$REF" == "refs/heads/main" ]]; then
|
||||
is_main_push=true
|
||||
build_enabled=true
|
||||
artifact_retention_days=7
|
||||
skip_reason=""
|
||||
elif [[ "$EVENT_NAME" == "pull_request" && " $PR_LABELS " == *" run-pipeline "* ]]; then
|
||||
is_labeled_pr=true
|
||||
is_pr_build=true
|
||||
build_enabled=true
|
||||
artifact_retention_days=3
|
||||
skip_reason=""
|
||||
elif [[ "$EVENT_NAME" == "pull_request" && " $PR_LABELS " != *" run-pipeline "* ]]; then
|
||||
skip_reason="Build disabled: PR does not have the required 'run-pipeline' label."
|
||||
fi
|
||||
|
||||
echo "is_release=${is_release}" >> "$GITHUB_OUTPUT"
|
||||
echo "is_main_push=${is_main_push}" >> "$GITHUB_OUTPUT"
|
||||
echo "is_labeled_pr=${is_labeled_pr}" >> "$GITHUB_OUTPUT"
|
||||
echo "is_pr_build=${is_pr_build}" >> "$GITHUB_OUTPUT"
|
||||
echo "is_internal_pr=${is_internal_pr}" >> "$GITHUB_OUTPUT"
|
||||
echo "build_enabled=${build_enabled}" >> "$GITHUB_OUTPUT"
|
||||
echo "artifact_retention_days=${artifact_retention_days}" >> "$GITHUB_OUTPUT"
|
||||
echo "skip_reason=${skip_reason}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Log run mode
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REF: ${{ github.ref }}
|
||||
PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ', ') }}
|
||||
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
IS_RELEASE: ${{ steps.determine.outputs.is_release }}
|
||||
IS_MAIN_PUSH: ${{ steps.determine.outputs.is_main_push }}
|
||||
IS_LABELED_PR: ${{ steps.determine.outputs.is_labeled_pr }}
|
||||
IS_PR_BUILD: ${{ steps.determine.outputs.is_pr_build }}
|
||||
IS_INTERNAL_PR: ${{ steps.determine.outputs.is_internal_pr }}
|
||||
BUILD_ENABLED: ${{ steps.determine.outputs.build_enabled }}
|
||||
ARTIFACT_RETENTION_DAYS: ${{ steps.determine.outputs.artifact_retention_days }}
|
||||
SKIP_REASON: ${{ steps.determine.outputs.skip_reason }}
|
||||
run: |
|
||||
echo "event_name: ${EVENT_NAME}"
|
||||
echo "ref: ${REF}"
|
||||
echo "repository: ${REPOSITORY}"
|
||||
echo "pr_head_repo: ${PR_HEAD_REPO}"
|
||||
echo "pr_labels: ${PR_LABELS}"
|
||||
echo "is_release: ${IS_RELEASE}"
|
||||
echo "is_main_push: ${IS_MAIN_PUSH}"
|
||||
echo "is_labeled_pr: ${IS_LABELED_PR}"
|
||||
echo "is_pr_build: ${IS_PR_BUILD}"
|
||||
echo "is_internal_pr: ${IS_INTERNAL_PR}"
|
||||
echo "build_enabled: ${BUILD_ENABLED}"
|
||||
echo "artifact_retention_days: ${ARTIFACT_RETENTION_DAYS}"
|
||||
echo "skip_reason: ${SKIP_REASON}"
|
||||
|
||||
{
|
||||
echo "### Run Mode"
|
||||
echo ""
|
||||
echo "| Key | Value |"
|
||||
echo "| --- | --- |"
|
||||
echo "| event_name | ${EVENT_NAME} |"
|
||||
echo "| ref | ${REF} |"
|
||||
echo "| repository | ${REPOSITORY} |"
|
||||
echo "| pr_head_repo | ${PR_HEAD_REPO} |"
|
||||
echo "| pr_labels | ${PR_LABELS} |"
|
||||
echo "| is_release | ${IS_RELEASE} |"
|
||||
echo "| is_main_push | ${IS_MAIN_PUSH} |"
|
||||
echo "| is_labeled_pr | ${IS_LABELED_PR} |"
|
||||
echo "| is_pr_build | ${IS_PR_BUILD} |"
|
||||
echo "| is_internal_pr | ${IS_INTERNAL_PR} |"
|
||||
echo "| build_enabled | ${BUILD_ENABLED} |"
|
||||
echo "| artifact_retention_days | ${ARTIFACT_RETENTION_DAYS} |"
|
||||
echo "| skip_reason | ${SKIP_REASON} |"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
read_metadata:
|
||||
name: Read metadata
|
||||
runs-on: ubuntu-latest
|
||||
needs: determine_run_mode
|
||||
if: needs.determine_run_mode.outputs.build_enabled == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
@ -62,6 +187,7 @@ jobs:
|
||||
|
||||
- name: Read changelog
|
||||
id: read_changelog
|
||||
if: needs.determine_run_mode.outputs.is_release == 'true'
|
||||
run: |
|
||||
# Ensure, that the matching changelog file for the current version exists:
|
||||
if [ ! -f "app/MindWork AI Studio/wwwroot/changelog/${FORMATTED_VERSION}.md" ]; then
|
||||
@ -81,7 +207,8 @@ jobs:
|
||||
|
||||
build_main:
|
||||
name: Build app (${{ matrix.dotnet_runtime }})
|
||||
needs: read_metadata
|
||||
needs: [determine_run_mode, read_metadata]
|
||||
if: needs.determine_run_mode.outputs.build_enabled == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@ -93,37 +220,43 @@ jobs:
|
||||
rust_target: 'aarch64-apple-darwin'
|
||||
dotnet_runtime: 'osx-arm64'
|
||||
dotnet_name_postfix: '-aarch64-apple-darwin'
|
||||
tauri_bundle: 'dmg updater'
|
||||
tauri_bundle: 'dmg,updater'
|
||||
tauri_bundle_pr: 'dmg'
|
||||
|
||||
- platform: 'macos-latest' # for Intel-based macOS
|
||||
rust_target: 'x86_64-apple-darwin'
|
||||
dotnet_runtime: 'osx-x64'
|
||||
dotnet_name_postfix: '-x86_64-apple-darwin'
|
||||
tauri_bundle: 'dmg updater'
|
||||
tauri_bundle: 'dmg,updater'
|
||||
tauri_bundle_pr: 'dmg'
|
||||
|
||||
- platform: 'ubuntu-22.04' # for x86-based Linux
|
||||
rust_target: 'x86_64-unknown-linux-gnu'
|
||||
dotnet_runtime: 'linux-x64'
|
||||
dotnet_name_postfix: '-x86_64-unknown-linux-gnu'
|
||||
tauri_bundle: 'appimage deb updater'
|
||||
tauri_bundle: 'appimage,deb,updater'
|
||||
tauri_bundle_pr: 'appimage,deb'
|
||||
|
||||
- platform: 'ubuntu-22.04-arm' # for ARM-based Linux
|
||||
rust_target: 'aarch64-unknown-linux-gnu'
|
||||
dotnet_runtime: 'linux-arm64'
|
||||
dotnet_name_postfix: '-aarch64-unknown-linux-gnu'
|
||||
tauri_bundle: 'appimage deb updater'
|
||||
tauri_bundle: 'appimage,deb,updater'
|
||||
tauri_bundle_pr: 'appimage,deb'
|
||||
|
||||
- platform: 'windows-latest' # for x86-based Windows
|
||||
rust_target: 'x86_64-pc-windows-msvc'
|
||||
dotnet_runtime: 'win-x64'
|
||||
dotnet_name_postfix: '-x86_64-pc-windows-msvc.exe'
|
||||
tauri_bundle: 'nsis updater'
|
||||
tauri_bundle: 'nsis,updater'
|
||||
tauri_bundle_pr: 'nsis'
|
||||
|
||||
- platform: 'windows-latest' # for ARM-based Windows
|
||||
rust_target: 'aarch64-pc-windows-msvc'
|
||||
dotnet_runtime: 'win-arm64'
|
||||
dotnet_name_postfix: '-aarch64-pc-windows-msvc.exe'
|
||||
tauri_bundle: 'nsis updater'
|
||||
tauri_bundle: 'nsis,updater'
|
||||
tauri_bundle_pr: 'nsis'
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
@ -632,10 +765,18 @@ jobs:
|
||||
PRIVATE_PUBLISH_KEY: ${{ secrets.PRIVATE_PUBLISH_KEY }}
|
||||
PRIVATE_PUBLISH_KEY_PASSWORD: ${{ secrets.PRIVATE_PUBLISH_KEY_PASSWORD }}
|
||||
run: |
|
||||
bundles="${{ matrix.tauri_bundle }}"
|
||||
|
||||
if [ "${{ needs.determine_run_mode.outputs.is_pr_build }}" = "true" ]; then
|
||||
echo "Running PR test build without updater bundle signing"
|
||||
bundles="${{ matrix.tauri_bundle_pr }}"
|
||||
else
|
||||
export TAURI_PRIVATE_KEY="$PRIVATE_PUBLISH_KEY"
|
||||
export TAURI_KEY_PASSWORD="$PRIVATE_PUBLISH_KEY_PASSWORD"
|
||||
fi
|
||||
|
||||
cd runtime
|
||||
export TAURI_PRIVATE_KEY="$PRIVATE_PUBLISH_KEY"
|
||||
export TAURI_KEY_PASSWORD="$PRIVATE_PUBLISH_KEY_PASSWORD"
|
||||
cargo tauri build --target ${{ matrix.rust_target }} --bundles ${{ matrix.tauri_bundle }}
|
||||
cargo tauri build --target ${{ matrix.rust_target }} --bundles "$bundles"
|
||||
|
||||
- name: Build Tauri project (Windows)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
@ -643,13 +784,21 @@ jobs:
|
||||
PRIVATE_PUBLISH_KEY: ${{ secrets.PRIVATE_PUBLISH_KEY }}
|
||||
PRIVATE_PUBLISH_KEY_PASSWORD: ${{ secrets.PRIVATE_PUBLISH_KEY_PASSWORD }}
|
||||
run: |
|
||||
$bundles = "${{ matrix.tauri_bundle }}"
|
||||
|
||||
if ("${{ needs.determine_run_mode.outputs.is_pr_build }}" -eq "true") {
|
||||
Write-Output "Running PR test build without updater bundle signing"
|
||||
$bundles = "${{ matrix.tauri_bundle_pr }}"
|
||||
} else {
|
||||
$env:TAURI_PRIVATE_KEY="$env:PRIVATE_PUBLISH_KEY"
|
||||
$env:TAURI_KEY_PASSWORD="$env:PRIVATE_PUBLISH_KEY_PASSWORD"
|
||||
}
|
||||
|
||||
cd runtime
|
||||
$env:TAURI_PRIVATE_KEY="$env:PRIVATE_PUBLISH_KEY"
|
||||
$env:TAURI_KEY_PASSWORD="$env:PRIVATE_PUBLISH_KEY_PASSWORD"
|
||||
cargo tauri build --target ${{ matrix.rust_target }} --bundles ${{ matrix.tauri_bundle }}
|
||||
cargo tauri build --target ${{ matrix.rust_target }} --bundles $bundles
|
||||
|
||||
- name: Upload artifact (macOS)
|
||||
if: startsWith(matrix.platform, 'macos') && startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(matrix.platform, 'macos')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MindWork AI Studio (macOS ${{ matrix.dotnet_runtime }})
|
||||
@ -657,10 +806,10 @@ jobs:
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/dmg/MindWork AI Studio_*.dmg
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/macos/MindWork AI Studio.app.tar.gz*
|
||||
if-no-files-found: error
|
||||
retention-days: ${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
retention-days: ${{ fromJSON(needs.determine_run_mode.outputs.artifact_retention_days) }}
|
||||
|
||||
- name: Upload artifact (Windows - MSI)
|
||||
if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'msi') && startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'msi')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MindWork AI Studio (Windows - MSI ${{ matrix.dotnet_runtime }})
|
||||
@ -668,10 +817,10 @@ jobs:
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/msi/MindWork AI Studio_*.msi
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/msi/MindWork AI Studio*msi.zip*
|
||||
if-no-files-found: error
|
||||
retention-days: ${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
retention-days: ${{ fromJSON(needs.determine_run_mode.outputs.artifact_retention_days) }}
|
||||
|
||||
- name: Upload artifact (Windows - NSIS)
|
||||
if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'nsis') && startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'nsis')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MindWork AI Studio (Windows - NSIS ${{ matrix.dotnet_runtime }})
|
||||
@ -679,20 +828,20 @@ jobs:
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/nsis/MindWork AI Studio_*.exe
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/nsis/MindWork AI Studio*nsis.zip*
|
||||
if-no-files-found: error
|
||||
retention-days: ${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
retention-days: ${{ fromJSON(needs.determine_run_mode.outputs.artifact_retention_days) }}
|
||||
|
||||
- name: Upload artifact (Linux - Debian Package)
|
||||
if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'deb') && startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'deb')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MindWork AI Studio (Linux - deb ${{ matrix.dotnet_runtime }})
|
||||
path: |
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/deb/mind-work-ai-studio_*.deb
|
||||
if-no-files-found: error
|
||||
retention-days: ${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
retention-days: ${{ fromJSON(needs.determine_run_mode.outputs.artifact_retention_days) }}
|
||||
|
||||
- name: Upload artifact (Linux - AppImage)
|
||||
if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'appimage') && startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'appimage')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MindWork AI Studio (Linux - AppImage ${{ matrix.dotnet_runtime }})
|
||||
@ -700,7 +849,7 @@ jobs:
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/appimage/mind-work-ai-studio_*.AppImage
|
||||
runtime/target/${{ matrix.rust_target }}/release/bundle/appimage/mind-work-ai-studio*AppImage.tar.gz*
|
||||
if-no-files-found: error
|
||||
retention-days: ${{ env.RETENTION_INTERMEDIATE_ASSETS }}
|
||||
retention-days: ${{ fromJSON(needs.determine_run_mode.outputs.artifact_retention_days) }}
|
||||
|
||||
create_release:
|
||||
name: Prepare & create release
|
||||
|
||||
@ -100,7 +100,7 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
||||
Event.PLUGINS_RELOADED,
|
||||
};
|
||||
|
||||
this.MessageBus.ApplyFilters(this, filterComponents, eventsList.ToArray());
|
||||
this.MessageBus.ApplyFilters(this, filterComponents, eventsList.ToHashSet());
|
||||
}
|
||||
|
||||
protected virtual void DisposeResources()
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
@attribute [Route(Routes.ABOUT)]
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@using AIStudio.Tools.Services
|
||||
@inherits MSGComponentBase
|
||||
|
||||
<div class="inner-scrolling-context">
|
||||
@ -85,7 +84,7 @@
|
||||
@T("AI Studio runs with an enterprise configuration and configuration servers. The configuration plugins are not yet available.")
|
||||
</MudText>
|
||||
<MudCollapse Expanded="@this.showEnterpriseConfigDetails">
|
||||
@foreach (var env in EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.Where(e => e.IsActive))
|
||||
@foreach (var env in this.enterpriseEnvironments.Where(e => e.IsActive))
|
||||
{
|
||||
<ConfigPluginInfoCard HeaderIcon="@Icons.Material.Filled.HourglassBottom"
|
||||
HeaderText="@T("Waiting for the configuration plugin...")"
|
||||
@ -123,7 +122,7 @@
|
||||
</MudText>
|
||||
}
|
||||
<MudCollapse Expanded="@this.showEnterpriseConfigDetails">
|
||||
@foreach (var env in EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.Where(e => e.IsActive))
|
||||
@foreach (var env in this.enterpriseEnvironments.Where(e => e.IsActive))
|
||||
{
|
||||
var matchingPlugin = this.FindManagedConfigurationPlugin(env.ConfigurationId);
|
||||
if (matchingPlugin is null)
|
||||
|
||||
@ -75,14 +75,16 @@ public partial class Information : MSGComponentBase
|
||||
.Where(x => x.Type is PluginType.CONFIGURATION)
|
||||
.OfType<IAvailablePlugin>()
|
||||
.ToList();
|
||||
|
||||
private List<EnterpriseEnvironment> enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList();
|
||||
|
||||
private sealed record DatabaseDisplayInfo(string Label, string Value);
|
||||
|
||||
private readonly List<DatabaseDisplayInfo> databaseDisplayInfo = new();
|
||||
|
||||
private static bool HasAnyActiveEnvironment => EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.Any(e => e.IsActive);
|
||||
private bool HasAnyActiveEnvironment => this.enterpriseEnvironments.Any(e => e.IsActive);
|
||||
|
||||
private bool HasAnyLoadedEnterpriseConfigurationPlugin => EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS
|
||||
private bool HasAnyLoadedEnterpriseConfigurationPlugin => this.enterpriseEnvironments
|
||||
.Where(e => e.IsActive)
|
||||
.Any(env => this.FindManagedConfigurationPlugin(env.ConfigurationId) is not null);
|
||||
|
||||
@ -94,7 +96,7 @@ public partial class Information : MSGComponentBase
|
||||
{
|
||||
get
|
||||
{
|
||||
return HasAnyActiveEnvironment switch
|
||||
return this.HasAnyActiveEnvironment switch
|
||||
{
|
||||
// Case 1: No enterprise config and no plugin - no details available
|
||||
false when this.configPlugins.Count == 0 => false,
|
||||
@ -115,7 +117,10 @@ public partial class Information : MSGComponentBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.ApplyFilters([], [ Event.ENTERPRISE_ENVIRONMENTS_CHANGED ]);
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
this.RefreshEnterpriseConfigurationState();
|
||||
|
||||
this.osLanguage = await this.RustService.ReadUserLanguage();
|
||||
this.logPaths = await this.RustService.GetLogPaths();
|
||||
@ -139,10 +144,8 @@ public partial class Information : MSGComponentBase
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.PLUGINS_RELOADED:
|
||||
this.configPlugins = PluginFactory.AvailablePlugins
|
||||
.Where(x => x.Type is PluginType.CONFIGURATION)
|
||||
.OfType<IAvailablePlugin>()
|
||||
.ToList();
|
||||
case Event.ENTERPRISE_ENVIRONMENTS_CHANGED:
|
||||
this.RefreshEnterpriseConfigurationState();
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
break;
|
||||
}
|
||||
@ -152,6 +155,16 @@ public partial class Information : MSGComponentBase
|
||||
|
||||
#endregion
|
||||
|
||||
private void RefreshEnterpriseConfigurationState()
|
||||
{
|
||||
this.configPlugins = PluginFactory.AvailablePlugins
|
||||
.Where(x => x.Type is PluginType.CONFIGURATION)
|
||||
.OfType<IAvailablePlugin>()
|
||||
.ToList();
|
||||
|
||||
this.enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList();
|
||||
}
|
||||
|
||||
private async Task DeterminePandocVersion()
|
||||
{
|
||||
this.pandocInstallation = await Pandoc.CheckAvailabilityAsync(this.RustService, false);
|
||||
|
||||
@ -11,6 +11,7 @@ public enum Event
|
||||
STARTUP_PLUGIN_SYSTEM,
|
||||
STARTUP_COMPLETED,
|
||||
STARTUP_ENTERPRISE_ENVIRONMENT,
|
||||
ENTERPRISE_ENVIRONMENTS_CHANGED,
|
||||
PLUGINS_RELOADED,
|
||||
SHOW_ERROR,
|
||||
SHOW_WARNING,
|
||||
|
||||
@ -33,10 +33,10 @@ public sealed class MessageBus
|
||||
/// <param name="receiver">That's you, the receiver.</param>
|
||||
/// <param name="filterComponents">A list of components for which you want to receive messages. Use an empty list to receive messages from all components.</param>
|
||||
/// <param name="events">A list of events for which you want to receive messages.</param>
|
||||
public void ApplyFilters(IMessageBusReceiver receiver, ComponentBase[] filterComponents, Event[] events)
|
||||
public void ApplyFilters(IMessageBusReceiver receiver, ComponentBase[] filterComponents, HashSet<Event> events)
|
||||
{
|
||||
this.componentFilters[receiver] = filterComponents;
|
||||
this.componentEvents[receiver] = events;
|
||||
this.componentEvents[receiver] = events.ToArray();
|
||||
}
|
||||
|
||||
public void RegisterComponent(IMessageBusReceiver receiver)
|
||||
|
||||
@ -11,6 +11,6 @@ public static class MessageBusExtensions
|
||||
|
||||
public static void ApplyFilters(this IMessageBusReceiver component, ComponentBase[] components, Event[] events)
|
||||
{
|
||||
MessageBus.INSTANCE.ApplyFilters(component, components, events);
|
||||
MessageBus.INSTANCE.ApplyFilters(component, components, events.ToHashSet());
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,8 @@ public sealed class EnterpriseEnvironmentService(ILogger<EnterpriseEnvironmentSe
|
||||
|
||||
public static bool HasValidEnterpriseSnapshot { get; private set; }
|
||||
|
||||
private readonly record struct EnterpriseEnvironmentSnapshot(Guid ConfigurationId, string ConfigurationServerUrl, string? ETag);
|
||||
|
||||
#if DEBUG
|
||||
private static readonly TimeSpan CHECK_INTERVAL = TimeSpan.FromMinutes(6);
|
||||
#else
|
||||
@ -36,6 +38,7 @@ public sealed class EnterpriseEnvironmentService(ILogger<EnterpriseEnvironmentSe
|
||||
{
|
||||
logger.LogInformation("Start updating of the enterprise environment.");
|
||||
HasValidEnterpriseSnapshot = false;
|
||||
var previousSnapshot = BuildNormalizedSnapshot(CURRENT_ENVIRONMENTS);
|
||||
|
||||
//
|
||||
// Step 1: Fetch all active configurations.
|
||||
@ -165,12 +168,33 @@ public sealed class EnterpriseEnvironmentService(ILogger<EnterpriseEnvironmentSe
|
||||
if (effectiveEnvironments.Count == 0)
|
||||
logger.LogInformation("AI Studio runs without any enterprise configurations.");
|
||||
|
||||
var effectiveSnapshot = BuildNormalizedSnapshot(effectiveEnvironments);
|
||||
CURRENT_ENVIRONMENTS = effectiveEnvironments;
|
||||
HasValidEnterpriseSnapshot = true;
|
||||
|
||||
if (!previousSnapshot.SequenceEqual(effectiveSnapshot))
|
||||
await MessageBus.INSTANCE.SendMessage<bool>(null, Event.ENTERPRISE_ENVIRONMENTS_CHANGED);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, "An error occurred while updating the enterprise environment.");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<EnterpriseEnvironmentSnapshot> BuildNormalizedSnapshot(IEnumerable<EnterpriseEnvironment> environments)
|
||||
{
|
||||
return environments
|
||||
.Where(environment => environment.IsActive)
|
||||
.Select(environment => new EnterpriseEnvironmentSnapshot(
|
||||
environment.ConfigurationId,
|
||||
NormalizeServerUrl(environment.ConfigurationServerUrl),
|
||||
environment.ETag?.ToString()))
|
||||
.OrderBy(environment => environment.ConfigurationId)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static string NormalizeServerUrl(string serverUrl)
|
||||
{
|
||||
return serverUrl.Trim().TrimEnd('/');
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@
|
||||
- Improved the profile selection for assistants and the chat. You can now explicitly choose between the app default profile, no profile, or a specific profile.
|
||||
- Improved the performance by caching the OS language detection and requesting the user language only once per app start.
|
||||
- Improved the chat performance by reducing unnecessary UI updates, making chats smoother and more responsive, especially in longer conversations.
|
||||
- Improved the information page so enterprise configuration details now refresh live when your organization's configuration changes.
|
||||
- Improved the workspace loading experience: when opening the chat for the first time, your workspaces now appear faster and load step by step in the background, with placeholder rows so the app feels responsive right away.
|
||||
- Improved the reliability of the global voice recording shortcut so it stays available more consistently.
|
||||
- Improved the user-language logging by limiting language detection logs to a single entry per app start.
|
||||
|
||||
17
runtime/Cargo.lock
generated
17
runtime/Cargo.lock
generated
@ -238,7 +238,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"untrusted 0.7.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@ -2776,7 +2775,6 @@ dependencies = [
|
||||
"aes",
|
||||
"arboard",
|
||||
"async-stream",
|
||||
"aws-lc-rs",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"calamine",
|
||||
@ -2798,7 +2796,6 @@ dependencies = [
|
||||
"rcgen",
|
||||
"reqwest 0.13.2",
|
||||
"rocket",
|
||||
"rustls-webpki 0.103.10",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
@ -4172,7 +4169,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.2.15",
|
||||
"libc",
|
||||
"untrusted 0.9.0",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@ -4408,7 +4405,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted 0.9.0",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4420,7 +4417,7 @@ dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted 0.9.0",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4472,7 +4469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted 0.9.0",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5785,12 +5782,6 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
||||
@ -45,9 +45,7 @@ sysinfo = "0.38.4"
|
||||
# Fixes security vulnerability downstream, where the upstream is not fixed yet:
|
||||
time = "0.3.47" # -> Rocket
|
||||
bytes = "1.11.1" # -> almost every dependency
|
||||
aws-lc-rs = "1.16.2" # -> reqwest
|
||||
tar = "0.4.45" # -> Tauri v1
|
||||
rustls-webpki = "0.103.10" # -> tokio, reqwest
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
# See issue https://github.com/tauri-apps/tauri/issues/4470
|
||||
|
||||
Loading…
Reference in New Issue
Block a user