diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.Designer.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.Designer.cs
new file mode 100644
index 000000000..e6b5bb135
--- /dev/null
+++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.Designer.cs
@@ -0,0 +1,308 @@
+//
+using System;
+using LINGYUN.Abp.MicroService.AIService;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Volo.Abp.EntityFrameworkCore;
+
+#nullable disable
+
+namespace LINGYUN.Abp.MicroService.AIService.Migrations
+{
+ [DbContext(typeof(AIServiceMigrationsDbContext))]
+ [Migration("20260313010418_Add-Workspace-To-Conversation-Record")]
+ partial class AddWorkspaceToConversationRecord
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.PostgreSql)
+ .HasAnnotation("ProductVersion", "10.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("LINGYUN.Abp.AIManagement.Chats.ConversationRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExpiredAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("UpdateAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Workspace")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpAIConversations", (string)null);
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.AIManagement.Chats.TextChatMessageRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Content")
+ .IsRequired()
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)");
+
+ b.Property("ConversationId")
+ .HasColumnType("uuid");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ReplyAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ReplyMessage")
+ .HasColumnType("text");
+
+ b.Property("Role")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.Property("Workspace")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ConversationId");
+
+ b.ToTable("AbpAITextChatMessages", (string)null);
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.AIManagement.Tokens.TokenUsageRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CachedInputTokenCount")
+ .HasColumnType("bigint");
+
+ b.Property("ConversationId")
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("InputTokenCount")
+ .HasColumnType("bigint");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("MessageId")
+ .HasColumnType("uuid");
+
+ b.Property("OutputTokenCount")
+ .HasColumnType("bigint");
+
+ b.Property("ReasoningTokenCount")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("TotalTokenCount")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ConversationId");
+
+ b.ToTable("AbpAITokenUsages", (string)null);
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.AIManagement.Workspaces.WorkspaceDefinitionRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ApiBaseUrl")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.Property("ApiKey")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("Description")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("FrequencyPenalty")
+ .HasColumnType("real");
+
+ b.Property("Instructions")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("MaxOutputTokens")
+ .HasColumnType("integer");
+
+ b.Property("ModelName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("PresencePenalty")
+ .HasColumnType("real");
+
+ b.Property("Provider")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("StateCheckers")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("SystemPrompt")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.Property("Temperature")
+ .HasColumnType("real");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("AbpAIWorkspaceDefinitions", (string)null);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.cs
new file mode 100644
index 000000000..b080e32e7
--- /dev/null
+++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/20260313010418_Add-Workspace-To-Conversation-Record.cs
@@ -0,0 +1,30 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace LINGYUN.Abp.MicroService.AIService.Migrations
+{
+ ///
+ public partial class AddWorkspaceToConversationRecord : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "Workspace",
+ table: "AbpAIConversations",
+ type: "character varying(64)",
+ maxLength: 64,
+ nullable: false,
+ defaultValue: "");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Workspace",
+ table: "AbpAIConversations");
+ }
+ }
+}
diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/AIServiceMigrationsDbContextModelSnapshot.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/AIServiceMigrationsDbContextModelSnapshot.cs
index 095a0771d..9cc821579 100644
--- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/AIServiceMigrationsDbContextModelSnapshot.cs
+++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService.EntityFrameworkCore/Migrations/AIServiceMigrationsDbContextModelSnapshot.cs
@@ -63,6 +63,11 @@ namespace LINGYUN.Abp.MicroService.AIService.Migrations
b.Property("UpdateAt")
.HasColumnType("timestamp with time zone");
+ b.Property("Workspace")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
b.HasKey("Id");
b.ToTable("AbpAIConversations", (string)null);
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentService.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentService.cs
index 78c9f0508..046d714ce 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentService.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentService.cs
@@ -127,6 +127,7 @@ public class AgentService : IAgentService, IScopedDependency
var conversation = new Conversation(
_guidGenerator.Create(),
_localizerResource["NewConversation"],
+ message.Workspace,
_clock.Now);
await _conversationStore.SaveAsync(conversation);
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationCreateDto.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationCreateDto.cs
index 8112305b2..e8ad0a33b 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationCreateDto.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationCreateDto.cs
@@ -1,8 +1,15 @@
-using Volo.Abp.Validation;
+using LINGYUN.Abp.AIManagement.Workspaces;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Validation;
namespace LINGYUN.Abp.AIManagement.Chats.Dtos;
public class ConversationCreateDto
{
[DynamicStringLength(typeof(ConversationRecordConsts), nameof(ConversationRecordConsts.MaxNameLength))]
public string? Name { get; set; }
+
+ [Required]
+ [DynamicStringLength(typeof(WorkspaceDefinitionRecordConsts), nameof(WorkspaceDefinitionRecordConsts.MaxNameLength))]
+ public string Workspace { get; set; }
+
}
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationDto.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationDto.cs
index 8f5945c95..5a64ac79e 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationDto.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Chats/Dtos/ConversationDto.cs
@@ -6,6 +6,8 @@ public class ConversationDto : AuditedEntityDto
{
public string Name { get; set; }
+ public string Workspace { get; set; }
+
public DateTime CreatedAt { get; set; }
public DateTime ExpiredAt { get; set; }
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Chats/ConversationAppService.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Chats/ConversationAppService.cs
index 203747602..dc1fc00af 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Chats/ConversationAppService.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Chats/ConversationAppService.cs
@@ -46,6 +46,7 @@ public class ConversationAppService :
return new ConversationRecord(
GuidGenerator.Create(),
conversationName,
+ createInput.Workspace,
createdAt,
expiredTime,
CurrentTenant.Id);
@@ -57,6 +58,8 @@ public class ConversationAppService :
{
entity.SetName(updateInput.Name);
}
+
+ entity.ChangeTime(Clock.Now);
}
protected override ConversationDto MapToGetOutputDto(ConversationRecord entity)
@@ -72,6 +75,7 @@ public class ConversationAppService :
LastModifierId = entity.LastModifierId,
Name = entity.Name,
UpdateAt = entity.UpdateAt,
+ Workspace = entity.Workspace,
};
}
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationRecord.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationRecord.cs
index 10192ab8b..939d6f935 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationRecord.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationRecord.cs
@@ -1,4 +1,5 @@
-using System;
+using LINGYUN.Abp.AIManagement.Workspaces;
+using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
@@ -10,6 +11,8 @@ public class ConversationRecord : AuditedEntity, IMultiTenant
public string Name { get; private set; }
+ public string Workspace { get; private set; }
+
public DateTime CreatedAt { get; private set; }
public DateTime ExpiredAt { get; set; }
@@ -18,13 +21,16 @@ public class ConversationRecord : AuditedEntity, IMultiTenant
public ConversationRecord(
Guid id,
string name,
+ string workspace,
DateTime createdAt,
DateTime expiredAt,
Guid? tenantId = null)
: base(id)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), ConversationRecordConsts.MaxNameLength);
+ Workspace = Check.NotNullOrWhiteSpace(workspace, nameof(workspace), WorkspaceDefinitionRecordConsts.MaxNameLength);
CreatedAt = createdAt;
+ CreationTime = createdAt;
ExpiredAt = expiredAt;
UpdateAt = createdAt;
@@ -36,4 +42,10 @@ public class ConversationRecord : AuditedEntity, IMultiTenant
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), ConversationRecordConsts.MaxNameLength);
}
+
+ public void ChangeTime(DateTime updateTime)
+ {
+ UpdateAt = updateTime;
+ LastModificationTime = updateTime;
+ }
}
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationStore.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationStore.cs
index 3d7d2ed5e..7ee2c120a 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationStore.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationStore.cs
@@ -3,7 +3,6 @@ using LINGYUN.Abp.AI.Models;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
-using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Specifications;
@@ -58,6 +57,7 @@ public class ConversationStore : IConversationStore, ITransientDependency
var conversation = new Conversation(
conversationRecord.Id,
conversationRecord.Name,
+ conversationRecord.Workspace,
conversationRecord.CreatedAt)
{
UpdateAt = conversationRecord.UpdateAt,
@@ -77,6 +77,7 @@ public class ConversationStore : IConversationStore, ITransientDependency
conversationRecord = new ConversationRecord(
conversation.Id,
conversation.Name,
+ conversation.Workspace,
conversation.CreatedAt,
expiredTime,
_currentTenant.Id);
diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.EntityFrameworkCore/LINGYUN/Abp/AIManagement/EntityFrameworkCore/AIManagementDbContextModelBuilderExtensions.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.EntityFrameworkCore/LINGYUN/Abp/AIManagement/EntityFrameworkCore/AIManagementDbContextModelBuilderExtensions.cs
index f3f5e9f9a..e62b67b95 100644
--- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.EntityFrameworkCore/LINGYUN/Abp/AIManagement/EntityFrameworkCore/AIManagementDbContextModelBuilderExtensions.cs
+++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.EntityFrameworkCore/LINGYUN/Abp/AIManagement/EntityFrameworkCore/AIManagementDbContextModelBuilderExtensions.cs
@@ -24,6 +24,9 @@ public static class AIManagementDbContextModelBuilderExtensions
b.Property(x => x.Name)
.HasMaxLength(ConversationRecordConsts.MaxNameLength)
.IsRequired();
+ b.Property(x => x.Workspace)
+ .HasMaxLength(WorkspaceDefinitionRecordConsts.MaxNameLength)
+ .IsRequired();
});
builder.Entity(b =>
{