From cc3217c81e02da5311b0ad035ca4bff110f82365 Mon Sep 17 00:00:00 2001 From: Eric Curtin Date: Mon, 31 Aug 2026 00:55:44 +0100 Subject: [PATCH] feat: add llmman as an LLM provider llmman (https://github.com/llmmanorg/llmman) is a local model runner that serves the Ollama API, so the provider subclasses the existing Ollama implementation and changes only the provider name and the default port it listens on. Model listing, FIM, embeddings and streaming all come along unchanged. Tool support delegates to the same name-based heuristic, since llmman serves the same local models. fetchModels needs no case of its own: the default branch goes through listModels, which the inherited implementation already answers from the running server rather than a remote catalog. Signed-off-by: Eric Curtin --- core/llm/llms/Llmman.ts | 18 ++++++++++++++++++ core/llm/llms/index.ts | 2 ++ core/llm/toolSupport.ts | 3 +++ packages/config-types/src/index.ts | 2 ++ 4 files changed, 25 insertions(+) create mode 100644 core/llm/llms/Llmman.ts diff --git a/core/llm/llms/Llmman.ts b/core/llm/llms/Llmman.ts new file mode 100644 index 00000000000..289165e7817 --- /dev/null +++ b/core/llm/llms/Llmman.ts @@ -0,0 +1,18 @@ +import Ollama from "./Ollama"; + +import type { LLMOptions } from "../../index.js"; + +/** + * llmman (https://github.com/llmmanorg/llmman) is a local model runner that + * serves the Ollama API, so it reuses that implementation wholesale and only + * changes the provider name and the default port it listens on. + */ +class Llmman extends Ollama { + static providerName = "llmman"; + static defaultOptions: Partial = { + ...Ollama.defaultOptions, + apiBase: "http://localhost:17434/", + }; +} + +export default Llmman; diff --git a/core/llm/llms/index.ts b/core/llm/llms/index.ts index 4978f0617f2..ba470bac131 100644 --- a/core/llm/llms/index.ts +++ b/core/llm/llms/index.ts @@ -47,6 +47,7 @@ import Nebius from "./Nebius"; import Nous from "./Nous"; import Novita from "./Novita"; import Nvidia from "./Nvidia"; +import Llmman from "./Llmman"; import Ollama from "./Ollama"; import OpenAI from "./OpenAI"; import OpenRouter from "./OpenRouter"; @@ -78,6 +79,7 @@ export const LLMClasses = [ Gemini, Llamafile, Moonshot, + Llmman, Ollama, Replicate, TextGenWebUI, diff --git a/core/llm/toolSupport.ts b/core/llm/toolSupport.ts index 3f65473233c..7870e17ecd1 100644 --- a/core/llm/toolSupport.ts +++ b/core/llm/toolSupport.ts @@ -199,6 +199,9 @@ export const PROVIDER_TOOL_SUPPORT: Record boolean> = return false; }, + // llmman serves the same local models over the Ollama API, so the same + // name-based heuristic applies. + llmman: (model) => PROVIDER_TOOL_SUPPORT["ollama"](model), lmstudio: (model) => { // LM Studio uses hyphenated model IDs (e.g., "Meta-Llama-3.1-8B-Instruct-GGUF") // that don't match Ollama's substring patterns (e.g., "llama3.1"). diff --git a/packages/config-types/src/index.ts b/packages/config-types/src/index.ts index c73c4f5142b..ac1643265dc 100644 --- a/packages/config-types/src/index.ts +++ b/packages/config-types/src/index.ts @@ -47,6 +47,7 @@ export const modelDescriptionSchema = z.object({ "anthropic", "cohere", "ollama", + "llmman", "huggingface-tgi", "huggingface-inference-api", "replicate", @@ -107,6 +108,7 @@ export const embeddingsProviderSchema = z.object({ provider: z.enum([ "transformers.js", "ollama", + "llmman", "openai", "cohere", "gemini",