replaced embedding_state with index_store as a sqlite name

This commit is contained in:
PaulKoudelka committed 2026-08-14 12:37:50 +02:00
1 parent 50aa5c485d
commit 1a263127f5
15 files changed
+129 -129

No files matched your search

@@ -1,4 +1,4 @@
using AIStudio.Tools.Databases.EmbeddingState;
using AIStudio.Tools.Databases.IndexStore;
using AIStudio.Tools.Databases.VectorStore;
using AIStudio.Tools.Services;
@@ -57,13 +57,13 @@ public sealed partial class DatabaseClientProvider(RustService rustService, ILog
client.Status);
}
public async Task<EmbeddingStateClient> GetEmbeddingStateAsync(CancellationToken cancellationToken = default)
public async Task<IndexStoreClient> GetIndexStoreAsync(CancellationToken cancellationToken = default)
{
var client = await this.GetClientAsync(DatabaseRole.EMBEDDING_STATE, cancellationToken);
if (client is EmbeddingStateClient embeddingState)
return embeddingState;
var client = await this.GetClientAsync(DatabaseRole.INDEX_STORE, cancellationToken);
if (client is IndexStoreClient indexStore)
return indexStore;
return new NoEmbeddingStateClient(
return new NoIndexStoreClient(
client.Name,
"The configured database client does not support local RAG index operations.",
client.Status);
@@ -105,7 +105,7 @@ public sealed partial class DatabaseClientProvider(RustService rustService, ILog
private async Task<DatabaseClient> CreateClientAsync(DatabaseRole databaseRole, CancellationToken cancellationToken) => databaseRole switch
{
DatabaseRole.VECTOR_STORE => await QdrantEdgeClientImplementation.CreateAsync(rustService, this.logger, this.databaseClientLogger, cancellationToken),
DatabaseRole.EMBEDDING_STATE => await SqliteEmbeddingStateClientImplementation.CreateAsync(this.logger, this.databaseClientLogger, cancellationToken),
DatabaseRole.INDEX_STORE => await SqliteIndexStoreClientImplementation.CreateAsync(this.logger, this.databaseClientLogger, cancellationToken),
_ => new NoDatabaseClient(databaseRole.ToString(), "The requested database role is not supported.")
};
@@ -3,5 +3,5 @@ namespace AIStudio.Tools.Databases;
public enum DatabaseRole
{
VECTOR_STORE,
EMBEDDING_STATE,
INDEX_STORE,
}
@@ -1,8 +1,8 @@
using AIStudio.Tools.Services;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
public abstract class EmbeddingStateClient(string name, string path) : DatabaseClient(name, path)
public abstract class IndexStoreClient(string name, string path) : DatabaseClient(name, path)
{
public abstract Task<DataSourceEmbeddingManifest> GetManifestAsync(string dataSourceId, CancellationToken token);
@@ -26,7 +26,7 @@ public abstract class EmbeddingStateClient(string name, string path) : DatabaseC
public abstract Task UpsertChunksAsync(string dataSourceId, IReadOnlyList<EmbeddingStateChunk> chunks, CancellationToken token);
public abstract Task<IReadOnlyList<EmbeddingStateSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token);
public abstract Task<IReadOnlyList<IndexStoreSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token);
public abstract Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token);
}
@@ -54,7 +54,7 @@ public sealed record EmbeddingStateChunk(
string ChunkText,
DateTimeOffset EmbeddedAtUtc);
public sealed record EmbeddingStateSearchResult(
public sealed record IndexStoreSearchResult(
string ChunkId,
string ParentFileId,
string DataSourceId,
@@ -4,11 +4,11 @@ using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
internal sealed class EmbeddingStateDbContext(DbContextOptions<EmbeddingStateDbContext> options) : DbContext(options)
internal sealed class IndexStoreDbContext(DbContextOptions<IndexStoreDbContext> options) : DbContext(options)
{
public static DbContextOptions<EmbeddingStateDbContext> CreateOptions(string databasePath) => new DbContextOptionsBuilder<EmbeddingStateDbContext>()
public static DbContextOptions<IndexStoreDbContext> CreateOptions(string databasePath) => new DbContextOptionsBuilder<IndexStoreDbContext>()
.UseSqlite(BuildConnectionString(databasePath))
.Options;
@@ -18,11 +18,11 @@ internal sealed class EmbeddingStateDbContext(DbContextOptions<EmbeddingStateDbC
public DbSet<EmbeddingStateChunkEntity> EmbeddingChunks => this.Set<EmbeddingStateChunkEntity>();
public DbSet<EmbeddingStateSearchResultEntity> SearchResults => this.Set<EmbeddingStateSearchResultEntity>();
public DbSet<IndexStoreSearchResultEntity> SearchResults => this.Set<IndexStoreSearchResultEntity>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var utcDateTimeOffsetConverter = new EmbeddingStateDateTimeOffsetConverter();
var utcDateTimeOffsetConverter = new IndexStoreDateTimeOffsetConverter();
modelBuilder.Entity<EmbeddingStateDataSourceEntity>(entity =>
{
@@ -97,7 +97,7 @@ internal sealed class EmbeddingStateDbContext(DbContextOptions<EmbeddingStateDbC
entity.HasIndex(chunk => new { chunk.ParentFileId, chunk.ChunkIndex }).HasDatabaseName("idx_embedding_chunks_parent_file_chunk_index").IsUnique();
});
modelBuilder.Entity<EmbeddingStateSearchResultEntity>(entity =>
modelBuilder.Entity<IndexStoreSearchResultEntity>(entity =>
{
entity.HasNoKey();
entity.ToView("embedding_chunk_search_results");
@@ -193,7 +193,7 @@ internal sealed class EmbeddingStateChunkEntity
public EmbeddingStateFileEntity? File { get; set; }
}
internal sealed class EmbeddingStateSearchResultEntity
internal sealed class IndexStoreSearchResultEntity
{
public string ChunkId { get; set; } = string.Empty;
@@ -238,11 +238,11 @@ internal sealed class EmbeddingStateSearchResultEntity
public int ConfidenceLevelRank { get; set; }
}
internal sealed class EmbeddingStateDateTimeOffsetConverter() : ValueConverter<DateTimeOffset, string>(
value => EmbeddingStateDateTimeOffset.ToUtcText(value),
value => EmbeddingStateDateTimeOffset.ParseUtc(value));
internal sealed class IndexStoreDateTimeOffsetConverter() : ValueConverter<DateTimeOffset, string>(
value => IndexStoreDateTimeOffset.ToUtcText(value),
value => IndexStoreDateTimeOffset.ParseUtc(value));
internal static class EmbeddingStateDateTimeOffset
internal static class IndexStoreDateTimeOffset
{
public static string ToUtcText(DateTimeOffset dateTime)
{
@@ -1,15 +1,15 @@
using Microsoft.EntityFrameworkCore.Design;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
internal sealed class EmbeddingStateDesignTimeDbContextFactory : IDesignTimeDbContextFactory<EmbeddingStateDbContext>
internal sealed class IndexStoreDesignTimeDbContextFactory : IDesignTimeDbContextFactory<IndexStoreDbContext>
{
public EmbeddingStateDbContext CreateDbContext(string[] args)
public IndexStoreDbContext CreateDbContext(string[] args)
{
var databasePath = args.FirstOrDefault(argument => argument.EndsWith(".sqlite3", StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrWhiteSpace(databasePath))
databasePath = Path.Combine(Path.GetTempPath(), "mindwork-ai-studio-rag-index-design.sqlite3");
return new EmbeddingStateDbContext(EmbeddingStateDbContext.CreateOptions(databasePath));
return new IndexStoreDbContext(IndexStoreDbContext.CreateOptions(databasePath));
}
}
@@ -2,12 +2,12 @@ using System.Diagnostics.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
internal static class EmbeddingStateSchemaMigrator
internal static class IndexStoreSchemaMigrator
{
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Migrations.InitialRagIndex))]
public static async Task MigrateAsync(EmbeddingStateDbContext context, CancellationToken token)
public static async Task MigrateAsync(IndexStoreDbContext context, CancellationToken token)
{
await context.Database.MigrateAsync(token);
await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL;", token);
@@ -3,9 +3,9 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace AIStudio.Tools.Databases.EmbeddingState.Migrations;
namespace AIStudio.Tools.Databases.IndexStore.Migrations;
[DbContext(typeof(EmbeddingStateDbContext))]
[DbContext(typeof(IndexStoreDbContext))]
[Migration("20260804000000_InitialRagIndex")]
public partial class InitialRagIndex : Migration
{
@@ -3,18 +3,18 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace AIStudio.Tools.Databases.EmbeddingState.Migrations;
namespace AIStudio.Tools.Databases.IndexStore.Migrations;
[DbContext(typeof(EmbeddingStateDbContext))]
partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
[DbContext(typeof(IndexStoreDbContext))]
partial class IndexStoreDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.18");
var utcDateTimeOffsetConverter = new EmbeddingStateDateTimeOffsetConverter();
var utcDateTimeOffsetConverter = new IndexStoreDateTimeOffsetConverter();
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateDataSourceEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateDataSourceEntity", entity =>
{
entity.Property<string>("DataSourceId")
.HasColumnType("TEXT")
@@ -61,7 +61,7 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.ToTable("data_sources");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateFileEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateFileEntity", entity =>
{
entity.Property<string>("ParentFileId")
.HasColumnType("TEXT")
@@ -151,7 +151,7 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.ToTable("embedded_files");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateChunkEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateChunkEntity", entity =>
{
entity.Property<int>("Id")
.ValueGeneratedOnAdd()
@@ -206,7 +206,7 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.ToTable("embedding_chunks");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateSearchResultEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.IndexStoreSearchResultEntity", entity =>
{
entity.Property<string>("AbsolutePath")
.IsRequired()
@@ -291,9 +291,9 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.ToView("embedding_chunk_search_results");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateFileEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateFileEntity", entity =>
{
entity.HasOne("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateDataSourceEntity", "DataSource")
entity.HasOne("AIStudio.Tools.Databases.IndexStore.EmbeddingStateDataSourceEntity", "DataSource")
.WithMany("Files")
.HasForeignKey("DataSourceId")
.OnDelete(DeleteBehavior.Cascade)
@@ -302,9 +302,9 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.Navigation("DataSource");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateChunkEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateChunkEntity", entity =>
{
entity.HasOne("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateFileEntity", "File")
entity.HasOne("AIStudio.Tools.Databases.IndexStore.EmbeddingStateFileEntity", "File")
.WithMany("Chunks")
.HasForeignKey("ParentFileId")
.OnDelete(DeleteBehavior.Cascade)
@@ -313,12 +313,12 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot
entity.Navigation("File");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateDataSourceEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateDataSourceEntity", entity =>
{
entity.Navigation("Files");
});
modelBuilder.Entity("AIStudio.Tools.Databases.EmbeddingState.EmbeddingStateFileEntity", entity =>
modelBuilder.Entity("AIStudio.Tools.Databases.IndexStore.EmbeddingStateFileEntity", entity =>
{
entity.Navigation("Chunks");
});
@@ -1,11 +1,11 @@
using AIStudio.Tools.PluginSystem;
using AIStudio.Tools.Services;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
public sealed class NoEmbeddingStateClient(string name, string? unavailableReason, DatabaseClientStatus status = DatabaseClientStatus.UNAVAILABLE) : EmbeddingStateClient(name, string.Empty)
public sealed class NoIndexStoreClient(string name, string? unavailableReason, DatabaseClientStatus status = DatabaseClientStatus.UNAVAILABLE) : IndexStoreClient(name, string.Empty)
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(NoEmbeddingStateClient).Namespace, nameof(NoEmbeddingStateClient));
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(NoIndexStoreClient).Namespace, nameof(NoIndexStoreClient));
public override DatabaseClientStatus Status => status;
@@ -46,8 +46,8 @@ public sealed class NoEmbeddingStateClient(string name, string? unavailableReaso
public override Task UpsertChunksAsync(string dataSourceId, IReadOnlyList<EmbeddingStateChunk> chunks, CancellationToken token) => Task.CompletedTask;
public override Task<IReadOnlyList<EmbeddingStateSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token) =>
Task.FromResult<IReadOnlyList<EmbeddingStateSearchResult>>([]);
public override Task<IReadOnlyList<IndexStoreSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token) =>
Task.FromResult<IReadOnlyList<IndexStoreSearchResult>>([]);
public override Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token) => Task.CompletedTask;
@@ -7,13 +7,13 @@ using AIStudio.Tools.Services;
using Microsoft.EntityFrameworkCore;
namespace AIStudio.Tools.Databases.EmbeddingState;
namespace AIStudio.Tools.Databases.IndexStore;
public sealed class SqliteEmbeddingStateClientImplementation(
public sealed class SqliteIndexStoreClientImplementation(
string name,
string databasePath,
string basePath,
string version) : EmbeddingStateClient(name, basePath)
string version) : IndexStoreClient(name, basePath)
{
private const string DATABASE_NAME = "Local RAG Index";
private const string DATABASE_FILENAME = "rag-index.sqlite3";
@@ -23,9 +23,9 @@ public sealed class SqliteEmbeddingStateClientImplementation(
private static readonly Regex FTS_TOKEN_REGEX = new(@"[\p{L}\p{Nd}_]+", RegexOptions.Compiled | RegexOptions.CultureInvariant);
private readonly string databasePath = databasePath;
private readonly DbContextOptions<EmbeddingStateDbContext> dbContextOptions = EmbeddingStateDbContext.CreateOptions(databasePath);
private readonly DbContextOptions<IndexStoreDbContext> dbContextOptions = IndexStoreDbContext.CreateOptions(databasePath);
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(SqliteEmbeddingStateClientImplementation).Namespace, nameof(SqliteEmbeddingStateClientImplementation));
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(SqliteIndexStoreClientImplementation).Namespace, nameof(SqliteIndexStoreClientImplementation));
public override string CacheKey => $"{this.Name}:{this.databasePath}:{version}";
@@ -35,7 +35,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(SettingsManager.DataDirectory))
return CreateNoEmbeddingStateClient(DATABASE_NAME, "The application data directory is not available yet.", DatabaseClientStatus.STARTING, databaseClientLogger);
return CreateNoIndexStoreClient(DATABASE_NAME, "The application data directory is not available yet.", DatabaseClientStatus.STARTING, databaseClientLogger);
try
{
@@ -45,18 +45,18 @@ public sealed class SqliteEmbeddingStateClientImplementation(
Directory.CreateDirectory(basePath);
var databasePath = Path.Combine(basePath, DATABASE_FILENAME);
var client = new SqliteEmbeddingStateClientImplementation(DATABASE_NAME, databasePath, basePath, string.Empty);
var client = new SqliteIndexStoreClientImplementation(DATABASE_NAME, databasePath, basePath, string.Empty);
await client.InitializeAsync(cancellationToken);
var version = await client.GetSqliteVersionAsync(cancellationToken);
client = new SqliteEmbeddingStateClientImplementation(DATABASE_NAME, databasePath, basePath, version);
client = new SqliteIndexStoreClientImplementation(DATABASE_NAME, databasePath, basePath, version);
client.SetLogger(databaseClientLogger);
return client;
}
catch (Exception exception)
{
logger.LogWarning(exception, "{DatabaseName} is not available. Indexed file fingerprints and search chunks are disabled.", DATABASE_NAME);
return CreateNoEmbeddingStateClient(DATABASE_NAME, exception.Message, DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
return CreateNoIndexStoreClient(DATABASE_NAME, exception.Message, DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
}
}
@@ -236,7 +236,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
await transaction.CommitAsync(token);
}
public override async Task<IReadOnlyList<EmbeddingStateSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token)
public override async Task<IReadOnlyList<IndexStoreSearchResult>> SearchChunksAsync(string dataSourceId, string query, int maxMatches, CancellationToken token)
{
if (maxMatches <= 0)
return [];
@@ -314,7 +314,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
private async Task InitializeAsync(CancellationToken token)
{
await using var context = this.CreateContext();
await EmbeddingStateSchemaMigrator.MigrateAsync(context, token);
await IndexStoreSchemaMigrator.MigrateAsync(context, token);
}
private async Task<string> GetSqliteVersionAsync(CancellationToken token)
@@ -326,7 +326,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
return versions.FirstOrDefault() ?? string.Empty;
}
private EmbeddingStateDbContext CreateContext() => new(this.dbContextOptions);
private IndexStoreDbContext CreateContext() => new(this.dbContextOptions);
private static void ApplyDataSource(
EmbeddingStateDataSourceEntity dataSource,
@@ -373,7 +373,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
chunkEntity.EmbeddedAtUtc = chunk.EmbeddedAtUtc;
}
private static EmbeddingStateSearchResult ToSearchResult(EmbeddingStateSearchResultEntity result) => new(
private static IndexStoreSearchResult ToSearchResult(IndexStoreSearchResultEntity result) => new(
result.ChunkId,
result.ParentFileId,
result.DataSourceId,
@@ -410,9 +410,9 @@ public sealed class SqliteEmbeddingStateClientImplementation(
return terms.Count == 0 ? string.Empty : string.Join(" OR ", terms);
}
private static NoEmbeddingStateClient CreateNoEmbeddingStateClient(string name, string? unavailableReason, DatabaseClientStatus status, ILogger<DatabaseClient> databaseClientLogger)
private static NoIndexStoreClient CreateNoIndexStoreClient(string name, string? unavailableReason, DatabaseClientStatus status, ILogger<DatabaseClient> databaseClientLogger)
{
var client = new NoEmbeddingStateClient(name, unavailableReason, status);
var client = new NoIndexStoreClient(name, unavailableReason, status);
client.SetLogger(databaseClientLogger);
return client;
}