zeph-core 0.12.6

Core agent loop, configuration, context builder, metrics, and vault for Zeph
Documentation
// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
// SPDX-License-Identifier: MIT OR Apache-2.0

use std::path::PathBuf;
use zeph_llm::any::AnyProvider;
use zeph_memory::semantic::SemanticMemory;
use zeph_skills::loader::SkillMeta;
use zeph_skills::matcher::{SkillMatcher, SkillMatcherBackend};
use zeph_skills::qdrant_matcher::QdrantSkillMatcher;

use crate::config::{Config, ProviderKind};

#[allow(unused_variables)]
pub async fn create_skill_matcher(
    config: &Config,
    provider: &AnyProvider,
    meta: &[&SkillMeta],
    memory: &SemanticMemory,
    embedding_model: &str,
) -> Option<SkillMatcherBackend> {
    let embed_fn = provider.embed_fn();

    if config.memory.semantic.enabled && memory.is_vector_store_connected().await {
        match QdrantSkillMatcher::new(&config.memory.qdrant_url) {
            Ok(mut qm) => match qm.sync(meta, embedding_model, &embed_fn).await {
                Ok(_) => return Some(SkillMatcherBackend::Qdrant(qm)),
                Err(e) => {
                    tracing::warn!("Qdrant skill sync failed, falling back to in-memory: {e:#}");
                }
            },
            Err(e) => {
                tracing::warn!("Qdrant client creation failed, falling back to in-memory: {e:#}");
            }
        }
    }

    SkillMatcher::new(meta, &embed_fn)
        .await
        .map(SkillMatcherBackend::InMemory)
}

pub fn effective_embedding_model(config: &Config) -> String {
    match config.llm.provider {
        ProviderKind::OpenAi => {
            if let Some(m) = config
                .llm
                .openai
                .as_ref()
                .and_then(|o| o.embedding_model.clone())
            {
                return m;
            }
        }
        ProviderKind::Orchestrator => {
            if let Some(orch) = &config.llm.orchestrator
                && let Some(pcfg) = orch.providers.get(&orch.embed)
            {
                if let Some(ref m) = pcfg.embedding_model {
                    return m.clone();
                }
                if pcfg.provider_type == "openai"
                    && let Some(m) = config
                        .llm
                        .openai
                        .as_ref()
                        .and_then(|o| o.embedding_model.clone())
                {
                    return m;
                }
            }
        }
        ProviderKind::Compatible => {
            if let Some(entries) = &config.llm.compatible
                && let Some(entry) = entries.first()
                && let Some(ref m) = entry.embedding_model
            {
                return m.clone();
            }
        }
        _ => {}
    }
    config.llm.embedding_model.clone()
}

/// Returns the default managed skills directory: `~/.config/zeph/skills/`.
pub fn managed_skills_dir() -> PathBuf {
    crate::vault::default_vault_dir().join("skills")
}