[package]
name = "blazen-llm"
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
rust-version.workspace = true
repository.workspace = true
description = "LLM provider abstraction layer for the Blazen workflow engine"
build = "build.rs"

[build-dependencies]
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true

[features]
default = ["content-detect"]
reqwest = ["dep:reqwest"]
tiktoken = ["dep:tiktoken-rs"]
# Magic-number-based file-type detection for the content store. Adds the
# `infer` dependency. Disable for footprint-sensitive embedded targets;
# detection then falls back to extension + MIME hints.
content-detect = ["dep:infer"]
tsify = ["dep:tsify-next", "dep:wasm-bindgen"]
pyo3-serde = ["dep:pythonize", "dep:pyo3"]
# Local inference backends (populated per-phase as crates land)
embed = ["dep:blazen-embed"]      # Phase 2: local embeddings via blazen-embed facade
candle-embed = ["dep:blazen-embed-candle"]   # Phase 6: local embeddings via candle
mistralrs = ["dep:blazen-llm-mistralrs"]      # Phase 3: local LLM via mistral.rs
llamacpp = ["dep:blazen-llm-llamacpp"]       # Phase 8: local LLM via llama.cpp
candle-llm = ["dep:blazen-llm-candle"]     # Phase 7: local LLM via candle
diffusion = ["dep:blazen-image-diffusion"]      # Phase 5: local image gen via diffusion-rs
whispercpp = ["dep:blazen-audio-whispercpp"]     # Phase 4: local STT via whisper.cpp
piper = ["dep:blazen-audio-piper"]          # Phase 9: local TTS via Piper
candle-audio = []   # Phase 10: local music/SFX via candle

[dependencies]
blazen-events.workspace = true
async-trait.workspace = true
schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true
tokio = { version = "1", default-features = false, features = ["sync", "macros"] }
tokio-util = { workspace = true, features = ["io"] }
futures-util.workspace = true
futures-core.workspace = true
tracing.workspace = true
bytes.workspace = true
chrono.workspace = true
reqwest = { workspace = true, optional = true }
tiktoken-rs = { version = "0.9", optional = true }
tsify-next = { version = "0.5", features = ["js", "json"], optional = true }
wasm-bindgen = { version = "=0.2.118", optional = true }
pythonize = { version = "0.28", optional = true }
pyo3 = { version = "0.28", optional = true }
base64 = { workspace = true }
infer = { workspace = true, optional = true }
uuid.workspace = true
blazen-embed = { workspace = true, optional = true }
blazen-llm-mistralrs = { workspace = true, optional = true }
blazen-audio-whispercpp = { workspace = true, optional = true }
blazen-embed-candle = { workspace = true, optional = true }
blazen-image-diffusion = { workspace = true, optional = true }
blazen-llm-candle = { workspace = true, optional = true }
blazen-llm-llamacpp = { workspace = true, optional = true }
blazen-audio-piper = { workspace = true, optional = true }

# Timer/runtime features only on native targets (mio doesn't support any wasm32 target)
[target.'cfg(not(any(target_os = "wasi", target_arch = "wasm32")))'.dependencies]
tokio = { version = "1", default-features = false, features = ["rt", "time", "fs", "io-util"] }

# Browser WASM only (not WASIp2 -- WASIp2 has no JS runtime).
# `web-sys`, `uuid["js"]`, and `getrandom["js"]` all transitively pull
# `wasm-bindgen`, which the wasi build cannot satisfy (no JS shim host),
# so they live in the browser-only block.
[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies]
wasm-bindgen = "=0.2.118"
wasm-bindgen-futures = "=0.4.68"
js-sys = "=0.3.95"
web-sys = { version = "=0.3.95", features = [
    "Request",
    "RequestInit",
    "Response",
    "Headers",
    "Window",
    "ReadableStream",
    "ReadableStreamDefaultReader",
] }
uuid = { workspace = true, features = ["js"] }
getrandom = { version = "0.2", features = ["js"] }

# Cross-wasm32 deps (browser + wasi). web-time transparently re-exports
# std::time on native/wasi and uses Performance.now() in the browser; the
# source unconditionally imports `web_time::Instant` under cfg(wasm32) so
# both wasm flavors must pull the dep. web-time does NOT pull wasm-bindgen.
[target.'cfg(target_arch = "wasm32")'.dependencies]
web-time = "1"

[dev-dependencies]
tempfile = { workspace = true }

[lints]
workspace = true
