remove :storage-ksqlite (conversation/message) and related tests; decouple schema from journal
ci / JVM build + tests (push) Successful in 6m6s
ci / JVM build + tests (push) Successful in 6m6s
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(21)
|
||||
jvm()
|
||||
macosX64()
|
||||
macosArm64()
|
||||
iosX64()
|
||||
iosArm64()
|
||||
iosSimulatorArm64()
|
||||
linuxX64()
|
||||
linuxArm64()
|
||||
mingwX64()
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
api(libs.kotlinx.coroutines.core)
|
||||
}
|
||||
commonTest.dependencies {
|
||||
implementation(kotlin("test"))
|
||||
implementation(libs.kotlinx.coroutines.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package pw.binom.agentik.vectorindex
|
||||
|
||||
interface MutableVectorIndexStore : VectorIndexStore {
|
||||
|
||||
/**
|
||||
* Добавляет запись в индекс.
|
||||
*
|
||||
* @param id Идентификатор записи. Если `null` — реализация генерирует
|
||||
* его сама (формат остаётся на усмотрение реализации).
|
||||
* @param embedding Вектор. Размер должен совпадать с [VectorIndexStore.dimension].
|
||||
* @param payload Пользовательские данные (любая сериализуемая структура —
|
||||
* реализация хранит opaque string и не интерпретирует).
|
||||
* @return Добавленная запись (с сгенерированным `id`, если был передан `null`).
|
||||
* @throws VectorIndexAlreadyExistsException запись с указанным `id` уже есть в индексе.
|
||||
*/
|
||||
suspend fun add(id: String?, embedding: FloatArray, payload: String?): VectorIndex
|
||||
|
||||
/**
|
||||
* Удаляет запись из индекса.
|
||||
* @return `true`, если запись была удалена, `false`, если записи с таким `id` не было.
|
||||
*/
|
||||
suspend fun delete(id: String): Boolean
|
||||
|
||||
/**
|
||||
* Полностью очищает индекс.
|
||||
* @return количество удалённых записей.
|
||||
*/
|
||||
suspend fun clear(): Long
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package pw.binom.agentik.vectorindex
|
||||
|
||||
/**
|
||||
* Запись в vector-индексе: идентификатор + embedding + опциональный
|
||||
* пользовательский payload.
|
||||
*
|
||||
* НЕ `data class` потому что [embedding] это `FloatArray`, а дефолтные
|
||||
* `equals`/`hashCode` data-class'а сравнивают массивы по reference (а не
|
||||
* по содержимому) — два `VectorIndex` с идентичными числами оказались бы
|
||||
* `!=`. Вместо этого [equals]/[hashCode]/[toString] переопределены руками.
|
||||
*/
|
||||
class VectorIndex(
|
||||
val id: String,
|
||||
val embedding: FloatArray,
|
||||
val payload: String?,
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || this::class != other::class) return false
|
||||
other as VectorIndex
|
||||
if (id != other.id) return false
|
||||
if (!embedding.contentEquals(other.embedding)) return false
|
||||
if (payload != other.payload) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + embedding.contentHashCode()
|
||||
result = 31 * result + (payload?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"VectorIndex(id='$id', embedding.size=${embedding.size}, payload=$payload)"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pw.binom.agentik.vectorindex
|
||||
|
||||
class VectorIndexAlreadyExistsException : Exception()
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package pw.binom.agentik.vectorindex
|
||||
|
||||
/**
|
||||
* Интерфейс read-only доступа к ANN-индексу. Реализации могут держать
|
||||
* native resources (mmap'нутые файлы, sqlite handles) — поэтому [close]
|
||||
* обязателен и наследуется от [AutoCloseable].
|
||||
*/
|
||||
interface VectorIndexStore : AutoCloseable {
|
||||
|
||||
/** Размерность embeddings, которые принимает этот индекс. */
|
||||
val dimension: Int
|
||||
|
||||
/** Текущее количество записей в индексе. */
|
||||
suspend fun getSize(): Long
|
||||
|
||||
/**
|
||||
* Возвращает top-[limit] ближайших к [embedding] записей, отсортированных
|
||||
* по убыванию [VectorSearchResult.score]. Если в индексе меньше [limit]
|
||||
* записей — возвращается меньший список.
|
||||
*/
|
||||
suspend fun search(embedding: FloatArray, limit: Int): List<VectorSearchResult>
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package pw.binom.agentik.vectorindex
|
||||
|
||||
data class VectorSearchResult(
|
||||
val index: VectorIndex,
|
||||
val score: Float,
|
||||
)
|
||||
Reference in New Issue
Block a user