mantle
mantle
A Crystal Lang framework for abstracting LLM interactions into composable Step execution pipelines and strongly-typed outcomes.
Intended to be a base layer for building LLM applications.
Developed with AI Notice
ieve is not a software engineer, just a hobbyist. So I use heavy use of LLM tools to help me in a few ways:
- Talking through architecture approaches or language features/patterns to accomplish what I want.
- Use of Claude Code or Google Jules to implement features or do refactoring. It's probably about 50/50 hand coded and machine coded. The tests are mostly machine generated. Things that are boring are machine generated. I, just personally, would never get anywhere if I couldn't hand off big chunks to the machine.
However, my limit of use of AI is that I don't want to let the codebase get beyond my understanding. All architectural and design decisions are curated and reviewed by the human, at minimum.
Separation of concerns
Mantle is intended to be pretty low level - if code is related to how to talk to the model or how to structure a loop, it should live here in Mantle. If the code is related to what an agent is trying to achieve, it should live at the application layer.
Installation
-
Add the dependency to your
shard.yml:dependencies: mantle: github: ieve-rothe/mantle -
Run
shards install
Usage
Mantle is a framework to abstract details of communication to LLMs away, to help keep the application layer focused on... application stuff.
- The Most Basic Client
- Client: Handles sending message and getting a response from an LLM provider (currently supporting Ollama via
Mantle::Clients::OllamaClient), with configuration set by aMantle::Clients::ModelConfigobject.
- Context and Memory Management
- Context Store: Tracks the ongoing back and forth conversation between the user and the bot. Stored in JSON (
Mantle::JSONContextStore), with optional ephemeral system prompt support. - Context Cascade and Memory Store: To help avoid context dilution during long sessions or ongoing interactions, Mantle implements a summarization cascade with configurable thresholds based on a rough token counting heuristic.
- When context exceeds the
token_hardmaxtarget, we run summarization usingMantle::Squishifiers, asking the model to summarize messages to return totoken_target. Those messages are moved toMantle::JSONLayeredMemoryStore.
- When context exceeds the
- Context Manager: Coordinates putting messages into context/memory, and getting current view of context by concatenating memory layers with context store view.
- Step Execution Pipeline and Tool Calling
- Step:
Mantle::Stepis a pure inference pipeline decoupled from storage persistence. It consumes messages and returns a strongly typedMantle::StepResult(String, Mantle::StepError). - StepResult: Encapsulates outcome state:
.ok?,.err?,.unwrap,.thinking,.iterations, and.raw_response. - Domain Errors: Standardized in
Mantle::StepError(MalformedOutput,MaxIterationsReached,ClientFailure,ToolExecutionFailure). - Tool Calling & Middleware:
Mantle::Tools::Toolsupports inline executable blocks or handlers.Mantle::Tools::Middlewareprovides composable execution pipelines (e.g.,ToolMiddleware::ExceptionTrappingto trap operational errors while letting system bugs bubble up).Stepcoordinates bounded tool loops up tomax_iterations, safely handling tool outputs or returning typed errors without throwing unexpected exceptions. - Typed API Errors:
Mantle::Clients::APIErrorcaptures HTTP status and raw body from upstream providers, exposing#context_overflow?to reliably detect context window exhaustion (e.g. 400 rejections) without string scraping.
- Advanced Features for Cognitive Architectures
See
ARCHITECTURE.mdfor detailed documentation
Mantle provides several advanced primitives designed for cognitive operating systems and multi-agent architectures:
-
Ephemeral System Blocks: Dynamically inject temporary system messages (K-Lines, "Demon" instructions) into a single LLM call without persisting to storage. Useful for frame switching and context manipulation.
-
Invisible Appends: Append backend routing instructions to user messages that appear in the LLM context but not in long-term memory. Prevents metadata from cluttering conversation history.
-
Dynamic System Prompt Updates: Update the system prompt on any
ContextStoreor through theContextManagermid-session (e.g.@context_manager.update_system_prompt(new_prompt)) to adapt context to changing cognitive tasks. -
System Prompt Ephemeral Mode: Configure
JSONContextStorewithpersist_system_prompt: falseto allow the application layer or Hypervisor to manage system prompts dynamically in memory without saving them to the JSON context files, preventing old system prompts from being restored on reload. -
Hot-Swapping State Stores: Safely replace ContextStore and MemoryStore mid-session for "hard shifts" between personas or conversation frames. Ensures data integrity through proper flushing.
-
Custom Tool Formatting: Tool callbacks can return
formatted_overrideto control how results appear in context, maintaining persona continuity when subagents need custom formatting. -
Subagent Recursion Kill-Switch: Framework-level depth tracking (
MAX_SUBAGENT_DEPTH = 1) automatically strips tools at depth boundaries to prevent infinite recursion, runaway costs, and context collapse.
These features maintain Mantle's core principle: the framework provides agnostic pipes, while applications control the content and timing.
Development
- Run tests with
crystal spec. - Bots: See
AGENTS.mdandCLAUDE.mdfor architectural guidelines.
Contributing
- Fork it (https://github.com/ieve-rothe/mantle/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- ieve (Cam Carroll) - creator and maintainer
License
Mantle is licensed under the MIT License. See the LICENSE file for details.
mantle
- 0
- 0
- 0
- 1
- 0
- 14 days ago
- November 11, 2025
MIT License
Sat, 10 Oct 2026 17:58:15 GMT