diff --git a/AGENTS.md b/AGENTS.md index 287de42b4..4e36424bc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -173,11 +173,11 @@ Found a bug, workaround, or pattern? Update the docs: - **Usage pattern?** → Add to [`docs/AGENTS_TEMPLATE.md`](docs/AGENTS_TEMPLATE.md) - **New pitfall?** → Add warning near relevant section -## 13. Working with Intrinsics +## 14. Working with Adapter Functions -Intrinsics are specialized LoRA adapters that add task-specific capabilities (RAG evaluation, safety checks, calibration, etc.) to Granite models. Mellea handles adapter loading and input formatting automatically — you just call the right function. +Adapter functions are specialized LoRA/aLoRA adapters that add task-specific capabilities (RAG evaluation, safety checks, calibration, etc.) to Granite models. Mellea handles adapter loading and input formatting automatically — you just call the right function. -### Using Intrinsics in Mellea +### Using Adapter Functions in Mellea **Prefer the high-level wrappers** in `mellea/stdlib/components/intrinsic/`. These handle adapter loading, context formatting, and output parsing for you: @@ -212,28 +212,28 @@ For lower-level control (custom adapters, model options), use `mfuncs.act()` wit ### Project Resources -- **Canonical catalog**: `mellea/backends/adapters/catalog.py` — source of truth for intrinsic names, HF repo IDs, and adapter types -- **Usage examples**: `docs/examples/intrinsics/` — working code for every intrinsic +- **Canonical catalog**: `mellea/backends/adapters/catalog.py` — source of truth for adapter function names, HF repo IDs, and adapter types +- **Usage examples**: `docs/examples/intrinsics/` — working code for every adapter function - **Helper functions**: `mellea/stdlib/components/intrinsic/rag.py` and `core.py` -### Adding New Intrinsics +### Adding New Adapter Functions -When adding support for a new intrinsic (not just using an existing one), fetch its README from Hugging Face first. Each README contains the authoritative spec for input/output format, intended use, and examples. +When adding support for a new adapter function (not just using an existing one), fetch its README from Hugging Face first. Each README contains the authoritative spec for input/output format, intended use, and examples. **Writing examples?** The HF READMEs also document intended usage patterns and example inputs — useful reference when writing code in `docs/examples/intrinsics/`. -| Repo | Purpose | Intrinsics | +| Repo | Purpose | Adapter functions | |------|---------|------------| | [`ibm-granite/granitelib-rag-r1.0`](https://huggingface.co/ibm-granite/granitelib-rag-r1.0) | RAG pipeline | answerability, citations, context_relevance, hallucination_detection, query_rewrite, query_clarification | | [`ibm-granite/granitelib-core-r1.0`](https://huggingface.co/ibm-granite/granitelib-core-r1.0) | Core capabilities | context-attribution, requirement-check, uncertainty | | [`ibm-granite/granitelib-guardian-r1.0`](https://huggingface.co/ibm-granite/granitelib-guardian-r1.0) | Safety & compliance | guardian-core, policy-guardrails, factuality-detection, factuality-correction | -**README URLs** — RAG intrinsics (no model subfolder): +**README URLs** — RAG adapter functions (no model subfolder): ``` https://huggingface.co/ibm-granite/granitelib-rag-r1.0/blob/main/{intrinsic_name}/README.md ``` -Core and Guardian intrinsics (include model subfolder): +Core and Guardian adapter functions (include model subfolder): ``` https://huggingface.co/ibm-granite/granitelib-{core,guardian,rag}-r1.0/blob/main/{intrinsic_name}/granite-4.1-{3b,8b,30b}/{lora,alora}/README.md ``` diff --git a/docs/docs/advanced/intrinsics.md b/docs/docs/advanced/intrinsics.md index 509f10f57..721985855 100644 --- a/docs/docs/advanced/intrinsics.md +++ b/docs/docs/advanced/intrinsics.md @@ -1,5 +1,5 @@ --- -title: "Intrinsics" +title: "Adapter functions" description: "Adapter-accelerated RAG quality checks using LoRA/aLoRA adapters with Granite models." # diataxis: how-to --- @@ -8,22 +8,22 @@ description: "Adapter-accelerated RAG quality checks using LoRA/aLoRA adapters w Silicon Mac recommended), or `pip install mellea` for OpenAIBackend with a [Granite Switch](/reference/glossary#granite-switch) model served via vLLM. -Intrinsics are adapter-accelerated operations for RAG quality checks. They use -LoRA/aLoRA adapters loaded directly into the HuggingFace backend — faster and more +Adapter functions are adapter-accelerated operations for RAG quality checks. They use +LoRA/aLoRA adapters loaded directly into the Hugging Face backend — faster and more reliable than prompting a general-purpose model for these specialized micro-tasks. -> **Backend note:** Intrinsics work with two backends: +> **Backend note:** Adapter functions work with two backends: > > - **LocalHFBackend** — loads LoRA/aLoRA adapters from the catalog at runtime. -> All intrinsics are available. Requires a GPU or Apple Silicon Mac. +> All adapter functions are available. Requires a GPU or Apple Silicon Mac. > - **OpenAIBackend** — uses a Granite Switch model served via vLLM with -> `load_embedded_adapters=True`. Only intrinsics embedded in the model are +> `load_embedded_adapters=True`. Only adapter functions embedded in the model are > available — check the model's `adapter_index.json` for the list. > See `docs/docs/examples/granite-switch/README.md` > -> Intrinsics do not work with Ollama or other remote backends. +> Adapter functions do not work with Ollama or other remote backends. -Set up the backend once and reuse it across intrinsic calls: +Set up the backend once and reuse it across adapter function calls: ```python # Requires: mellea[hf] @@ -209,7 +209,7 @@ print(result) # Maps each response sentence to supporting document sentences ``` -## Direct intrinsic usage +## Direct adapter function usage > **Advanced:** For custom adapter tasks, use the `Intrinsic` component and > `CustomIntrinsicAdapter` directly. @@ -249,14 +249,14 @@ print(out) # {"requirement_likelihood": 1.0} The `Intrinsic` component loads aLoRA adapters (falling back to LoRA) by task name. For OpenAI backends with Granite Switch, adapters are loaded from the model's -HuggingFace repository configuration instead of the intrinsic catalog. +Hugging Face repository configuration instead of the adapter function catalog. Output format is task-specific — `requirement-check` returns a likelihood score. --- -## Guardian Intrinsics +## Guardian adapter functions -Safety and factuality checks use a separate set of Guardian-specific intrinsics: +Safety and factuality checks use a separate set of Guardian-specific adapter functions: `guardian_check()`, `policy_guardrails()`, `factuality_detection()`, and `factuality_correction()`. These are documented in the [Safety Guardrails](../how-to/safety-guardrails) how-to guide. diff --git a/docs/docs/advanced/lora-and-alora-adapters.md b/docs/docs/advanced/lora-and-alora-adapters.md index fa0aad481..da5594530 100644 --- a/docs/docs/advanced/lora-and-alora-adapters.md +++ b/docs/docs/advanced/lora-and-alora-adapters.md @@ -18,9 +18,9 @@ Hugging Face account. > **Backend note:** Custom-trained adapters can only be loaded into `LocalHFBackend`. > They do not work with Ollama, OpenAI, or other remote backends. > -> Granite Switch models ship with pre-trained intrinsic adapters embedded in the +> Granite Switch models ship with pre-trained adapter functions embedded in the > model weights, which can be used via `OpenAIBackend` with -> `load_embedded_adapters=True`. See [Intrinsics](./intrinsics) for details. +> `load_embedded_adapters=True`. See [Adapter functions](./intrinsics.md) for details. ## LoRA vs aLoRA @@ -104,7 +104,7 @@ weights. Requires `HF_TOKEN` set or a prior `huggingface-cli login`. > data includes proprietary, confidential, or personal information. Language models can > memorize details from small domain-specific datasets. -If you intend to use the adapter as a Mellea intrinsic (so that it can be loaded by +If you intend to use the adapter as a Mellea adapter function (so that it can be loaded by model ID rather than local path), pass `--intrinsic` and provide an `io.yaml` file: ```bash @@ -160,7 +160,7 @@ backend.default_to_constraint_checking_alora = False Set it back to `True` to re-enable. This flag is per-backend instance and does not affect other sessions. -**See also:** [Intrinsics](./intrinsics) | +**See also:** [Adapter functions](./intrinsics.md) | [The Requirements System](../concepts/requirements-system) | [Write Custom Verifiers](../how-to/write-custom-verifiers) | [CLI Reference](../reference/cli) diff --git a/docs/docs/advanced/prefix-caching-and-kv-blocks.md b/docs/docs/advanced/prefix-caching-and-kv-blocks.md index 902ed9109..40832f2f6 100644 --- a/docs/docs/advanced/prefix-caching-and-kv-blocks.md +++ b/docs/docs/advanced/prefix-caching-and-kv-blocks.md @@ -131,6 +131,6 @@ Or pass `use_caches=False` at construction. The session behaviour is otherwise identical — disabling caching only affects whether prefill states are stored and reused. -**See also:** [HuggingFace Transformers](../integrations/huggingface) | -[Intrinsics](./intrinsics) | -[LoRA and aLoRA Adapters](./lora-and-alora-adapters) +**See also:** [Hugging Face Transformers](../integrations/huggingface.md) | +[Adapter functions](./intrinsics.md) | +[LoRA and aLoRA Adapters](./lora-and-alora-adapters.md) diff --git a/docs/docs/concepts/architecture-vs-agents.md b/docs/docs/concepts/architecture-vs-agents.md index 2eb434ce7..7d5f7e089 100644 --- a/docs/docs/concepts/architecture-vs-agents.md +++ b/docs/docs/concepts/architecture-vs-agents.md @@ -135,7 +135,7 @@ orchestrator: with [`ChatContext`](../reference/glossary#chatcontext) and the `@tool` decorator. See [Tools and Agents](../how-to/tools-and-agents). - **Guarded agents** — combine the ReACT pattern with `requirements` and - [Guardian Intrinsics](../how-to/safety-guardrails) to enforce safety constraints + [Guardian adapter functions](../how-to/safety-guardrails.md) to enforce safety constraints at every step. - **Structured outputs** — use `@generative` with Pydantic models or `Literal` types to enforce type-safe structured output at each step. See diff --git a/docs/docs/concepts/context-and-sessions.md b/docs/docs/concepts/context-and-sessions.md index b4f65895a..405d65268 100644 --- a/docs/docs/concepts/context-and-sessions.md +++ b/docs/docs/concepts/context-and-sessions.md @@ -40,7 +40,7 @@ The backend is responsible for: - Making the network or process call to the LLM - Parsing the response into a typed representation where applicable -Different backends — Ollama, OpenAI, HuggingFace, WatsonX — share the same +Different backends — Ollama, OpenAI, Hugging Face, WatsonX — share the same component interface. A `Component` does not know which backend will render it. ### Contexts diff --git a/docs/docs/examples/index.md b/docs/docs/examples/index.md index 8832273cc..f378a2652 100644 --- a/docs/docs/examples/index.md +++ b/docs/docs/examples/index.md @@ -61,7 +61,7 @@ to run. | Category | What it shows | | -------- | ------------- | -| `intrinsics/` | [Guardian Intrinsics](../how-to/safety-guardrails.md): `guardian_check()` for harm, jailbreak, social bias, groundedness; `policy_guardrails()`; `factuality_detection()` / `factuality_correction()` | +| `intrinsics/` | [Guardian adapter functions](../how-to/safety-guardrails.md): `guardian_check()` for harm, jailbreak, social bias, groundedness; `policy_guardrails()`; `factuality_detection()` / `factuality_correction()` | | `safety/` | *(Examples removed — see [Guardian how-to guide](../how-to/safety-guardrails.md) for the current API. The `RepairTemplateStrategy` gap is tracked in [#1071](https://github.com/generative-computing/mellea/issues/1071).)* | ### Integration and deployment diff --git a/docs/docs/getting-started/installation.md b/docs/docs/getting-started/installation.md index 95ea19843..14e600027 100644 --- a/docs/docs/getting-started/installation.md +++ b/docs/docs/getting-started/installation.md @@ -27,7 +27,7 @@ Install extras for specific backends and features: ```bash pip install "mellea[litellm]" # LiteLLM multi-provider (Anthropic, Bedrock, etc.) -pip install "mellea[hf]" # HuggingFace transformers for local inference +pip install "mellea[hf]" # Hugging Face Transformers for local inference pip install "mellea[watsonx]" # IBM WatsonX pip install "mellea[tools]" # Tool and agent dependencies (LangChain, smolagents) pip install "mellea[cli]" # m serve, m alora, m decompose CLI commands @@ -36,7 +36,7 @@ pip install "mellea[telemetry]" # OpenTelemetry tracing and metrics ```bash uv add "mellea[litellm]" # LiteLLM multi-provider (Anthropic, Bedrock, etc.) -uv add "mellea[hf]" # HuggingFace transformers for local inference +uv add "mellea[hf]" # Hugging Face Transformers for local inference uv add "mellea[watsonx]" # IBM WatsonX uv add "mellea[tools]" # Tool and agent dependencies (LangChain, smolagents) uv add "mellea[cli]" # m serve, m alora, m decompose CLI commands diff --git a/docs/docs/getting-started/quickstart.md b/docs/docs/getting-started/quickstart.md index 1e9f3dbd7..f58300c9a 100644 --- a/docs/docs/getting-started/quickstart.md +++ b/docs/docs/getting-started/quickstart.md @@ -186,7 +186,7 @@ multi-turn conversations. Pass `ctx=ChatContext()` to `start_session()` for stat chat. **Backends** — Pluggable model providers. Ollama is the default. OpenAI, [LiteLLM](../reference/glossary#litellm--litellmbackend), -HuggingFace, and WatsonX are also supported. See +Hugging Face, and WatsonX are also supported. See [Backends and Configuration](../how-to/backends-and-configuration). ## Troubleshooting diff --git a/docs/docs/how-to/backends-and-configuration.md b/docs/docs/how-to/backends-and-configuration.md index 8113d3e02..156698dad 100644 --- a/docs/docs/how-to/backends-and-configuration.md +++ b/docs/docs/how-to/backends-and-configuration.md @@ -1,6 +1,6 @@ --- title: "Backends and Configuration" -description: "Configure Mellea to use Ollama, OpenAI, LiteLLM, HuggingFace, or WatsonX backends." +description: "Configure Mellea to use Ollama, OpenAI, LiteLLM, Hugging Face, or WatsonX backends." # diataxis: how-to --- @@ -8,7 +8,7 @@ description: "Configure Mellea to use Ollama, OpenAI, LiteLLM, HuggingFace, or W or appropriate credentials for cloud backends. A backend is the engine that runs the LLM. Mellea ships with backends for Ollama, -OpenAI-compatible APIs, LiteLLM, HuggingFace transformers, and IBM WatsonX. You +OpenAI-compatible APIs, LiteLLM, Hugging Face Transformers, and IBM WatsonX. You configure the backend when you create a session. ## Default backend @@ -128,13 +128,13 @@ print(str(result)) # Output will vary — LLM responses depend on model and temperature. ``` -## HuggingFace backend +## Hugging Face backend > **Backend note:** Requires `pip install "mellea[hf]"`. Models are downloaded from -> HuggingFace Hub on first use. GPU recommended for reasonable inference speed. -> Required for [Intrinsics](../advanced/intrinsics). +> Hugging Face Hub on first use. GPU recommended for reasonable inference speed. +> Required for [Adapter functions](../advanced/intrinsics.md). -Run models locally using HuggingFace transformers: +Run models locally using Hugging Face Transformers: ```python # Requires: mellea[hf] diff --git a/docs/docs/how-to/safety-guardrails.md b/docs/docs/how-to/safety-guardrails.md index 2577adeb8..e4669b3c9 100644 --- a/docs/docs/how-to/safety-guardrails.md +++ b/docs/docs/how-to/safety-guardrails.md @@ -1,18 +1,18 @@ --- title: "Safety Guardrails" -description: "Use Guardian Intrinsics to detect harmful, biased, ungrounded, or policy-violating content in LLM outputs." +description: "Use Guardian adapter functions to detect harmful, biased, ungrounded, or policy-violating content in LLM outputs." # diataxis: how-to --- **Prerequisites:** `pip install "mellea[hf]"` for local inference; Apple Silicon or CUDA GPU recommended. -Guardian Intrinsics work via `LocalHFBackend` (local HuggingFace inference) or `OpenAIBackend` +Guardian adapter functions work via `LocalHFBackend` (local HuggingFace inference) or `OpenAIBackend` pointed at a Granite Switch endpoint. -Guardian Intrinsics evaluate LLM outputs for safety and quality using LoRA adapters -loaded directly into a HuggingFace backend — purpose-built for evaluation tasks, not +Guardian adapter functions evaluate LLM outputs for safety and quality using LoRA adapters +loaded directly into a Hugging Face backend — purpose-built for evaluation tasks, not general-purpose generation. -> **Generation vs evaluation:** Guardian Intrinsics evaluate content; they do not +> **Generation vs evaluation:** Guardian adapter functions evaluate content; they do not > generate responses. Your session's generation backend (Ollama, OpenAI, etc.) is > unchanged. A separate `LocalHFBackend` instance handles evaluation only. @@ -316,7 +316,7 @@ else: ## Limitations -Guardian Intrinsics return a numeric score (or label string) rather than a +Guardian adapter functions return a numeric score (or label string) rather than a [`Requirement`](../reference/glossary#requirement) instance, so they cannot be passed to `m.validate()` or wired into `RepairTemplateStrategy` the way the deprecated `GuardianCheck` could. The practical workaround is to call @@ -339,4 +339,4 @@ Guardian functions also do not emit `mellea.requirement` metrics — see > [`factuality_correction.py`](https://github.com/generative-computing/mellea/blob/main/docs/examples/intrinsics/factuality_correction.py), > and [`policy_guardrails.py`](https://github.com/generative-computing/mellea/blob/main/docs/examples/intrinsics/policy_guardrails.py). -**See also:** [Intrinsics](../advanced/intrinsics) | [LoRA and aLoRA Adapters](../advanced/lora-and-alora-adapters) | [Tutorial: Making Agents Reliable](../tutorials/making-agents-reliable) +**See also:** [Adapter functions](../advanced/intrinsics.md) | [LoRA and aLoRA Adapters](../advanced/lora-and-alora-adapters.md) | [Tutorial: Making Agents Reliable](../tutorials/04-making-agents-reliable.md) diff --git a/docs/docs/how-to/use-context-and-sessions.md b/docs/docs/how-to/use-context-and-sessions.md index 2b1039b9e..02a3d7e91 100644 --- a/docs/docs/how-to/use-context-and-sessions.md +++ b/docs/docs/how-to/use-context-and-sessions.md @@ -100,7 +100,7 @@ while keeping the session's backend and other configuration intact. Subclass `MelleaSession` and override any method to inject custom behavior. The example below gates all incoming chat messages through -[Guardian Intrinsics](../how-to/safety-guardrails) safety checks: +[Guardian adapter functions](../how-to/safety-guardrails.md) safety checks: ```python from typing import Literal diff --git a/docs/docs/integrations/huggingface.md b/docs/docs/integrations/huggingface.md index a46bfeed9..d1912595d 100644 --- a/docs/docs/integrations/huggingface.md +++ b/docs/docs/integrations/huggingface.md @@ -1,10 +1,10 @@ --- -title: "HuggingFace Transformers" -description: "Run Mellea on local hardware with LocalHFBackend and HuggingFace Transformers." +title: "Hugging Face Transformers" +description: "Run Mellea on local hardware with LocalHFBackend and Hugging Face Transformers." # diataxis: how-to --- -`LocalHFBackend` uses [HuggingFace Transformers](https://huggingface.co/docs/transformers) +`LocalHFBackend` uses [Hugging Face Transformers](https://huggingface.co/docs/transformers) for local inference. It is designed for experimental Mellea features — aLoRA adapters, constrained decoding, and span-based context — that are not yet available on server-based backends. @@ -83,13 +83,13 @@ See [Prefix Caching and KV Blocks](../advanced/prefix-caching-and-kv-blocks) for ## aLoRA adapters -`LocalHFBackend` supports [Activated LoRA (aLoRA)](../advanced/lora-and-alora-adapters) +`LocalHFBackend` supports [aLoRA](../advanced/lora-and-alora-adapters) adapters — lightweight domain-specific requirement validators that run on local GPU hardware. See the aLoRA guide for training and usage. -> **Tip:** For intrinsics without local GPU requirements, Granite Switch models +> **Tip:** For adapter functions without local GPU requirements, Granite Switch models > serve pre-embedded adapters via vLLM and the OpenAI backend. See -> [Intrinsics](../advanced/intrinsics) for details. +> [Adapter functions](../advanced/intrinsics.md) for details. ## Vision support diff --git a/docs/docs/integrations/openai.md b/docs/docs/integrations/openai.md index fba32f261..b37268c02 100644 --- a/docs/docs/integrations/openai.md +++ b/docs/docs/integrations/openai.md @@ -258,10 +258,10 @@ m = MelleaSession( > LiteLLM provides a verified integration — see > [Backends and Configuration](../how-to/backends-and-configuration). -## Intrinsics with Granite Switch +## Adapter functions with Granite Switch Granite Switch models embed LoRA/aLoRA adapters directly in the model weights. -When served via vLLM, these adapters enable intrinsic functions (RAG quality +When served via vLLM, these adapters enable adapter functions (RAG quality checks, safety evaluation, requirement validation) through the OpenAI-compatible API without loading adapter weights at runtime. @@ -290,13 +290,13 @@ backend = OpenAIBackend( ) ``` -The high-level intrinsic wrappers (`rag.check_answerability`, +The high-level adapter function wrappers (`rag.check_answerability`, `core.check_certainty`, etc.) work identically with this backend. See -[Intrinsics](../advanced/intrinsics) for the full list of available intrinsics. +[Adapter functions](../advanced/intrinsics.md) for the full list of available adapter functions. > **Note:** `load_embedded_adapters=True` downloads adapter I/O configurations -> from the model's HuggingFace repository on first use. No adapter weights are -> transferred — the adapters are already part of the model. Only intrinsics +> from the model's Hugging Face repository on first use. No adapter weights are +> transferred — the adapters are already part of the model. Only adapter functions > embedded in the model are available — check the model's `adapter_index.json` > for the list. @@ -316,7 +316,7 @@ backend = OpenAIBackend( load_embedded_adapters=False, ) -# Load a single adapter from the model's HuggingFace repo +# Load a single adapter from the model's Hugging Face repo adapters = EmbeddedIntrinsicAdapter.from_hub( IBM_GRANITE_SWITCH_4_1_3B_PREVIEW.hf_model_name, intrinsic_name="answerability", diff --git a/docs/docs/integrations/smolagents.md b/docs/docs/integrations/smolagents.md index 54e5f75a7..0d63317af 100644 --- a/docs/docs/integrations/smolagents.md +++ b/docs/docs/integrations/smolagents.md @@ -1,12 +1,12 @@ --- title: "smolagents" -description: "Use HuggingFace smolagents tools inside a Mellea session." +description: "Use Hugging Face smolagents tools inside a Mellea session." # diataxis: how-to --- `MelleaTool.from_smolagents()` wraps any [smolagents](https://huggingface.co/docs/smolagents) `Tool` instance so it can be passed to any [`MelleaSession`](../reference/glossary#melleasession) -call. The HuggingFace ecosystem provides many pre-built tools — `PythonInterpreterTool`, +call. The Hugging Face ecosystem provides many pre-built tools — `PythonInterpreterTool`, `DuckDuckGoSearchTool`, `WikipediaSearchTool`, and others. **Prerequisites:** `pip install 'mellea[smolagents]'` diff --git a/docs/docs/observability/metrics.md b/docs/docs/observability/metrics.md index 705a793c5..0371f4312 100644 --- a/docs/docs/observability/metrics.md +++ b/docs/docs/observability/metrics.md @@ -54,7 +54,7 @@ All token metrics include these attributes following Gen-AI semantic conventions | Ollama | Yes | Yes | `prompt_eval_count` and `eval_count` | | WatsonX | No | Yes | `input_token_count` and `generated_token_count` (streaming API limitation) | | LiteLLM | Yes | Yes | `usage.prompt_tokens` and `usage.completion_tokens` | -| HuggingFace | Yes | Yes | Calculated from input_ids and output sequences | +| Hugging Face | Yes | Yes | Calculated from input_ids and output sequences | ### Token recording timing @@ -193,7 +193,7 @@ is available. No code changes are required. Cost metrics use `litellm` (`mellea[litellm]`) as a pricing library. This is independent of the LiteLLM backend — pricing works with any Mellea backend, but cost is only recorded for models that `litellm` has pricing data for. Local and -private model IDs (Ollama, HuggingFace, custom deployments) will log a one-time +private model IDs (Ollama, Hugging Face, custom deployments) will log a one-time warning per model and produce no cost metric. Pricing is auto-enabled when `litellm` is installed. Use `MELLEA_PRICING_ENABLED` @@ -266,12 +266,12 @@ All sampling metrics include: | `requirement` | Requirement class name | `LLMaJRequirement`, `PythonExecutionReq`, `ALoraRequirement`, `GuardianCheck` *(deprecated v0.4)* | | `reason` | Human-readable failure reason (`mellea.requirement.failures` only) | `"Output did not satisfy constraint"`, `"unknown"` | -> **Guardian Intrinsics and metrics:** `guardian_check()`, `policy_guardrails()`, +> **Guardian adapter functions and metrics:** `guardian_check()`, `policy_guardrails()`, > `factuality_detection()`, and `factuality_correction()` are not `Requirement` > subclasses and do not emit `mellea.requirement.checks` or > `mellea.requirement.failures` metrics. If you migrate from `GuardianCheck` to -> Guardian Intrinsics, Guardian-related requirement counters will stop appearing -> in your metrics. Wrap Guardian Intrinsic calls in a custom `Requirement` subclass +> Guardian adapter functions, Guardian-related requirement counters will stop appearing +> in your metrics. Wrap Guardian adapter function calls in a custom `Requirement` subclass > if you need to preserve this telemetry. ### Tool counter diff --git a/docs/docs/reference/glossary.md b/docs/docs/reference/glossary.md index fb9903086..db4cd0975 100644 --- a/docs/docs/reference/glossary.md +++ b/docs/docs/reference/glossary.md @@ -22,13 +22,48 @@ See: [act() and aact()](/how-to/act-and-aact) --- -## aLoRA (Activated LoRA) +## Adapter -An **Activated LoRA** (aLoRA) is a LoRA adapter dynamically loaded by -`LocalHFBackend` at inference time to serve as a lightweight requirement verifier. -Instead of running a full LLM call to check a requirement, the adapter is activated on the same model weights already in memory. [Granite Switch](#granite-switch) models embed these adapters directly in the model weights, enabling intrinsic functions via `OpenAIBackend` without runtime adapter loading. +Informal shorthand for **[adapter function](#adapter-function)**. Acceptable in brief +references (e.g. code comments, table cells). Use the full term "adapter function" in +user-facing prose, documentation, and API descriptions. -See: [LoRA and aLoRA Adapters](../advanced/lora-and-alora-adapters) +--- + +## Adapter function + +An adapter function is a small, task-specific model component with a predictable structured +output. Adapter functions are implemented as LoRA or [aLoRA](#alora) adapters on top of a +base Granite model and expose a typed interface (input prompt + parsed output) through +Mellea's `Intrinsic` class and its high-level wrappers. Examples include answerability +checking, requirement verification, and hallucination detection. + +In prose and documentation, prefer "adapter function" over "intrinsic" or "intrinsic +function". The Python symbol `Intrinsic` is the current implementation name; see +[Intrinsic](#intrinsic). + +**Informal shorthand:** [Adapter](#adapter) (acceptable in brief references, avoid in +user-facing text where precision matters). + +See: [Adapter Functions](../advanced/intrinsics.md) + +--- + +## aLoRA + +aLoRA (Activated LoRA) is a LoRA adapter variant designed for fast inner-loop checks +such as requirement validation. Unlike a standard LoRA, which processes the full context +on every call, an aLoRA activates at a single invocation token — so the base model's +KV cache for the preceding context is reused rather than recomputed. This makes the +inference overhead minimal: only the activation token and the adapter's output tokens +need a forward pass, not the full prompt. + +In a [Granite Switch](#granite-switch) model, multiple aLoRA adapter functions are +embedded together and share the base model's KV cache across calls. This means serving +multiple adapter functions produces more cache hits than running equivalent separate LoRA +loads, lowering latency and memory pressure for the full serving deployment. + +See: [LoRA and aLoRA Adapters](../advanced/lora-and-alora-adapters.md) --- @@ -99,6 +134,27 @@ See: [Mellea Core Internals](../advanced/mellea-core-internals) --- +## Capability + +A capability is what an [adapter function](#adapter-function) does — for example, +`"answerability"` or `"requirement-check"`. Capability strings are used to look up +the right adapter at runtime and are listed in the adapter function catalog +(`mellea/backends/adapters/catalog.py`). Prefer "capability" over "feature" when +describing what an adapter function provides. + +See: `mellea.backends.adapters.capabilities.KNOWN_CAPABILITIES` + +--- + +## Checkpoint + +A checkpoint is a self-contained, ready-to-run model file produced by the +[Granite Switch](#granite-switch) composer. It bundles a base Granite model together +with all its embedded [adapter function](#adapter-function) weights into a single +deployable artefact. Deploying a Granite Switch model means deploying its checkpoint. + +--- + ## Component A `Component` is a reusable, composable unit in Mellea that encapsulates a prompt @@ -211,6 +267,24 @@ See: [Evaluate with LLM-as-a-Judge](../how-to/evaluate-with-llm-as-a-judge) --- +## Granite Libraries + +Granite Libraries is the collective name for the three curated collections of +[adapter functions](#adapter-function) published by IBM Granite: + +| Collection | Purpose | +|-----------|---------| +| **Granite Libraries Core** | General-purpose capabilities: certainty checking, requirement verification, context attribution | +| **Granite Libraries RAG** | Retrieval-Augmented Generation pipeline: answerability, citations, context relevance, hallucination detection, query rewriting | +| **Granite Libraries Guardian** | Safety and compliance: guardian checks, policy guardrails, factuality detection and correction | + +These adapter functions are distributed as Hugging Face repositories under +`ibm-granite/granitelib-{core,rag,guardian}-r1.0` and can be used with Mellea +via `LocalHFBackend` (runtime loading) or embedded in a +[Granite Switch](#granite-switch) checkpoint. + +--- + ## Hook / HookType A **hook** is an async function that intercepts a specific event in Mellea's @@ -305,7 +379,7 @@ See: [Safety Guardrails](../how-to/safety-guardrails) ## factuality_correction() -A Guardian Intrinsic function that generates a corrected version of the assistant's +A Guardian adapter function that generates a corrected version of the assistant's last response grounded in the documents provided in context. Returns whatever the model emits as a `str` — typically the corrected text. The model may emit `"none"` when no correction is needed, but this is a model-side convention, not part of the @@ -321,7 +395,7 @@ See: [Safety Guardrails](../how-to/safety-guardrails#factuality-correction) ## factuality_detection() -A Guardian Intrinsic function that evaluates whether the assistant's last response +A Guardian adapter function that evaluates whether the assistant's last response is factually consistent with the documents in context. Returns `"yes"` if the response contains factual errors, or `"no"` if it is consistent. @@ -335,7 +409,7 @@ See: [Safety Guardrails](../how-to/safety-guardrails#factuality-detection) ## guardian_check() -A Guardian Intrinsic function that evaluates the last message from a given role in +A Guardian adapter function that evaluates the last message from a given role in a `ChatContext` against a safety or quality criterion. Returns a `float` score from `0.0` (no risk) to `1.0` (risk detected); values at or above `0.5` indicate risk. @@ -356,11 +430,11 @@ See: [Safety Guardrails](../how-to/safety-guardrails) > **Deprecated as of v0.4.** Use [`guardian_check()`](#guardian_check), > [`policy_guardrails()`](#policy_guardrails), or -> [`factuality_detection()`](#factuality_detection) from the Guardian Intrinsics +> [`factuality_detection()`](#factuality_detection) from the Guardian adapter functions > instead. See [Safety Guardrails](../how-to/safety-guardrails). A deprecated `Requirement` subclass that validates LLM outputs using a separately loaded -Granite Guardian model. Requires an independent Ollama or HuggingFace backend +Granite Guardian model. Requires an independent Ollama or Hugging Face backend for the Guardian model. See: [Safety Guardrails](../how-to/safety-guardrails) @@ -381,7 +455,7 @@ See: [Safety Guardrails](../how-to/safety-guardrails) ## policy_guardrails() -A Guardian Intrinsic function that checks whether a scenario complies with a +A Guardian adapter function that checks whether a scenario complies with a natural-language policy. Returns `"Yes"` (compliant), `"No"` (non-compliant), or `"Ambiguous"` (insufficient information to decide). @@ -395,11 +469,30 @@ See: [Safety Guardrails](../how-to/safety-guardrails#policy-compliance) ## Granite Switch -A Granite model variant with LoRA and aLoRA adapters pre-baked into the model weights. When served via vLLM and accessed through `OpenAIBackend` with `load_embedded_adapters=True`, these embedded adapters enable [Intrinsics](../advanced/intrinsics) (RAG quality checks, requirement validation, safety evaluation) without runtime adapter loading. Only intrinsics embedded in the model are available — check the model's `adapter_index.json`. +Granite Switch is the architecture and toolchain for composing adapter functions into a +single deployable Granite model. The composer embeds LoRA/aLoRA adapter function weights +directly into a base Granite model checkpoint, producing a self-contained model file that +carries its adapter functions with it. When that checkpoint is served via vLLM and +accessed through `OpenAIBackend` with `load_embedded_adapters=True`, adapter functions +are available without runtime adapter loading. Only adapter functions embedded in the +checkpoint are available — check the model's `adapter_index.json`. + +The resulting model file is sometimes called a **Granite Switch checkpoint** or simply a +**checkpoint**. The toolchain that produces it is the **Granite Switch composer**. + +See: [Official Granite Switch Repository](https://github.com/generative-computing/granite-switch) | +[Adapter Functions](../advanced/intrinsics.md) | +[OpenAI and OpenAI-Compatible APIs](../integrations/openai.md) + +--- + +## Granite Switch composer -See: [Official Granite Switch Documentation](https://github.com/generative-computing/granite-switch) | -[Intrinsics](../advanced/intrinsics) | -[OpenAI and OpenAI-Compatible APIs](../integrations/openai) +The Granite Switch composer is the toolchain component that embeds +[adapter function](#adapter-function) weights into a base Granite model, +producing a [Granite Switch](#granite-switch) [checkpoint](#checkpoint). It is +distinct from the runtime: the composer runs offline to produce the checkpoint; +Mellea and vLLM consume the checkpoint at inference time. --- @@ -470,9 +563,19 @@ See: [Use Images and Vision Models](../how-to/use-images-and-vision) ## Intrinsic -An `Intrinsic` is a backend-level primitive in Mellea — a structured generation operation with special handling (e.g., constrained decoding, RAG retrieval). `LocalHFBackend` exposes Intrinsics via runtime adapter loading. `OpenAIBackend` supports Intrinsics when backed by a [Granite Switch](#granite-switch) model with `load_embedded_adapters=True`. +`Intrinsic` is the current Python class name for an **[adapter function](#adapter-function)** +in Mellea's implementation. It is a backend-level primitive — a structured generation +operation backed by a LoRA/aLoRA adapter with special input/output handling (e.g., +constrained decoding, RAG retrieval). `LocalHFBackend` loads `Intrinsic` adapters at +runtime; `OpenAIBackend` uses them when backed by a [Granite Switch](#granite-switch) +checkpoint with `load_embedded_adapters=True`. -See: [Intrinsics](../advanced/intrinsics) +> **Note:** The Python symbol `Intrinsic` (and related classes such as `IntrinsicAdapter`) +> will be renamed to `AdapterFunction` / `Adapter` in a future phase of Epic #929 +> (#1136). Prefer the term **adapter function** in prose and documentation; use `Intrinsic` +> only when referencing the current Python API directly. + +See: [Adapter Functions](../advanced/intrinsics.md) --- @@ -507,6 +610,15 @@ See: [Instruct, Validate, Repair](../concepts/instruct-validate-repair) --- +## Mellea + +Mellea is the open-source Python library for building reliable, testable LLM +applications. It orchestrates [Granite Switch](#granite-switch) +[adapter functions](#adapter-function) as ordinary typed Python calls — +structured inputs, structured outputs, built-in validation. + +--- + ## MelleaSession The primary entry point for Mellea. A `MelleaSession` wraps a backend and provides @@ -893,3 +1005,14 @@ than the sum of all calls. Use `SimpleContext` (the default) when calling `wait_for_all_mots`; concurrent writes to `ChatContext` can corrupt state. See: [Tutorial 02: Streaming and Async](/tutorials/streaming-and-async) + +--- + +## References + +External resources for the key technologies underlying Mellea's adapter function system: + +- **Granite Switch**: [github.com/generative-computing/granite-switch](https://github.com/generative-computing/granite-switch) — the architecture and composer toolchain for building Granite Switch checkpoints. +- **Granite Libraries Core**: [huggingface.co/ibm-granite/granitelib-core-r1.0](https://huggingface.co/ibm-granite/granitelib-core-r1.0) — certainty, requirement-check, context-attribution adapter functions. +- **Granite Libraries RAG**: [huggingface.co/ibm-granite/granitelib-rag-r1.0](https://huggingface.co/ibm-granite/granitelib-rag-r1.0) — answerability, citations, context relevance, hallucination detection, query rewriting. +- **Granite Libraries Guardian**: [huggingface.co/ibm-granite/granitelib-guardian-r1.0](https://huggingface.co/ibm-granite/granitelib-guardian-r1.0) — guardian checks, policy guardrails, factuality detection and correction. diff --git a/docs/docs/troubleshooting/common-errors.md b/docs/docs/troubleshooting/common-errors.md index b38e30264..b6ec0293d 100644 --- a/docs/docs/troubleshooting/common-errors.md +++ b/docs/docs/troubleshooting/common-errors.md @@ -53,7 +53,7 @@ Please install them with: pip install 'mellea[hf]' Each backend has an optional extras group. Install what you need: ```bash -pip install "mellea[hf]" # HuggingFace / local inference +pip install "mellea[hf]" # Hugging Face / local inference pip install "mellea[litellm]" # LiteLLM multi-provider pip install "mellea[watsonx]" # IBM WatsonX pip install "mellea[tools]" # Tool / agent dependencies @@ -177,7 +177,7 @@ If the model is not calling tools as expected: - Check the tool's docstring — the model uses it to decide when to call the tool. A vague or absent docstring leads to poor tool selection. - Use `guardian_check(context, backend, criteria="function_call")` from the - [Guardian Intrinsics](../how-to/safety-guardrails) to detect function call + [Guardian adapter functions](../how-to/safety-guardrails.md) to detect function call hallucinations. --- @@ -212,10 +212,10 @@ nest_asyncio.apply() ## Guardian / safety validation -Guardian Intrinsics (`guardian_check()`, `policy_guardrails()`, +Guardian adapter functions (`guardian_check()`, `policy_guardrails()`, `factuality_detection()`, `factuality_correction()`) require `LocalHFBackend` with an IBM Granite model. -See [Safety Guardrails](../how-to/safety-guardrails) for full usage. +See [Safety Guardrails](../how-to/safety-guardrails.md) for full usage. ### `guardian_check()` returns unexpected scores @@ -230,11 +230,11 @@ See [Safety Guardrails](../how-to/safety-guardrails) for full usage. ```text DeprecationWarning: GuardianCheck is deprecated as of version 0.4. -Use the Guardian Intrinsics instead +Use the Guardian adapter functions instead ``` -Replace `GuardianCheck` / `GuardianRisk` imports with the Guardian Intrinsics API. -See [Safety Guardrails](../how-to/safety-guardrails) for migration guidance. +Replace `GuardianCheck` / `GuardianRisk` imports with the Guardian adapter functions API. +See [Safety Guardrails](../how-to/safety-guardrails.md) for migration guidance. --- @@ -250,4 +250,4 @@ See [Safety Guardrails](../how-to/safety-guardrails) for migration guidance. **See also:** [Quick Start](../getting-started/quickstart) | [Inference-Time Scaling](../advanced/inference-time-scaling) | -[Safety Guardrails](../how-to/safety-guardrails) +[Safety Guardrails](../how-to/safety-guardrails.md) diff --git a/docs/docs/troubleshooting/faq.md b/docs/docs/troubleshooting/faq.md index 5550ea325..4170fa4af 100644 --- a/docs/docs/troubleshooting/faq.md +++ b/docs/docs/troubleshooting/faq.md @@ -73,14 +73,14 @@ m = MelleaSession( ## Can I use Mellea without Ollama? Yes. Ollama is the default backend but not the only one. Mellea ships with -backends for OpenAI-compatible APIs, HuggingFace local inference, IBM WatsonX, +backends for OpenAI-compatible APIs, Hugging Face local inference, IBM WatsonX, and LiteLLM (which itself proxies dozens of providers). Install the backend you need: ```bash pip install "mellea[litellm]" # LiteLLM multi-provider -pip install "mellea[hf]" # HuggingFace / local inference +pip install "mellea[hf]" # Hugging Face / local inference pip install "mellea[watsonx]" # IBM WatsonX ``` diff --git a/docs/docs/tutorials/04-making-agents-reliable.md b/docs/docs/tutorials/04-making-agents-reliable.md index 13cf33fe4..a25653e77 100644 --- a/docs/docs/tutorials/04-making-agents-reliable.md +++ b/docs/docs/tutorials/04-making-agents-reliable.md @@ -289,7 +289,7 @@ debugging or for choosing the best available output when the budget runs out. ## Step 4: Adding Guardian harm detection -Guardian intrinsics evaluate the output against specific risk criteria. Run them +Guardian adapter functions evaluate the output against specific risk criteria. Run them after your agent responds to flag outputs before they reach downstream code. ```python @@ -358,7 +358,7 @@ response = m.instruct( output_text = str(response) -# Guardian intrinsics require a LocalHFBackend — they load LoRA adapters +# Guardian adapter functions require a LocalHFBackend — they load LoRA adapters # that are not supported by OllamaModelBackend. guardian_backend = LocalHFBackend(model_id="ibm-granite/granite-4.1-3b") @@ -390,7 +390,7 @@ and dynamic applications with ease. The word "Mellea" consists of 6 characters. ``` -> **Note:** Guardian intrinsics load LoRA adapters and require `LocalHFBackend`. +> **Note:** Guardian adapter functions load LoRA adapters and require `LocalHFBackend`. > They cannot run against `OllamaModelBackend`. The main agent and the Guardian > checks can use different backends — only the Guardian calls need `LocalHFBackend`. diff --git a/mellea/backends/adapters/adapter.py b/mellea/backends/adapters/adapter.py index cc6c9c6b1..310197f33 100644 --- a/mellea/backends/adapters/adapter.py +++ b/mellea/backends/adapters/adapter.py @@ -1,10 +1,10 @@ """Adapter classes for adding fine-tuned modules to inference backends. Defines the abstract ``Adapter`` base class and its concrete subclasses -``LocalHFAdapter`` (for locally loaded HuggingFace models) and ``IntrinsicAdapter`` -(for adapters whose metadata is stored in Mellea's intrinsic catalog). Also provides -``get_adapter_for_intrinsic`` for resolving the right adapter class given an -intrinsic name, and ``AdapterMixin`` for backends that support runtime adapter +``LocalHFAdapter`` (for locally loaded Hugging Face models) and ``IntrinsicAdapter`` +(for adapters whose metadata is stored in Mellea's adapter function catalog). Also +provides ``get_adapter_for_intrinsic`` for resolving the right adapter class given an +adapter function name, and ``AdapterMixin`` for backends that support runtime adapter loading and unloading. """ @@ -56,7 +56,7 @@ def __init__(self, name: str, adapter_type: AdapterType): class LocalHFAdapter(Adapter): - """Abstract adapter subclass for locally loaded HuggingFace model backends. + """Abstract adapter subclass for locally loaded Hugging Face model backends. Subclasses must implement ``get_local_hf_path`` to return the filesystem path from which adapter weights should be loaded given a base model name. @@ -68,7 +68,7 @@ def get_local_hf_path(self, base_model_name: str) -> str: Args: base_model_name (str): The base model name; typically the last component - of the HuggingFace model ID (e.g. ``"granite-4.0-micro"``). + of the Hugging Face model ID (e.g. ``"granite-4.0-micro"``). Returns: str: Filesystem path to the adapter weights directory. @@ -77,36 +77,36 @@ def get_local_hf_path(self, base_model_name: str) -> str: class IntrinsicAdapter(LocalHFAdapter): - """Base class for adapters that implement intrinsics. + """Base class for adapters that implement adapter functions. Subtype of :class:`Adapter` for models that: - * implement intrinsic functions + * implement adapter functions * are packaged as LoRA or aLoRA adapters on top of a base model * use the shared model loading code in ``mellea.formatters.granite.intrinsics`` * use the shared input and output processing code in ``mellea.formatters.granite.intrinsics`` Args: - intrinsic_name (str): Name of the intrinsic (e.g. ``"answerability"``); the - adapter's ``qualified_name`` will be derived from this. + intrinsic_name (str): Name of the adapter function (e.g. ``"answerability"``); + the adapter's ``qualified_name`` will be derived from this. adapter_type (AdapterType): Enum describing the adapter type; defaults to ``AdapterType.ALORA``. config_file (str | pathlib.Path | None): Path to a YAML config file defining - the intrinsic's I/O transformations; mutually exclusive with + the adapter function's I/O transformations; mutually exclusive with ``config_dict``. - config_dict (dict | None): Dict defining the intrinsic's I/O transformations; - mutually exclusive with ``config_file``. + config_dict (dict | None): Dict defining the adapter function's I/O + transformations; mutually exclusive with ``config_file``. base_model_name (str | None): Base model name used to look up the I/O processing config when neither ``config_file`` nor ``config_dict`` are provided. Attributes: - intrinsic_name (str): Name of the intrinsic this adapter implements. - intrinsic_metadata (IntriniscsCatalogEntry): Catalog metadata for the intrinsic. + intrinsic_name (str): Name of the adapter function this adapter implements. + intrinsic_metadata (IntriniscsCatalogEntry): Catalog metadata for the adapter function. base_model_name (str | None): Base model name provided at construction, if any. adapter_type (AdapterType): The adapter type (``LORA`` or ``ALORA``). - config (dict): Parsed I/O transformation configuration for the intrinsic. + config (dict): Parsed I/O transformation configuration for the adapter function. """ def __init__( @@ -117,7 +117,7 @@ def __init__( config_dict: dict | None = None, base_model_name: str | None = None, ): - """Initialize IntrinsicAdapter for the named intrinsic, loading its I/O configuration.""" + """Initialize IntrinsicAdapter for the named adapter function, loading its I/O configuration.""" super().__init__(intrinsic_name, adapter_type) self.intrinsic_name = intrinsic_name @@ -126,14 +126,14 @@ def __init__( if adapter_type not in self.intrinsic_metadata.adapter_types: raise ValueError( - f"Intrinsic '{intrinsic_name}' not available as an adapter of type " + f"Adapter function '{intrinsic_name}' not available as an adapter of type " f"'{adapter_type}. Available types are " f"{self.intrinsic_metadata.adapter_types}." ) self.adapter_type = adapter_type # If any of the optional params are specified, attempt to set up the - # config for the intrinsic here. + # config for the adapter function here. if config_file and config_dict: raise ValueError( f"Conflicting values for config_file and config_dict " @@ -155,7 +155,7 @@ def __init__( ) is_alora = self.adapter_type == AdapterType.ALORA # TODO(phase-2.2): pass revision=self.intrinsic_metadata.revision - # once revision-aware prepare() lands (issue #1141 / epic #929). + # once revision-aware prepare() is merged (issue #1141 / epic #929). config_file = intrinsics.obtain_io_yaml( self.intrinsic_name, self.base_model_name, @@ -180,7 +180,7 @@ def get_local_hf_path(self, base_model_name: str) -> str: Args: base_model_name (str): The base model name; typically the last component - of the HuggingFace model ID (e.g. ``"granite-3.3-8b-instruct"``). + of the Hugging Face model ID (e.g. ``"granite-3.3-8b-instruct"``). Returns: str: Filesystem path to the downloaded adapter weights directory. @@ -188,7 +188,7 @@ def get_local_hf_path(self, base_model_name: str) -> str: return self.download_and_get_path(base_model_name) def download_and_get_path(self, base_model_name: str) -> str: - """Downloads the required rag intrinsics files if necessary and returns the path to them. + """Downloads the required RAG adapter function files if necessary and returns the path to them. Args: base_model_name: the base model; typically the last part of the huggingface @@ -199,7 +199,7 @@ def download_and_get_path(self, base_model_name: str) -> str: """ is_alora = self.adapter_type == AdapterType.ALORA # TODO(phase-2.2): pass revision=self.intrinsic_metadata.revision once - # revision-aware prepare() lands (issue #1141 / epic #929). + # revision-aware prepare() is merged (issue #1141 / epic #929). return str( intrinsics.obtain_lora( self.intrinsic_name, @@ -218,12 +218,12 @@ def get_adapter_for_intrinsic( intrinsic_adapter_types: list[AdapterType] | tuple[AdapterType, ...], available_adapters: dict[str, T], ) -> T | None: - """Find an adapter from a dict of available adapters based on the intrinsic name and its allowed adapter types. + """Find an adapter from a dict of available adapters based on the adapter function name and its allowed adapter types. Args: - intrinsic_name (str): The name of the intrinsic, e.g. ``"answerability"``. + intrinsic_name (str): The name of the adapter function, e.g. ``"answerability"``. intrinsic_adapter_types (list[AdapterType] | tuple[AdapterType, ...]): The - adapter types allowed for this intrinsic, e.g. + adapter types allowed for this adapter function, e.g. ``[AdapterType.ALORA, AdapterType.LORA]``. available_adapters (dict[str, T]): The available adapters to choose from; maps ``adapter.qualified_name`` to the adapter object. @@ -309,7 +309,7 @@ def list_adapters(self) -> list[str]: class EmbeddedIntrinsicAdapter(Adapter): - """Adapter for intrinsics embedded in a Granite Switch model. + """Adapter for adapter functions embedded in a Granite Switch model. Unlike PEFT-based adapters that are loaded into the model at runtime, embedded adapters are already baked into the model weights and activated @@ -318,7 +318,7 @@ class EmbeddedIntrinsicAdapter(Adapter): downloaded or loaded. Args: - intrinsic_name (str): Name of the intrinsic (e.g. ``"answerability"``). + intrinsic_name (str): Name of the adapter function (e.g. ``"answerability"``). config (dict): Parsed I/O transformation configuration (from ``io.yaml``). technology (str): Adapter technology in the switch model — ``"lora"`` or ``"alora"``. Determines where the control token is placed in the @@ -326,13 +326,13 @@ class EmbeddedIntrinsicAdapter(Adapter): prompt for aLoRA). Attributes: - intrinsic_name (str): Name of the intrinsic this adapter implements. + intrinsic_name (str): Name of the adapter function this adapter implements. config (dict): Parsed I/O transformation configuration. technology (str): ``"lora"`` or ``"alora"``. """ def __init__(self, intrinsic_name: str, config: dict, technology: str = "lora"): - """Initialize an embedded intrinsic adapter with its I/O config.""" + """Initialize an embedded adapter function with its I/O config.""" if technology not in ("lora", "alora"): raise ValueError( f"technology must be 'lora' or 'alora', got '{technology}'" @@ -356,7 +356,7 @@ def from_model_directory( model_path (str | pathlib.Path): Path to a Granite Switch model directory that contains ``adapter_index.json`` and ``io_configs/``. intrinsic_name (str | None): If provided, only load the adapter - matching this intrinsic name. ``None`` loads all adapters. + matching this adapter function name. ``None`` loads all adapters. Returns: list[EmbeddedIntrinsicAdapter]: One adapter per entry in the index. @@ -390,7 +390,7 @@ def from_model_directory( io_config_path = model_path / io_config_rel if not io_config_path.exists(): raise ValueError( - f"io.yaml for intrinsic '{entry_name}' " + f"io.yaml for adapter function '{entry_name}' " f"not found at {io_config_path}" ) @@ -408,7 +408,7 @@ def from_model_directory( if not adapters: if intrinsic_name is not None: raise ValueError( - f"No adapter found for intrinsic '{intrinsic_name}' in {model_path}" + f"No adapter found for adapter function '{intrinsic_name}' in {model_path}" ) raise ValueError(f"No adapters found in {model_path}") @@ -421,18 +421,18 @@ def from_hub( cache_dir: str | None = None, intrinsic_name: str | None = None, ) -> list["EmbeddedIntrinsicAdapter"]: - """Load embedded adapters from a Granite Switch model on HuggingFace Hub. + """Load embedded adapters from a Granite Switch model on Hugging Face Hub. Downloads ``adapter_index.json`` and the ``io_configs/`` directory, then delegates to :meth:`from_model_directory`. Args: - repo_id (str): HuggingFace Hub repository ID + repo_id (str): Hugging Face Hub repository ID (e.g. ``"ibm-granite/granite-switch-micro"``). revision (str): Git revision to download from. cache_dir (str | None): Local cache directory; ``None`` for the default. intrinsic_name (str | None): If provided, only load the adapter - matching this intrinsic name. ``None`` loads all adapters. + matching this adapter function name. ``None`` loads all adapters. Returns: list[EmbeddedIntrinsicAdapter]: One adapter per entry in the index. @@ -449,7 +449,7 @@ def from_hub( except ImportError as e: raise ImportError( "huggingface_hub is required to download embedded adapter configs from " - 'HuggingFace Hub. Please install it with: pip install "mellea[switch]"' + 'Hugging Face Hub. Please install it with: pip install "mellea[switch]"' ) from e local_root = huggingface_hub.snapshot_download( @@ -465,7 +465,7 @@ def from_hub( except ValueError as e: if intrinsic_name is not None: raise ValueError( - f"No adapter found for intrinsic '{intrinsic_name}' in {repo_id}" + f"No adapter found for adapter function '{intrinsic_name}' in {repo_id}" ) from e raise ValueError(f"No adapters found in {repo_id}") from e @@ -476,18 +476,18 @@ def from_source( cache_dir: str | None = None, intrinsic_name: str | None = None, ) -> list["EmbeddedIntrinsicAdapter"]: - """Load embedded adapters from a local directory or HuggingFace Hub. + """Load embedded adapters from a local directory or Hugging Face Hub. Automatically detects whether ``source`` is a local filesystem path - or a HuggingFace Hub repo ID, and delegates accordingly. + or a Hugging Face Hub repo ID, and delegates accordingly. Args: - source (str): Local path to a model directory, or a HuggingFace + source (str): Local path to a model directory, or a Hugging Face Hub repo ID (e.g. ``"ibm-granite/granite-switch-micro"``). revision (str): Git revision (only used for Hub downloads). cache_dir (str | None): Cache directory (only used for Hub downloads). intrinsic_name (str | None): If provided, only load the adapter - matching this intrinsic name. ``None`` loads all adapters. + matching this adapter function name. ``None`` loads all adapters. Returns: list[EmbeddedIntrinsicAdapter]: One adapter per entry in the index. @@ -505,9 +505,9 @@ def from_source( class CustomIntrinsicAdapter(IntrinsicAdapter): - """Special class for users to subclass when creating custom intrinsic adapters. + """Special class for users to subclass when creating custom adapter functions. - The documentation says that any developer who creates an intrinsic should create + The documentation says that any developer who creates an adapter function should create a subclass of this class. Creating a subclass of this class appears to be a cosmetic boilerplate development task that isn't actually necessary for any existing use case. @@ -517,9 +517,9 @@ class CustomIntrinsicAdapter(IntrinsicAdapter): temporary hack. Args: - model_id (str): The HuggingFace model ID used for downloading model weights; + model_id (str): The Hugging Face model ID used for downloading model weights; expected format is ``"/"``. - intrinsic_name (str | None): Catalog name for the intrinsic; defaults to the + intrinsic_name (str | None): Catalog name for the adapter function; defaults to the repository name portion of ``model_id`` if not provided. base_model_name (str): The short name of the base model (NOT its repo ID). """ @@ -527,7 +527,7 @@ class CustomIntrinsicAdapter(IntrinsicAdapter): def __init__( self, *, model_id: str, intrinsic_name: str | None = None, base_model_name: str ): - """Initialize CustomIntrinsicAdapter and patch the global intrinsics catalog if needed.""" + """Initialize CustomIntrinsicAdapter and patch the global adapter function catalog if needed.""" assert re.match(".*/.*", model_id), ( "expected a huggingface model id with format /" ) diff --git a/mellea/backends/adapters/capabilities.py b/mellea/backends/adapters/capabilities.py index 4078b6f9d..680ed33e5 100644 --- a/mellea/backends/adapters/capabilities.py +++ b/mellea/backends/adapters/capabilities.py @@ -1,9 +1,9 @@ """Advisory registry of known adapter capabilities. :data:`KNOWN_CAPABILITIES` is a frozenset of capability strings derived from the -intrinsics catalog. It is advisory only: callers are warned (not rejected) when a +adapter function catalog. It is advisory only: callers are warned (not rejected) when a capability outside this set is used, so that custom adapters and pre-release -intrinsics are not blocked. +adapter functions are not blocked. Deriving from the catalog (rather than hand-copying) keeps the two registries in sync automatically — adding a new entry to ``catalog.py`` automatically registers diff --git a/mellea/backends/adapters/catalog.py b/mellea/backends/adapters/catalog.py index 11f858dfb..f45599a36 100644 --- a/mellea/backends/adapters/catalog.py +++ b/mellea/backends/adapters/catalog.py @@ -1,7 +1,7 @@ -"""Catalog of available intrinsics. +"""Catalog of available adapter functions. -Catalog of intrinsics currently known to Mellea,including metadata about where to find -LoRA and aLoRA adapters that implement said intrinsics. +Catalog of adapter functions currently known to Mellea, including metadata about where +to find LoRA and aLoRA adapters that implement them. """ import enum @@ -10,16 +10,16 @@ def validate_revision(revision: str) -> str: - """Validate a HuggingFace revision value. + """Validate a Hugging Face revision value. - Accepts any non-empty string. HuggingFace's ``revision`` parameter takes a + Accepts any non-empty string. Hugging Face's ``revision`` parameter takes a branch name, tag, or commit SHA; this validator mirrors that contract. Catalogue entries pin to commit SHAs by convention; that is enforced by review and (optionally) build-time drift checks rather than by this validator. Args: - revision (str): Any non-empty string accepted by HuggingFace as a + revision (str): Any non-empty string accepted by Hugging Face as a revision (branch name, tag, or commit SHA). Returns: @@ -41,7 +41,7 @@ class AdapterType(enum.Enum): Attributes: LORA (str): Standard LoRA adapter; value ``"lora"``. - ALORA (str): Activated LoRA adapter; value ``"alora"``. + ALORA (str): aLoRA adapter (shares model KV cache across adapter functions); value ``"alora"``. """ LORA = "lora" @@ -49,12 +49,12 @@ class AdapterType(enum.Enum): class IntriniscsCatalogEntry(pydantic.BaseModel): - """A single row in the main intrinsics catalog table. + """A single row in the main adapter function catalog table. We use Pydantic for this dataclass because the rest of Mellea also uses Pydantic. Attributes: - name (str): User-visible name of the intrinsic. May contain hyphens when + name (str): User-visible name of the adapter function. May contain hyphens when that matches the upstream adapter name; prefer ``effective_capability`` to form the stable capability token. Must be non-empty with no leading or trailing whitespace. @@ -64,21 +64,21 @@ class IntriniscsCatalogEntry(pydantic.BaseModel): non-empty with no leading or trailing whitespace. internal_name (str | None): Internal name used for adapter loading, or ``None`` if the same as ``name``. - repo_id (str): HuggingFace repository where adapters for the intrinsic + repo_id (str): Hugging Face repository where adapters for the adapter function are located. - revision (str): HuggingFace revision — branch name, tag, or commit SHA. + revision (str): Hugging Face revision — branch name, tag, or commit SHA. Catalogue entries pin to commit SHAs by convention so loads are reproducible; the validator itself only requires a non-empty string. Note: this field is stored in the catalogue but not yet forwarded to - the HuggingFace download call; wiring it through is deferred to a + the Hugging Face download call; wiring it through is deferred to a subsequent phase of the adapter-lifecycle epic (#929). adapter_types (tuple[AdapterType, ...]): Adapter types known to be - available for this intrinsic; defaults to + available for this adapter function; defaults to ``(AdapterType.LORA, AdapterType.ALORA)``. """ name: str = pydantic.Field( - description="User-visible name of the intrinsic. Non-empty, no leading/trailing whitespace." + description="User-visible name of the adapter function. Non-empty, no leading/trailing whitespace." ) capability: str | None = pydantic.Field( default=None, @@ -95,15 +95,15 @@ class IntriniscsCatalogEntry(pydantic.BaseModel): ) repo_id: str = pydantic.Field( description="Hugging Face repository (aka 'model') where adapters for the " - "intrinsic are located." + "adapter function are located." ) revision: str = pydantic.Field( - description="HuggingFace revision (branch name, tag, or commit SHA). " + description="Hugging Face revision (branch name, tag, or commit SHA). " "Catalogue entries pin to commit SHAs by convention." ) adapter_types: tuple[AdapterType, ...] = pydantic.Field( default=(AdapterType.LORA, AdapterType.ALORA), - description="Adapter types that are known to be available for this intrinsic.", + description="Adapter types that are known to be available for this adapter function.", ) @pydantic.field_validator("name") @@ -135,7 +135,7 @@ def _check_revision(cls, v: str) -> str: @property def effective_capability(self) -> str: - """Return the stable capability token for this intrinsic. + """Return the stable capability token for this adapter function. Returns ``capability`` when explicitly set; falls back to ``name`` otherwise. Use this property — not ``name`` — whenever building the @@ -159,7 +159,7 @@ def effective_capability(self) -> str: _INTRINSICS_CATALOG_ENTRIES = [ ############################################ - # Core Intrinsics + # Core adapter functions ############################################ IntriniscsCatalogEntry( name="context-attribution", @@ -177,7 +177,7 @@ def effective_capability(self) -> str: name="uncertainty", repo_id=_CORE_R1_REPO, revision=_CORE_R1_SHA ), ############################################ - # RAG Intrinsics + # RAG adapter functions ############################################ IntriniscsCatalogEntry(name="answerability", repo_id=_RAG_REPO, revision=_RAG_SHA), IntriniscsCatalogEntry(name="citations", repo_id=_RAG_REPO, revision=_RAG_SHA), @@ -192,7 +192,7 @@ def effective_capability(self) -> str: ), IntriniscsCatalogEntry(name="query_rewrite", repo_id=_RAG_REPO, revision=_RAG_SHA), ############################################ - # Guardian Intrinsics + # Guardian adapter functions ############################################ IntriniscsCatalogEntry( name="policy-guardrails", @@ -221,7 +221,7 @@ def effective_capability(self) -> str: ] _INTRINSICS_CATALOG = {e.name: e for e in _INTRINSICS_CATALOG_ENTRIES} -"""Catalog of intrinsics that Mellea knows about. +"""Catalog of adapter functions that Mellea knows about. Mellea code should access this catalog via :func:`fetch_intrinsic_metadata()`""" @@ -235,26 +235,26 @@ def effective_capability(self) -> str: def known_intrinsic_names() -> list[str]: - """Return all known user-visible names for intrinsics. + """Return all known user-visible names for adapter functions. Returns: - List of all known user-visible intrinsic names. + List of all known user-visible adapter function names. """ return list(_INTRINSICS_CATALOG.keys()) def fetch_intrinsic_metadata(intrinsic_name: str) -> IntriniscsCatalogEntry: - """Retrieve information about the adapter that backs an intrinsic. + """Retrieve catalog metadata for the adapter that implements an adapter function. Args: - intrinsic_name (str): User-visible name of the intrinsic. + intrinsic_name (str): User-visible name of the adapter function. Returns: IntriniscsCatalogEntry: Metadata about the adapter(s) that implement the - intrinsic. + adapter function. Raises: - ValueError: If ``intrinsic_name`` is not a known intrinsic name. + ValueError: If ``intrinsic_name`` is not a known adapter function name. """ if intrinsic_name not in _INTRINSICS_CATALOG: raise ValueError( diff --git a/mellea/backends/huggingface.py b/mellea/backends/huggingface.py index 7c2cc0058..0d2a83524 100644 --- a/mellea/backends/huggingface.py +++ b/mellea/backends/huggingface.py @@ -1,6 +1,6 @@ """A backend that uses the Huggingface Transformers library. -The purpose of the Hugginface backend is to provide a setting for implementing experimental features. If you want a performance local backend, and do not need experimental features such as Span-based context or ALoras, consider using Ollama backends instead. +The purpose of the Hugginface backend is to provide a setting for implementing experimental features. If you want a performance local backend, and do not need experimental features such as Span-based context or aLoRA adapters, consider using Ollama backends instead. """ from __future__ import annotations @@ -36,7 +36,7 @@ from transformers.trainer_utils import set_seed except ImportError as e: raise ImportError( - "The HuggingFace backend requires extra dependencies. " + "The Hugging Face backend requires extra dependencies. " 'Please install them with: pip install "mellea[hf]"' ) from e @@ -134,7 +134,7 @@ class HFAloraCacheInfo: reused across generation requests via an LRU cache. Args: - kv_cache (DynamicCache | None): The HuggingFace `DynamicCache` holding + kv_cache (DynamicCache | None): The Hugging Face `DynamicCache` holding precomputed key/value tensors, or `None` if not available. merged_token_ids (Any): Token IDs corresponding to the cached prefix. merged_attention (Any): Attention mask for the cached prefix tokens. @@ -202,7 +202,7 @@ def _cleanup_kv_cache(cache_info: HFAloraCacheInfo) -> None: torch.cuda.empty_cache() -# Variables that HuggingFace injects into the Jinja template namespace automatically. +# Variables that Hugging Face injects into the Jinja template namespace automatically. # These must be excluded from _chat_template_allowlist because they are provided by # apply_chat_template itself — forwarding a model_option with the same name would # either cause a "got multiple values for keyword argument" TypeError (for the named-param @@ -235,7 +235,7 @@ def _cleanup_kv_cache(cache_info: HFAloraCacheInfo) -> None: class LocalHFBackend(FormatterBackend, AdapterMixin): - """The LocalHFBackend uses Huggingface's transformers library for inference, and uses a Formatter to convert `Component`s into prompts. This backend also supports Activated LoRAs (ALoras)](https://arxiv.org/pdf/2504.12397). + """The LocalHFBackend uses Huggingface's transformers library for inference, and uses a Formatter to convert `Component`s into prompts. This backend also supports [aLoRA adapters](https://arxiv.org/pdf/2504.12397). This backend is designed for running an HF model for small-scale inference locally on your machine. @@ -243,7 +243,7 @@ class LocalHFBackend(FormatterBackend, AdapterMixin): Args: model_id (str | ModelIdentifier): Used to load the model and tokenizer via - HuggingFace `Auto*` classes. + Hugging Face `Auto*` classes. formatter (ChatFormatter | None): Formatter for rendering components into prompts. Defaults to `TemplateFormatter`. use_caches (bool): If `False`, KV caching is disabled even if a `Cache` @@ -382,7 +382,7 @@ async def _generate_from_context( model_options: dict | None = None, tool_calls: bool = False, ) -> tuple[ModelOutputThunk[C], Context]: - """Generate a completion for `action` given `ctx` using the HuggingFace model. + """Generate a completion for `action` given `ctx` using the Hugging Face model. Automatically routes `Requirement` and `Intrinsic` actions to their corresponding aLoRA adapters when available. @@ -885,7 +885,7 @@ async def _generate_from_context_with_kv_cache( stream = model_options.get(ModelOption.STREAM, False) if stream: try: - # HuggingFace uses a streaming interface that you pass to the generate call. + # Hugging Face uses a streaming interface that you pass to the generate call. # Must be called from a running event loop. This should always be the case given the same # requirement of the ._generate function below. streamer = AsyncTextIteratorStreamer( @@ -1067,7 +1067,7 @@ async def _generate_from_context_standard( stream = model_options.get(ModelOption.STREAM, False) if stream: try: - # HuggingFace uses a streaming interface that you pass to the generate call. + # Hugging Face uses a streaming interface that you pass to the generate call. # Must be called from a running event loop. This should always be the case given the same # requirement of the ._generate function below. streamer = AsyncTextIteratorStreamer( @@ -1183,7 +1183,7 @@ async def processing( Args: mot (ModelOutputThunk): The output thunk being populated. chunk (str | GenerateDecoderOnlyOutput): A decoded text chunk (streaming) - or a full HuggingFace generation output object (non-streaming). + or a full Hugging Face generation output object (non-streaming). input_ids: The prompt token IDs used for decoding; required to slice off the prompt portion from the generated sequences. """ @@ -1219,7 +1219,7 @@ async def post_processing( seed, input_ids, ): - """Finalize the output thunk after HuggingFace generation completes. + """Finalize the output thunk after Hugging Face generation completes. Stores the KV cache for future reuse, parses tool calls if applicable, records token usage metrics, emits telemetry, and attaches the generate log. @@ -1390,7 +1390,7 @@ async def _generate_from_raw( ) -> tuple[list[ModelOutputThunk], dict[str, Any] | None]: """Generate completions for multiple actions without chat templating. - Passes formatted prompt strings directly to the HuggingFace model's + Passes formatted prompt strings directly to the Hugging Face model's `generate` method as a batch. Tool calling is not supported. Args: @@ -1649,7 +1649,7 @@ def _chat_template_allowlist(self) -> frozenset[str]: Parses the Jinja2 template with :func:`jinja2.meta.find_undeclared_variables` to find every variable the template references but does not define itself, then - subtracts :data:`_HF_INTERNAL_TEMPLATE_VARS` (variables HuggingFace provides + subtracts :data:`_HF_INTERNAL_TEMPLATE_VARS` (variables Hugging Face provides automatically). What remains is the exact set of keys a caller may legitimately forward from ``model_options`` to ``apply_chat_template``. @@ -1756,7 +1756,7 @@ def add_adapter(self, adapter: LocalHFAdapter): self._added_adapters[adapter.qualified_name] = adapter def load_adapter(self, adapter_qualified_name: str): - """Load a previously registered adapter into the underlying HuggingFace model. + """Load a previously registered adapter into the underlying Hugging Face model. The adapter must have been registered via `add_adapter` first. Do not call this method while generation requests are in progress. @@ -1797,7 +1797,7 @@ def load_adapter(self, adapter_qualified_name: str): self._loaded_adapters[adapter.qualified_name] = adapter def unload_adapter(self, adapter_qualified_name: str): - """Unload a previously loaded adapter from the underlying HuggingFace model. + """Unload a previously loaded adapter from the underlying Hugging Face model. If the adapter is not currently loaded, a log message is emitted and the method returns without error. diff --git a/mellea/backends/litellm.py b/mellea/backends/litellm.py index 63a443fcd..f4169d469 100644 --- a/mellea/backends/litellm.py +++ b/mellea/backends/litellm.py @@ -306,7 +306,7 @@ async def _generate_from_chat_context_standard( # Add the final message. match action: case ALoraRequirement(): - raise Exception("The LiteLLM backend does not support activated LoRAs.") + raise Exception("The LiteLLM backend does not support aLoRA adapters.") case _: messages.extend(self.formatter.to_chat_messages([action])) diff --git a/mellea/backends/ollama.py b/mellea/backends/ollama.py index 9fff26311..a7c1342c9 100644 --- a/mellea/backends/ollama.py +++ b/mellea/backends/ollama.py @@ -373,7 +373,7 @@ async def generate_from_chat_context( match action: case ALoraRequirement(): raise Exception( - "The ollama backend does not support currently support activated LoRAs." + "The ollama backend does not currently support aLoRA adapters." ) case _: messages.extend(self.formatter.to_chat_messages([action])) diff --git a/mellea/backends/openai.py b/mellea/backends/openai.py index eaf764581..42a4625fd 100644 --- a/mellea/backends/openai.py +++ b/mellea/backends/openai.py @@ -82,8 +82,8 @@ class OpenAIBackend(FormatterBackend, AdapterMixin): load_embedded_adapters (bool): If `True`, automatically registers embedded intrinsic adapters from *adapter_source* (or *model_id* if *adapter_source* is not set). Looks first for a local directory - and then for a HuggingFace hub repo. - adapter_source (str | None): Local directory path or HuggingFace hub + and then for a Hugging Face hub repo. + adapter_source (str | None): Local directory path or Hugging Face hub repo ID from which to load embedded adapter configs. When `None`, falls back to *model_id*. Use this when the vLLM served model name differs from the adapter config location. @@ -288,8 +288,8 @@ def register_embedded_adapter_model( """Register all embedded adapters from an Embedded Adapter model. Args: - source (str): A local model directory path or HuggingFace Hub repo ID. - revision (str): Git revision when loading from HuggingFace Hub. + source (str): A local model directory path or Hugging Face Hub repo ID. + revision (str): Git revision when loading from Hugging Face Hub. cache_dir (str | None): Cache directory for HF downloads. Returns: @@ -579,7 +579,7 @@ async def _generate_from_intrinsic( ) if adapter is None: raise ValueError( - f"backend ({self}) has no adapter for processing intrinsic: " + f"backend ({self}) has no adapter for processing adapter function: " f"{action.intrinsic_name}" ) diff --git a/mellea/backends/watsonx.py b/mellea/backends/watsonx.py index 0b8490c7c..0d3ec1f3f 100644 --- a/mellea/backends/watsonx.py +++ b/mellea/backends/watsonx.py @@ -362,7 +362,7 @@ async def generate_from_chat_context( match action: case ALoraRequirement(): raise Exception( - "The watsonx backend does not support currently support activated LoRAs." + "The watsonx backend does not currently support aLoRA adapters." ) case _: messages.extend(self.formatter.to_chat_messages([action])) diff --git a/mellea/core/requirement.py b/mellea/core/requirement.py index 04b99088a..5dbb88855 100644 --- a/mellea/core/requirement.py +++ b/mellea/core/requirement.py @@ -260,7 +260,7 @@ async def validate( # Python validation strategy return self.validation_fn(ctx) else: - # LLMaJ validation strategy. This includes ALora because the backend generate call will appropriately dispatch. + # LLMaJ validation strategy. This includes aLoRA because the backend generate call will appropriately dispatch. assert self.output_to_bool is not None last_output = ctx.last_output() assert isinstance(last_output, ModelOutputThunk), ( diff --git a/mellea/stdlib/components/adapter_based_component/__init__.py b/mellea/stdlib/components/adapter_based_component/__init__.py index ba03b016e..a370bad61 100644 --- a/mellea/stdlib/components/adapter_based_component/__init__.py +++ b/mellea/stdlib/components/adapter_based_component/__init__.py @@ -4,7 +4,7 @@ provided by a fine-tuned adapter (LoRA / aLoRA) rather than the base model. It is currently implemented as an alias for :class:`~mellea.stdlib.components.intrinsic.Intrinsic`; the alias allows -downstream code to migrate to the new name as the rest of Epic #929 lands. The +downstream code to migrate to the new name as the rest of Epic #929 is merged. The old import path ``mellea.stdlib.components.intrinsic`` continues to work. """ diff --git a/mellea/stdlib/components/intrinsic/core.py b/mellea/stdlib/components/intrinsic/core.py index 8f2b38083..41925bea9 100644 --- a/mellea/stdlib/components/intrinsic/core.py +++ b/mellea/stdlib/components/intrinsic/core.py @@ -1,4 +1,4 @@ -"""Intrinsic functions for core model capabilities.""" +"""Adapter functions for core model capabilities.""" import collections.abc @@ -12,7 +12,7 @@ def check_certainty(context: ChatContext, backend: AdapterMixin) -> float: """Estimate the model's certainty about its last response. - Intrinsic function that evaluates how certain the model is about the + Adapter function that evaluates how certain the model is about the assistant's response to a user's question. The context should end with a user question followed by an assistant answer. @@ -32,7 +32,7 @@ def requirement_check( ) -> float: """Detect if text adheres to provided requirements. - Intrinsic function that determines if the text satisfies the given + Adapter function that determines if the text satisfies the given requirements. The requirement text is passed through to the adapter's `io.yaml` `instruction` template via `IntrinsicsRewriter`, which appends the formatted evaluation prompt as a new user message. @@ -59,7 +59,7 @@ def find_context_attributions( ) -> list[dict]: """Find sentences in conversation history and documents that most influence an LLM's response. - Intrinsic function that finds sentences in prior conversation messages and RAG + Adapter function that finds sentences in prior conversation messages and RAG documents that were most important to the LLM in generating each sentence in the assistant response. diff --git a/mellea/stdlib/components/intrinsic/guardian.py b/mellea/stdlib/components/intrinsic/guardian.py index e888ba881..e1a508368 100644 --- a/mellea/stdlib/components/intrinsic/guardian.py +++ b/mellea/stdlib/components/intrinsic/guardian.py @@ -1,4 +1,4 @@ -"""Intrinsic functions for Guardian safety and hallucination detection. +"""Adapter functions for Guardian safety and hallucination detection. The Guardian adapters (`guardian-core`, `policy-guardrails`, `factuality-detection`, `factuality-correction`) require a @@ -243,7 +243,7 @@ def guardian_check( def factuality_detection(context: ChatContext, backend: AdapterMixin) -> str: """Determine is the last response is factually incorrect. - Intrinsic function that evaluates the factuality of the + Adapter function that evaluates the factuality of the assistant's response to a user's question. The context should end with a user question followed by an assistant answer. @@ -259,7 +259,7 @@ def factuality_detection(context: ChatContext, backend: AdapterMixin) -> str: def factuality_correction(context: ChatContext, backend: AdapterMixin) -> str: """Corrects the last response so that it is factually correct. - Intrinsic function that corrects the assistant's response to a user's + Adapter function that corrects the assistant's response to a user's question relative to the given contextual information. :param context: Chat context containing user question and assistant answer. diff --git a/mellea/stdlib/components/intrinsic/rag.py b/mellea/stdlib/components/intrinsic/rag.py index 27ad67dd0..8bc311d4f 100644 --- a/mellea/stdlib/components/intrinsic/rag.py +++ b/mellea/stdlib/components/intrinsic/rag.py @@ -1,4 +1,4 @@ -"""Intrinsic functions related to retrieval-augmented generation.""" +"""Adapter functions related to retrieval-augmented generation.""" import collections.abc @@ -18,7 +18,7 @@ def check_answerability( ) -> str: """Test a user's question for answerability. - Intrinsic function that checks whether the question in the last user turn of a + Adapter function that checks whether the question in the last user turn of a chat can be answered by a provided set of RAG documents. Args: @@ -51,7 +51,7 @@ def rewrite_question( ) -> str: """Rewrite a user's question for retrieval. - Intrinsic function that rewrites the question in the next user turn into a + Adapter function that rewrites the question in the next user turn into a self-contained query that can be passed to the retriever. Args: @@ -79,7 +79,7 @@ def clarify_query( ) -> str: """Generate clarification for an ambiguous query. - Intrinsic function that determines if a user's question requires clarification + Adapter function that determines if a user's question requires clarification based on the retrieved documents and conversation context, and generates an appropriate clarification question if needed. @@ -116,7 +116,7 @@ def find_citations( ) -> list[dict]: """Find information in documents that supports an assistant response. - Intrinsic function that finds sentences in RAG documents that support sentences + Adapter function that finds sentences in RAG documents that support sentences in a potential assistant response to a user question. Args: @@ -162,7 +162,7 @@ def check_context_relevance( ) -> str: """Test whether a document is relevant to a user's question. - Intrinsic function that checks whether a single document contains part or all of + Adapter function that checks whether a single document contains part or all of the answer to a user's question. Does not consider the context in which the question was asked. @@ -201,7 +201,7 @@ def flag_hallucinated_content( ) -> list[dict]: """Flag potentially-hallucinated sentences in an agent's response. - Intrinsic function that checks whether the sentences in an agent's response to a + Adapter function that checks whether the sentences in an agent's response to a user question are faithful to the retrieved document snippets. Sentences that do not align with the retrieved snippets are flagged as potential hallucinations. diff --git a/mellea/stdlib/requirements/rag.py b/mellea/stdlib/requirements/rag.py index 5fa44d90a..ca552ba6c 100644 --- a/mellea/stdlib/requirements/rag.py +++ b/mellea/stdlib/requirements/rag.py @@ -26,7 +26,7 @@ class GroundednessRequirement(Requirement): that LLM responses are fully grounded by citations to provided documents: 1. **Citation Generation**: Generate citations for the response using the - find_citations intrinsic. + find_citations adapter function. 2. **Citation Necessity**: Identify which response spans require citations (vs. conversational/inference text that doesn't need citations). 3. **Citation Support**: For spans that need citations, assess the level of @@ -35,7 +35,7 @@ class GroundednessRequirement(Requirement): citations are fully supported. **Important**: This requirement requires a HuggingFace backend (LocalHFBackend) - as it uses both the find_citations intrinsic and LLM-as-Judge for assessment. + as it uses both the find_citations adapter function and LLM-as-Judge for assessment. Args: documents: Optional documents to validate against. Can be Document @@ -115,7 +115,7 @@ async def validate( Args: backend: Backend to use for citation detection and LLM judgment. - Must be LocalHFBackend as this uses find_citations intrinsic. + Must be LocalHFBackend as this uses find_citations adapter function. ctx: Context containing the conversation history format: Unused for this requirement model_options: Unused for this requirement @@ -173,9 +173,9 @@ async def validate( ) # Create context without the response being validated. - # This removes the assistant's response from the context passed to intrinsics, + # This removes the assistant's response from the context passed to adapter functions, # ensuring they only see the conversation history (user messages and prior context). - # This is important because intrinsics need to assess citations/necessity/support + # This is important because adapter functions need to assess citations/necessity/support # for the response independently, without the response itself influencing the judgment. # ChatContext is immutable, so we build a new one with all messages except the last. all_messages = ctx.as_list() @@ -203,7 +203,7 @@ async def validate( ) except Exception as e: return ValidationResult( - False, reason=f"Citation generation intrinsic failed: {e!s}" + False, reason=f"Citation generation adapter function failed: {e!s}" ) # Step 2: Citation Necessity diff --git a/mellea/stdlib/requirements/safety/guardian.py b/mellea/stdlib/requirements/safety/guardian.py index 6f0f3e70e..42c463612 100644 --- a/mellea/stdlib/requirements/safety/guardian.py +++ b/mellea/stdlib/requirements/safety/guardian.py @@ -95,7 +95,7 @@ class GuardianCheck(Requirement): `"huggingface"`. model_version (str | None): Specific Guardian model version. Defaults to the appropriate 8B model for the chosen backend. - device (str | None): Device string for HuggingFace inference (e.g. + device (str | None): Device string for Hugging Face inference (e.g. `"cuda"`). ollama_url (str | None): Base URL for the Ollama server. When `None`, reads `OLLAMA_HOST` from the environment (falling back @@ -128,7 +128,7 @@ def __init__( warnings.warn( "GuardianCheck is deprecated as of version 0.4. " - "Use the Guardian Intrinsics instead ", + "Use the Guardian adapter functions instead ", DeprecationWarning, stacklevel=2, ) @@ -376,11 +376,11 @@ async def validate( # Generate the guardian decision. # For Ollama: add blank assistant turn to trigger generation - # For HuggingFace: use CBlock (won't be added to conversation, add_generation_prompt handles the judge role) + # For Hugging Face: use CBlock (won't be added to conversation, add_generation_prompt handles the judge role) if self._backend_type == "ollama": action = Message("assistant", "") else: - # Use a CBlock for HuggingFace - it won't be added as a message + # Use a CBlock for Hugging Face - it won't be added as a message action = CBlock("") # type: ignore mot, val_ctx = await self._backend.generate_from_context( diff --git a/test/backends/test_adapters/test_embedded_adapter.py b/test/backends/test_adapters/test_embedded_adapter.py index cd84d61aa..ff7dc9115 100644 --- a/test/backends/test_adapters/test_embedded_adapter.py +++ b/test/backends/test_adapters/test_embedded_adapter.py @@ -213,7 +213,7 @@ def test_filter_single_intrinsic(self, model_dir): def test_filter_nonexistent_intrinsic(self, model_dir): with pytest.raises( - ValueError, match="No adapter found for intrinsic 'nonexistent'" + ValueError, match="No adapter found for adapter function 'nonexistent'" ): EmbeddedIntrinsicAdapter.from_model_directory( model_dir, intrinsic_name="nonexistent"