Architecture
QueryMT is designed with a modular and extensible architecture to provide a flexible foundation for interacting with Large Language Models. Understanding its key components will help you leverage the library effectively.
Core Abstractions
At the heart of QueryMT are several key traits that define the contract for LLM interactions:
-
querymt::LLMProvider: This is the central trait that all LLM provider implementations must conform to. It combines capabilities for chat, text completion, and embeddings into a single, unified interface by extendingquerymt::chat::BasicChatProvider,querymt::chat::ToolChatProvider,querymt::completion::CompletionProvider, andquerymt::embedding::EmbeddingProvider. It also includes methods for listing available tools (tools()) and calling them (call_tool()).- Source:
crates/querymt/src/lib.rs
- Source:
-
querymt::HTTPLLMProvider: A specialized trait for LLM providers that are accessed over HTTP. It defines methods for constructing HTTP requests and parsing HTTP responses for chat, completion, and embedding operations by extending thehttpsub-traits (e.g.,querymt::chat::http::HTTPChatProvider).- Source:
crates/querymt/src/lib.rs
- Source:
Provider Adapters
querymt::adapters::LLMProviderFromHTTP: This struct acts as an adapter, allowing anHTTPLLMProvider(which handles the raw HTTP logic) to be used as a full-fledgedLLMProvider. It takes care of calling the outbound HTTP mechanism (fn@querymt::outbound::call_outbound) and then parsing the response using theHTTPLLMProviderimplementation.- Source:
crates/querymt/src/adapters.rs
- Source:
Building and Configuring Providers
querymt::builder::LLMBuilder: QueryMT provides a fluent builder pattern for configuring and instantiatingLLMProviderinstances. This builder allows you to set various options such as the model, API keys, temperature, custom parameters, and register tools. It uses aquerymt::plugin::host::PluginRegistryto find the appropriate factory for the selected provider.- Source:
crates/querymt/src/builder.rs
- Source:
Tool and Function Calling
QueryMT has robust support for LLM tool usage (often called function calling):
querymt::chat::Tool/querymt::chat::FunctionTool: These structs define the schema of tools that an LLM can use.querymt::tool_decorator::CallFunctionTool: A trait that your host-side functions must implement to be callable by the LLM. It includes a method to describe the tool (descriptor()) and a method to execute it (call()).querymt::tool_decorator::ToolEnabledProvider: A decorator that wraps an existingLLMProviderand injects tool-calling capabilities. It manages a registry ofCallFunctionToolimplementations and handles the interaction logic when an LLM decides to call a tool.- Source:
crates/querymt/src/tool_decorator.rs
- Source:
Plugin System
A core strength of QueryMT is its plugin system, enabling easy addition of new LLM providers. The system has been unified to support different plugin types through a single registry.
querymt::plugin::LLMProviderFactory: A trait that plugin authors implement. Its primary role is to create anLLMProviderinstance from a given configuration. It also provides metadata like the plugin name and configuration schema.-
querymt::plugin::http::HTTPLLMProviderFactory: A specialized factory for plugins that expose anHTTPLLMProvider. -
querymt::plugin::host::PluginRegistry: A central registry that discovers, loads, and managesLLMProviderFactoryinstances from a configuration file. It uses different loaders for different plugin types.querymt::plugin::host::PluginLoader: A trait for systems that can load a specificquerymt::plugin::host::PluginType. QueryMT provides implementations for:- Native Plugins: (
querymt::plugin::host::native::NativeLoader) Loads plugins from shared libraries (.so,.dll,.dylib). - WASM Plugins via Extism: (
querymt::plugin::extism_impl::host::ExtismLoader) Loads plugins compiled to WebAssembly and executed via Extism, offering sandboxing and portability.
- Native Plugins: (
- Sources:
crates/querymt/src/plugin/host/mod.rs,crates/querymt/src/plugin/host/native.rs,crates/querymt/src/plugin/extism_impl/host/loader.rs
Outbound HTTP Communication
- The
outbound.rsmodule provides a common function (fn@querymt::outbound::call_outbound) for making HTTP requests. This is used by HTTP-based providers and adapters. It's designed to work in both native environments (usingreqwest) and potentially WASM environments.- Source:
crates/querymt/src/outbound.rs
- Source:
Error Handling
- QueryMT defines a comprehensive
querymt::error::LLMErrorto represent various issues that can occur, such as HTTP errors, authentication problems, provider-specific errors, and plugin issues.- Source:
crates/querymt/src/error.rs
- Source:
High-Level Flow
- An application initializes a
querymt::plugin::host::PluginRegistryfrom a configuration file (e.g.,plugins.toml). - The application registers the desired loaders (e.g.,
NativeLoader,ExtismLoader) with the registry. - The registry calls
load_all_plugins(), which iterates through the configured providers. For each provider, it determines its type (e.g., local Wasm, OCI image, native library) and uses the appropriatePluginLoaderto load it and create anLLMProviderFactory. - The application uses
querymt::builder::LLMBuilderto configure a desired LLM provider by name (e.g., "openai", "custom-plugin"). - The builder's
build()method is called, passing a reference to thePluginRegistry. - The builder looks up the
LLMProviderFactoryfrom the registry using the provider name. - The factory's
from_config()method is called, which instantiates anLLMProvider(possibly anHTTPLLMProviderwrapped byLLMProviderFromHTTP). - If tools were added via
add_tool(), the base provider is wrapped in aquerymt::tool_decorator::ToolEnabledProvider. - If a validator is set, the provider is further wrapped in a
querymt::validated_llm::ValidatedLLM. - The application can then use the resulting
Box<dyn LLMProvider>instance to perform chat, completion, or embedding operations.
This layered and decoupled design makes QueryMT adaptable and easy to extend.