// Generated by alef. Do not edit by hand.
@file:Suppress(
    "ktlint:standard:trailing-comma-on-call-site",
    "ktlint:standard:trailing-comma-on-declaration-site",
    "ktlint:standard:spacing-between-declarations-with-comments",
    "ktlint:standard:spacing-between-declarations-with-annotations",
    "ktlint:standard:when-entry-bracing",
    "ktlint:standard:blank-line-between-when-conditions",
    "ktlint:standard:blank-line-before-declaration",
    "ktlint:standard:chain-method-continuation",
    "ktlint:standard:annotation",
    "ktlint:standard:max-line-length",
    "ktlint:standard:no-semi",
    "ktlint:standard:statement-wrapping",
    "MaxLineLength",
    "TooManyFunctions",
    "FunctionParameterNaming",
    "LongParameterList",
    "CyclomaticComplexMethod",
    "LongMethod",
)

package dev.kreuzberg

/**
 * Trait for in-process embedding backend plugins.
 *
 * Async to match the convention used by `OcrBackend`,
 * `DocumentExtractor`, and `PostProcessor`.
 * Host-language bridges (PyO3, napi-rs, Rustler, extendr, magnus, ext-php-rs,
 * C FFI, etc.) wrap their synchronous host callables in `spawn_blocking` or the
 * equivalent to satisfy the async signature.
 *
 * # Thread safety
 *
 * Backends must be `Send + Sync + 'static`. They are stored in
 * `Arc<dyn EmbeddingBackend>` and called concurrently from kreuzberg's chunking
 * pipeline. If the backend's underlying model isn't thread-safe, the backend
 * itself must serialize access internally (e.g. via `Mutex<Inner>`).
 *
 * # Contract
 *
 * - `embed(texts)` MUST return exactly `texts.len()` vectors, each of length
 *   `self.dimensions()`. The dispatcher in `embed_texts`
 *   validates this before returning to downstream consumers; a non-conforming
 *   backend surfaces as a `KreuzbergError.Validation`, not a panic.
 *
 * - `embed` may be called from any thread. Its future must be `Send`
 *   (enforced by `async_trait` when `#[async_trait]` is used on non-WASM targets).
 *
 * - `dimensions()` is called exactly once at registration, immediately after
 *   `initialize()` succeeds. The returned value is cached by the registry and
 *   used for all subsequent shape validation. Lazy-loading implementations can
 *   defer model loading into `initialize()` and report the real dimension
 *   afterwards. Later mutations of the backend's reported dimension are not
 *   observed by kreuzberg — implementations that need to change dimension
 *   must unregister and re-register.
 *
 * - `shutdown()` (inherited from `Plugin`) may be invoked
 *   concurrently with an in-flight `embed()` call. Implementations must
 *   tolerate this — e.g. by letting in-flight calls finish using resources
 *   held via the `Arc<dyn EmbeddingBackend>` reference, and only releasing
 *   shared state that isn't needed by `embed`.
 *
 * # Runtime
 *
 * The synchronous `embed_texts` entry uses
 * `tokio.task.block_in_place` to await the trait's async `embed`, which
 * requires a multi-thread tokio runtime. Callers running inside a
 * `current_thread` runtime (e.g. `#[tokio.test]` without `flavor = "multi_thread"`,
 * or `tokio.runtime.Builder.new_current_thread()`) must use
 * `embed_texts_async` instead, which awaits directly without
 * `block_in_place`.
 */
interface IEmbeddingBackend {
    fun name(): String
    fun version(): String
    fun initialize() {}
    fun shutdown() {}
    /**
     * Embedding vector dimension. Must be `> 0` and must match the length of
     * every vector returned by `embed`.
     */
    fun dimensions(): Long
    /**
     * Embed a batch of texts, returning one vector per input in order.
     *
     * **Errors:**
     *
     * Implementations should return `Plugin` for
     * backend-specific failures. The dispatcher layers its own validation
     * (length, per-vector dimension) on top.
     */
    suspend fun embed(texts: List<String>): List<List<Float>>
}
