Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Events #81

Merged
merged 7 commits into from
Jan 14, 2025
Merged
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
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PackageProjectUrl>https://github.com/squidex/squidex</PackageProjectUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Version>6.23.0</Version>
<Version>6.24.0</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
Expand Down
39 changes: 38 additions & 1 deletion Squidex.Libs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.AI.Mongo", "ai\Squi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.AI.EntityFramework", "ai\Squidex.AI.EntityFramework\Squidex.AI.EntityFramework.csproj", "{F15850C7-D623-4CBE-ABE0-07D9822B9326}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Messaging.EntityFramework", "messaging\Squidex.Messaging.EntityFramework\Squidex.Messaging.EntityFramework.csproj", "{F653DF48-6ED7-45A0-B630-88E783202A64}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Messaging.EntityFramework", "messaging\Squidex.Messaging.EntityFramework\Squidex.Messaging.EntityFramework.csproj", "{F653DF48-6ED7-45A0-B630-88E783202A64}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "events", "events", "{94285572-6875-4A9C-AFC4-987758DC9088}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Events", "events\Squidex.Events\Squidex.Events.csproj", "{CD62FC9A-42CC-45C8-B3FC-CB72694AE037}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Events.EntityFramework", "events\Squidex.Events.EntityFramework\Squidex.Events.EntityFramework.csproj", "{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Events.Tests", "events\Squidex.Events.Tests\Squidex.Events.Tests.csproj", "{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Events.Mongo", "events\Squidex.Events.Mongo\Squidex.Events.Mongo.csproj", "{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Events.GetEventStore", "events\Squidex.Events.GetEventStore\Squidex.Events.GetEventStore.csproj", "{98156A5E-1B4A-46EF-AA84-019868425D80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -251,6 +263,26 @@ Global
{F653DF48-6ED7-45A0-B630-88E783202A64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F653DF48-6ED7-45A0-B630-88E783202A64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F653DF48-6ED7-45A0-B630-88E783202A64}.Release|Any CPU.Build.0 = Release|Any CPU
{CD62FC9A-42CC-45C8-B3FC-CB72694AE037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD62FC9A-42CC-45C8-B3FC-CB72694AE037}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD62FC9A-42CC-45C8-B3FC-CB72694AE037}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD62FC9A-42CC-45C8-B3FC-CB72694AE037}.Release|Any CPU.Build.0 = Release|Any CPU
{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA}.Release|Any CPU.Build.0 = Release|Any CPU
{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4}.Release|Any CPU.Build.0 = Release|Any CPU
{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0}.Release|Any CPU.Build.0 = Release|Any CPU
{98156A5E-1B4A-46EF-AA84-019868425D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98156A5E-1B4A-46EF-AA84-019868425D80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98156A5E-1B4A-46EF-AA84-019868425D80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98156A5E-1B4A-46EF-AA84-019868425D80}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -294,6 +326,11 @@ Global
{98AE3491-7D34-498B-8A8F-14BDAAF37AD3} = {F18E275B-4805-4DCB-BE31-ACC314FB508E}
{F15850C7-D623-4CBE-ABE0-07D9822B9326} = {F18E275B-4805-4DCB-BE31-ACC314FB508E}
{F653DF48-6ED7-45A0-B630-88E783202A64} = {28B7D0BB-1971-4802-BC40-28297D644B26}
{CD62FC9A-42CC-45C8-B3FC-CB72694AE037} = {94285572-6875-4A9C-AFC4-987758DC9088}
{5F4B51E1-0ADD-4C03-A93A-401BA86D08BA} = {94285572-6875-4A9C-AFC4-987758DC9088}
{1E9B31E9-EA9D-4A82-B207-00E8B275EFD4} = {94285572-6875-4A9C-AFC4-987758DC9088}
{E36DAC0D-8A2D-49AA-B9C4-E74CAB0660B0} = {94285572-6875-4A9C-AFC4-987758DC9088}
{98156A5E-1B4A-46EF-AA84-019868425D80} = {94285572-6875-4A9C-AFC4-987758DC9088}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {060512DD-34DA-4929-A67F-2E473577FBF5}
Expand Down
19 changes: 5 additions & 14 deletions ai/Squidex.AI.EntityFramework/EFChatServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,22 @@
// ==========================================================================

using Microsoft.EntityFrameworkCore;
using Squidex.AI;
using Squidex.AI.Implementation;
using Squidex.AI.Mongo;

namespace Microsoft.Extensions.DependencyInjection;

public static class EFChatServiceExtensions
{
public static IServiceCollection AddEntityFrameworkChatStore<T>(this IServiceCollection services)
public static AIBuilder AddEntityFrameworkChatStore<T>(this AIBuilder builder)
where T : DbContext
{
services.AddSingletonAs<EFChatStore<T>>()
builder.Services.AddSingletonAs<EFChatStore<T>>()
.As<IChatStore>();

services.AddDbContextFactory<T>();
builder.Services.AddDbContextFactory<T>();

return services;
}

public static ModelBuilder AddChatStore(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<EFChatEntity>(b =>
{
b.HasIndex(x => x.LastUpdated);
});

return modelBuilder;
return builder;
}
}
25 changes: 25 additions & 0 deletions ai/Squidex.AI.EntityFramework/EFSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using Squidex.AI.Mongo;

namespace Microsoft.EntityFrameworkCore;

public static class EFSchema
{
public static ModelBuilder AddChatStore(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<EFChatEntity>(b =>
{
b.ToTable("Chats");

b.HasIndex(x => x.LastUpdated);
});

return modelBuilder;
}
}
10 changes: 6 additions & 4 deletions ai/Squidex.AI.Mongo/MongoChatServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
// ==========================================================================

using Microsoft.Extensions.Configuration;
using Squidex.AI;
using Squidex.AI.Implementation;
using Squidex.AI.Mongo;

namespace Microsoft.Extensions.DependencyInjection;

public static class MongoChatServiceExtensions
{
public static IServiceCollection AddMongoChatStore(this IServiceCollection services, IConfiguration config, Action<MongoChatStoreOptions>? configure = null,
public static AIBuilder AddMongoChatStore(this AIBuilder builder, IConfiguration config, Action<MongoChatStoreOptions>? configure = null,
string configPath = "chatBot:mongoDb")
{
services.ConfigureAndValidate(config, configPath, configure);
builder.Services.ConfigureAndValidate(config, configPath, configure);

services.AddSingletonAs<MongoChatStore>()
builder.Services.AddSingletonAs<MongoChatStore>()
.As<IChatStore>();
return services;

return builder;
}
}
3 changes: 3 additions & 0 deletions ai/Squidex.AI.Tests/DallEPipeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Squidex.AI.Implementation.OpenAI;
using Squidex.AI.Utils;
using Squidex.Assets;
using Squidex.Assets.ImageSharp;
using Squidex.Hosting;
using Xunit;

Expand Down Expand Up @@ -41,6 +42,7 @@ public async Task Should_create_article_with_image()
.AddSingleton<IHttpImageEndpoint, ImageEndpoint>()
.AddSingleton<IAssetStore, MemoryAssetStore>()
.AddSingleton<IAssetThumbnailGenerator, ImageSharpThumbnailGenerator>()
.AddAI()
.AddDallE(TestHelpers.Configuration, options =>
{
options.DownloadImage = downloadImage;
Expand All @@ -50,6 +52,7 @@ public async Task Should_create_article_with_image()
options.Seed = 42;
})
.AddAIImagePipe()
.Services
.Configure<ChatOptions>(options =>
{
options.Defaults = new ChatConfiguration
Expand Down
3 changes: 3 additions & 0 deletions ai/Squidex.AI.Tests/DallETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Squidex.AI.Implementation.OpenAI;
using Squidex.AI.Utils;
using Squidex.Assets;
using Squidex.Assets.ImageSharp;
using Squidex.Hosting;
using Xunit;

Expand Down Expand Up @@ -111,6 +112,7 @@ private static void AssertImageFromTool(ChatResult result)
.AddSingleton<IHttpImageEndpoint, ImageEndpoint>()
.AddSingleton<IAssetStore, MemoryAssetStore>()
.AddSingleton<IAssetThumbnailGenerator, ImageSharpThumbnailGenerator>()
.AddAI()
.AddDallE(TestHelpers.Configuration, options =>
{
options.DownloadImage = downloadImage;
Expand All @@ -119,6 +121,7 @@ private static void AssertImageFromTool(ChatResult result)
{
options.Seed = 42;
})
.Services
.Configure<ChatOptions>(options =>
{
options.Defaults = new ChatConfiguration
Expand Down
21 changes: 14 additions & 7 deletions ai/Squidex.AI.Tests/EFChatStoreFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Squidex.AI.Implementation;
using Squidex.AI.Mongo;
using Squidex.Hosting;
using Testcontainers.PostgreSql;
Expand All @@ -19,7 +19,12 @@ namespace Squidex.AI;

public sealed class EFChatStoreFixture : IAsyncLifetime
{
private readonly PostgreSqlContainer postgresSql = new PostgreSqlBuilder().Build();
private readonly PostgreSqlContainer postgresSql =
new PostgreSqlBuilder()
.WithReuse(Debugger.IsAttached)
.WithLabel("reuse-id", "chatstore-postgres")
.Build();

private IServiceProvider services;

public EFChatStore<AppDbContext> Store => services.GetRequiredService<EFChatStore<AppDbContext>>();
Expand Down Expand Up @@ -52,18 +57,20 @@ public async Task InitializeAsync()
{
b.UseNpgsql(postgresSql.GetConnectionString());
})
.AddAI()
.AddEntityFrameworkChatStore<AppDbContext>()
.Services
.BuildServiceProvider();

foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
{
await service.InitializeAsync(default);
}

var factory = services.GetRequiredService<IDbContextFactory<AppDbContext>>();
var context = await factory.CreateDbContextAsync();
var creator = (RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();

await creator.EnsureCreatedAsync();

foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
{
await service.InitializeAsync(default);
}
}
}
14 changes: 10 additions & 4 deletions ai/Squidex.AI.Tests/MongoChatStoreFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
using Squidex.AI.Implementation;
using Squidex.AI.Mongo;
using Squidex.Hosting;
using Testcontainers.MongoDb;
Expand All @@ -18,7 +17,12 @@ namespace Squidex.AI;

public sealed class MongoChatStoreFixture : IAsyncLifetime
{
private readonly MongoDbContainer mongoDb = new MongoDbBuilder().Build();
private readonly MongoDbContainer mongoDb =
new MongoDbBuilder()
.WithReuse(Debugger.IsAttached)
.WithLabel("reuse-id", "chatstore-mongo")
.Build();

private IServiceProvider services;

public MongoChatStore Store => services.GetRequiredService<MongoChatStore>();
Expand All @@ -40,7 +44,9 @@ public async Task InitializeAsync()
services = new ServiceCollection()
.AddSingleton<IMongoClient>(_ => new MongoClient(mongoDb.GetConnectionString()))
.AddSingleton(c => c.GetRequiredService<IMongoClient>().GetDatabase("Test"))
.AddMongoChatStore(new ConfigurationBuilder().Build())
.AddAI()
.AddMongoChatStore(TestHelpers.Configuration)
.Services
.BuildServiceProvider();

foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
Expand Down
2 changes: 2 additions & 0 deletions ai/Squidex.AI.Tests/OpenAIEmbeddingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public async Task Should_calculate_vector()
{
var services =
new ServiceCollection()
.AddAI()
.AddOpenAIEmbeddings(TestHelpers.Configuration)
.Services
.BuildServiceProvider();

var initializables = services.GetRequiredService<IEnumerable<IInitializable>>();
Expand Down
9 changes: 9 additions & 0 deletions ai/Squidex.AI.Tests/OpenAITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public void Should_not_be_configured_if_open_ai_is_not_added()
var sut =
new ServiceCollection()
.AddAI()
.Services
.BuildServiceProvider()
.GetRequiredService<IChatAgent>();

Expand All @@ -34,10 +35,12 @@ public void Should_be_configured_if_open_ai_is_added()
{
var sut =
new ServiceCollection()
.AddAI()
.AddOpenAIChat(TestHelpers.Configuration, options =>
{
options.ApiKey = "test";
})
.Services
.BuildServiceProvider()
.GetRequiredService<IChatAgent>();

Expand All @@ -50,10 +53,12 @@ public async Task Should_throw_exception_on_invalid_configuration()
{
var sut =
new ServiceCollection()
.AddAI()
.AddOpenAIChat(TestHelpers.Configuration, options =>
{
options.Model = "invalid";
})
.Services
.BuildServiceProvider()
.GetRequiredService<IChatAgent>();

Expand All @@ -71,10 +76,12 @@ public async Task Should_throw_exception_on_invalid_configuration_when_streaming
{
var sut =
new ServiceCollection()
.AddAI()
.AddOpenAIChat(TestHelpers.Configuration, options =>
{
options.Model = "invalid";
})
.Services
.BuildServiceProvider()
.GetRequiredService<IChatAgent>();

Expand Down Expand Up @@ -342,12 +349,14 @@ private static async Task UseConversationId(Func<string, IChatAgent, IServicePro
{
var services =
new ServiceCollection()
.AddAI()
.AddTool<MathTool>()
.AddTool<WheatherTool>()
.AddOpenAIChat(TestHelpers.Configuration, options =>
{
options.Seed = 42;
})
.Services
.Configure<ChatOptions>(options =>
{
options.Defaults = new ChatConfiguration
Expand Down
2 changes: 2 additions & 0 deletions ai/Squidex.AI.Tests/PineconeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public async Task Should_answer_question()
{
var services =
new ServiceCollection()
.AddAI()
.AddOpenAIChat(TestHelpers.Configuration, options =>
{
options.Seed = 42;
Expand All @@ -47,6 +48,7 @@ public async Task Should_answer_question()
{
options.ToolDescription = "Answers questions about Squidex.";
})
.Services
.Configure<ChatOptions>(options =>
{
options.Defaults = new ChatConfiguration
Expand Down
Loading
Loading