feat: add MiniMax LLM provider support (#550)
Add MiniMax as a supported LLM provider via the OpenAI-compatible interface. - Register MiniMax in the provider factory and valid providers list - Set default base URL to https://api.minimax.io/v1 - Set default model to MiniMax-M2.5 in PROVIDER_DEFAULT_MODELS - Add temperature clamping for MiniMax (must be >0, ≤1.0) - Add API key validation (MiniMax requires an API key) - Add MiniMax configuration example to .env.example - Update documentation (models.md, configuration.md, embed.md, CLAUDE.md, README.md) - Add unit and integration tests for MiniMax provider Co-authored-by: octo-patch <octo-patch@users.noreply.github.com>
This commit is contained in:
parent
a01bb18bc4
commit
2344484f77
10 changed files with 236 additions and 11 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
# Copy this file to .env and fill in your values
|
# Copy this file to .env and fill in your values
|
||||||
|
|
||||||
# LLM Configuration (Required)
|
# LLM Configuration (Required)
|
||||||
# Supported providers: openai, groq, ollama, gemini, anthropic, lmstudio, vertexai
|
# Supported providers: openai, groq, ollama, gemini, anthropic, lmstudio, vertexai, minimax
|
||||||
HINDSIGHT_API_LLM_PROVIDER=openai
|
HINDSIGHT_API_LLM_PROVIDER=openai
|
||||||
HINDSIGHT_API_LLM_API_KEY=your-api-key-here
|
HINDSIGHT_API_LLM_API_KEY=your-api-key-here
|
||||||
HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
||||||
|
|
@ -20,6 +20,11 @@ HINDSIGHT_API_LLM_BASE_URL=https://api.openai.com/v1
|
||||||
# HINDSIGHT_API_LLM_VERTEXAI_REGION=us-central1
|
# HINDSIGHT_API_LLM_VERTEXAI_REGION=us-central1
|
||||||
# HINDSIGHT_API_LLM_VERTEXAI_SERVICE_ACCOUNT_KEY=/path/to/service-account-key.json # Optional, uses ADC if not set
|
# HINDSIGHT_API_LLM_VERTEXAI_SERVICE_ACCOUNT_KEY=/path/to/service-account-key.json # Optional, uses ADC if not set
|
||||||
|
|
||||||
|
# Example: MiniMax configuration (204K context window)
|
||||||
|
# HINDSIGHT_API_LLM_PROVIDER=minimax
|
||||||
|
# HINDSIGHT_API_LLM_API_KEY=your-minimax-api-key
|
||||||
|
# HINDSIGHT_API_LLM_MODEL=MiniMax-M2.5
|
||||||
|
|
||||||
# Example: LM Studio local configuration (Qwen 2.5 32B recommended)
|
# Example: LM Studio local configuration (Qwen 2.5 32B recommended)
|
||||||
# HINDSIGHT_API_LLM_PROVIDER=lmstudio
|
# HINDSIGHT_API_LLM_PROVIDER=lmstudio
|
||||||
# HINDSIGHT_API_LLM_API_KEY=lmstudio
|
# HINDSIGHT_API_LLM_API_KEY=lmstudio
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ cd hindsight-control-plane && npm run dev
|
||||||
|
|
||||||
### Core Engine (hindsight-api/hindsight_api/engine/)
|
### Core Engine (hindsight-api/hindsight_api/engine/)
|
||||||
- `memory_engine.py`: Main orchestrator (~170KB) for retain/recall/reflect operations
|
- `memory_engine.py`: Main orchestrator (~170KB) for retain/recall/reflect operations
|
||||||
- `llm_wrapper.py`: LLM abstraction supporting OpenAI, Anthropic, Gemini, Groq, Ollama, LM Studio
|
- `llm_wrapper.py`: LLM abstraction supporting OpenAI, Anthropic, Gemini, Groq, MiniMax, Ollama, LM Studio
|
||||||
- `embeddings.py`: Embedding generation (local sentence-transformers or TEI)
|
- `embeddings.py`: Embedding generation (local sentence-transformers or TEI)
|
||||||
- `cross_encoder.py`: Reranking (local or TEI)
|
- `cross_encoder.py`: Reranking (local or TEI)
|
||||||
- `entity_resolver.py`: Entity extraction and normalization
|
- `entity_resolver.py`: Entity extraction and normalization
|
||||||
|
|
@ -315,7 +315,7 @@ npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
Required env vars:
|
Required env vars:
|
||||||
- `HINDSIGHT_API_LLM_PROVIDER`: openai, anthropic, gemini, groq, ollama, lmstudio
|
- `HINDSIGHT_API_LLM_PROVIDER`: openai, anthropic, gemini, groq, minimax, ollama, lmstudio
|
||||||
- `HINDSIGHT_API_LLM_API_KEY`: Your API key
|
- `HINDSIGHT_API_LLM_API_KEY`: Your API key
|
||||||
- `HINDSIGHT_API_LLM_MODEL`: Model name (e.g., gpt-4o-mini, claude-sonnet-4-20250514)
|
- `HINDSIGHT_API_LLM_MODEL`: Model name (e.g., gpt-4o-mini, claude-sonnet-4-20250514)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
|
||||||
>API: http://localhost:8888
|
>API: http://localhost:8888
|
||||||
>UI: http://localhost:9999
|
>UI: http://localhost:9999
|
||||||
|
|
||||||
You can modify the LLM provider by setting `HINDSIGHT_API_LLM_PROVIDER`. Valid options are `openai`, `anthropic`, `gemini`, `groq`, `ollama`, and `lmstudio`. The documentation provides more details on [supported models](https://hindsight.vectorize.io/developer/models).
|
You can modify the LLM provider by setting `HINDSIGHT_API_LLM_PROVIDER`. Valid options are `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `lmstudio`, and `minimax`. The documentation provides more details on [supported models](https://hindsight.vectorize.io/developer/models).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,7 @@ PROVIDER_DEFAULT_MODELS = {
|
||||||
"anthropic": "claude-haiku-4-5-20251001",
|
"anthropic": "claude-haiku-4-5-20251001",
|
||||||
"gemini": "gemini-2.5-flash",
|
"gemini": "gemini-2.5-flash",
|
||||||
"groq": "openai/gpt-oss-120b",
|
"groq": "openai/gpt-oss-120b",
|
||||||
|
"minimax": "MiniMax-M2.5",
|
||||||
"ollama": "gemma3:12b",
|
"ollama": "gemma3:12b",
|
||||||
"lmstudio": "local-model",
|
"lmstudio": "local-model",
|
||||||
"vertexai": "google/gemini-2.5-flash-lite",
|
"vertexai": "google/gemini-2.5-flash-lite",
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ def create_llm_provider(
|
||||||
reasoning_effort=reasoning_effort,
|
reasoning_effort=reasoning_effort,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif provider_lower in ("openai", "groq", "ollama", "lmstudio"):
|
elif provider_lower in ("openai", "groq", "ollama", "lmstudio", "minimax"):
|
||||||
return OpenAICompatibleLLM(
|
return OpenAICompatibleLLM(
|
||||||
provider=provider,
|
provider=provider,
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
|
|
@ -296,6 +296,7 @@ class LLMProvider:
|
||||||
"openai-codex",
|
"openai-codex",
|
||||||
"claude-code",
|
"claude-code",
|
||||||
"mock",
|
"mock",
|
||||||
|
"minimax",
|
||||||
]
|
]
|
||||||
if self.provider not in valid_providers:
|
if self.provider not in valid_providers:
|
||||||
raise ValueError(f"Invalid LLM provider: {self.provider}. Must be one of: {', '.join(valid_providers)}")
|
raise ValueError(f"Invalid LLM provider: {self.provider}. Must be one of: {', '.join(valid_providers)}")
|
||||||
|
|
@ -308,6 +309,8 @@ class LLMProvider:
|
||||||
self.base_url = "http://localhost:11434/v1"
|
self.base_url = "http://localhost:11434/v1"
|
||||||
elif self.provider == "lmstudio":
|
elif self.provider == "lmstudio":
|
||||||
self.base_url = "http://localhost:1234/v1"
|
self.base_url = "http://localhost:1234/v1"
|
||||||
|
elif self.provider == "minimax":
|
||||||
|
self.base_url = "https://api.minimax.io/v1"
|
||||||
|
|
||||||
# Prepare Vertex AI config (if applicable)
|
# Prepare Vertex AI config (if applicable)
|
||||||
vertexai_project_id = None
|
vertexai_project_id = None
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
"""
|
"""
|
||||||
OpenAI-compatible LLM provider supporting OpenAI, Groq, Ollama, and LMStudio.
|
OpenAI-compatible LLM provider supporting OpenAI, Groq, Ollama, LMStudio, and MiniMax.
|
||||||
|
|
||||||
This provider handles all OpenAI API-compatible models including:
|
This provider handles all OpenAI API-compatible models including:
|
||||||
- OpenAI: GPT-4, GPT-4o, GPT-5, o1, o3 (reasoning models)
|
- OpenAI: GPT-4, GPT-4o, GPT-5, o1, o3 (reasoning models)
|
||||||
- Groq: Fast inference with seed control and service tiers
|
- Groq: Fast inference with seed control and service tiers
|
||||||
- Ollama: Local models with native streaming API support
|
- Ollama: Local models with native streaming API support
|
||||||
- LMStudio: Local models with OpenAI-compatible API
|
- LMStudio: Local models with OpenAI-compatible API
|
||||||
|
- MiniMax: MiniMax-M2.5 models with 204K context window
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Reasoning models with extended thinking (o1, o3, GPT-5 families)
|
- Reasoning models with extended thinking (o1, o3, GPT-5 families)
|
||||||
|
|
@ -47,6 +48,7 @@ class OpenAICompatibleLLM(LLMInterface):
|
||||||
- Groq: Fast inference with seed control and service tiers
|
- Groq: Fast inference with seed control and service tiers
|
||||||
- Ollama: Local models with native streaming API for better structured output
|
- Ollama: Local models with native streaming API for better structured output
|
||||||
- LMStudio: Local models with OpenAI-compatible API
|
- LMStudio: Local models with OpenAI-compatible API
|
||||||
|
- MiniMax: MiniMax-M2.5 models via OpenAI-compatible API (https://api.minimax.io/v1)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -76,7 +78,7 @@ class OpenAICompatibleLLM(LLMInterface):
|
||||||
super().__init__(provider, api_key, base_url, model, reasoning_effort, **kwargs)
|
super().__init__(provider, api_key, base_url, model, reasoning_effort, **kwargs)
|
||||||
|
|
||||||
# Validate provider
|
# Validate provider
|
||||||
valid_providers = ["openai", "groq", "ollama", "lmstudio"]
|
valid_providers = ["openai", "groq", "ollama", "lmstudio", "minimax"]
|
||||||
if self.provider not in valid_providers:
|
if self.provider not in valid_providers:
|
||||||
raise ValueError(f"OpenAICompatibleLLM only supports: {', '.join(valid_providers)}. Got: {self.provider}")
|
raise ValueError(f"OpenAICompatibleLLM only supports: {', '.join(valid_providers)}. Got: {self.provider}")
|
||||||
|
|
||||||
|
|
@ -88,13 +90,15 @@ class OpenAICompatibleLLM(LLMInterface):
|
||||||
self.base_url = "http://localhost:11434/v1"
|
self.base_url = "http://localhost:11434/v1"
|
||||||
elif self.provider == "lmstudio":
|
elif self.provider == "lmstudio":
|
||||||
self.base_url = "http://localhost:1234/v1"
|
self.base_url = "http://localhost:1234/v1"
|
||||||
|
elif self.provider == "minimax":
|
||||||
|
self.base_url = "https://api.minimax.io/v1"
|
||||||
|
|
||||||
# For ollama/lmstudio, use dummy key if not provided
|
# For ollama/lmstudio, use dummy key if not provided
|
||||||
if self.provider in ("ollama", "lmstudio") and not self.api_key:
|
if self.provider in ("ollama", "lmstudio") and not self.api_key:
|
||||||
self.api_key = "local"
|
self.api_key = "local"
|
||||||
|
|
||||||
# Validate API key for cloud providers
|
# Validate API key for cloud providers
|
||||||
if self.provider in ("openai", "groq") and not self.api_key:
|
if self.provider in ("openai", "groq", "minimax") and not self.api_key:
|
||||||
raise ValueError(f"API key is required for {self.provider}")
|
raise ValueError(f"API key is required for {self.provider}")
|
||||||
|
|
||||||
# Service tier configuration (from config, not env vars)
|
# Service tier configuration (from config, not env vars)
|
||||||
|
|
@ -231,6 +235,9 @@ class OpenAICompatibleLLM(LLMInterface):
|
||||||
|
|
||||||
# Temperature - reasoning models don't support custom temperature
|
# Temperature - reasoning models don't support custom temperature
|
||||||
if temperature is not None and not is_reasoning_model:
|
if temperature is not None and not is_reasoning_model:
|
||||||
|
# MiniMax requires temperature in (0.0, 1.0] — clamp accordingly
|
||||||
|
if self.provider == "minimax":
|
||||||
|
temperature = max(0.01, min(temperature, 1.0))
|
||||||
call_params["temperature"] = temperature
|
call_params["temperature"] = temperature
|
||||||
|
|
||||||
# Set reasoning_effort for reasoning models
|
# Set reasoning_effort for reasoning models
|
||||||
|
|
@ -546,6 +553,9 @@ class OpenAICompatibleLLM(LLMInterface):
|
||||||
if max_completion_tokens is not None:
|
if max_completion_tokens is not None:
|
||||||
call_params["max_completion_tokens"] = max_completion_tokens
|
call_params["max_completion_tokens"] = max_completion_tokens
|
||||||
if temperature is not None:
|
if temperature is not None:
|
||||||
|
# MiniMax requires temperature in (0.0, 1.0] — clamp accordingly
|
||||||
|
if self.provider == "minimax":
|
||||||
|
temperature = max(0.01, min(temperature, 1.0))
|
||||||
call_params["temperature"] = temperature
|
call_params["temperature"] = temperature
|
||||||
|
|
||||||
# Provider-specific parameters
|
# Provider-specific parameters
|
||||||
|
|
|
||||||
200
hindsight-api/tests/test_minimax_provider.py
Normal file
200
hindsight-api/tests/test_minimax_provider.py
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
"""Tests for MiniMax provider integration.
|
||||||
|
|
||||||
|
Validates that MiniMax is correctly registered as an OpenAI-compatible provider
|
||||||
|
with proper base URL, temperature clamping, and default model configuration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from hindsight_api.engine.llm_wrapper import LLMProvider, create_llm
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_provider_creation():
|
||||||
|
"""Test that MiniMax provider can be instantiated correctly."""
|
||||||
|
llm = LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="test-key",
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
assert llm.provider == "minimax"
|
||||||
|
assert llm.model == "MiniMax-M2.5"
|
||||||
|
assert llm.base_url == "https://api.minimax.io/v1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_default_base_url():
|
||||||
|
"""Test that MiniMax uses the correct default base URL when none is provided."""
|
||||||
|
llm = LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="test-key",
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
assert llm.base_url == "https://api.minimax.io/v1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_custom_base_url():
|
||||||
|
"""Test that a custom base URL overrides the default."""
|
||||||
|
llm = LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="test-key",
|
||||||
|
base_url="https://custom.api.example.com/v1",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
assert llm.base_url == "https://custom.api.example.com/v1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_factory_function():
|
||||||
|
"""Test that the create_llm factory function creates MiniMax provider correctly."""
|
||||||
|
llm = create_llm(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="test-key",
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
assert llm is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_requires_api_key():
|
||||||
|
"""Test that MiniMax provider requires an API key."""
|
||||||
|
with pytest.raises(ValueError, match="API key"):
|
||||||
|
LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="",
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_default_model_config():
|
||||||
|
"""Test that MiniMax has a default model in PROVIDER_DEFAULT_MODELS."""
|
||||||
|
from hindsight_api.config import PROVIDER_DEFAULT_MODELS
|
||||||
|
|
||||||
|
assert "minimax" in PROVIDER_DEFAULT_MODELS
|
||||||
|
assert PROVIDER_DEFAULT_MODELS["minimax"] == "MiniMax-M2.5"
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_config_default_model():
|
||||||
|
"""Test that MiniMax default model is used when model is not explicitly set."""
|
||||||
|
from hindsight_api.config import HindsightConfig, clear_config_cache
|
||||||
|
|
||||||
|
original_provider = os.environ.get("HINDSIGHT_API_LLM_PROVIDER")
|
||||||
|
original_model = os.environ.get("HINDSIGHT_API_LLM_MODEL")
|
||||||
|
|
||||||
|
try:
|
||||||
|
clear_config_cache()
|
||||||
|
os.environ["HINDSIGHT_API_LLM_PROVIDER"] = "minimax"
|
||||||
|
if "HINDSIGHT_API_LLM_MODEL" in os.environ:
|
||||||
|
del os.environ["HINDSIGHT_API_LLM_MODEL"]
|
||||||
|
|
||||||
|
config = HindsightConfig.from_env()
|
||||||
|
assert config.llm_provider == "minimax"
|
||||||
|
assert config.llm_model == "MiniMax-M2.5"
|
||||||
|
finally:
|
||||||
|
clear_config_cache()
|
||||||
|
if original_provider:
|
||||||
|
os.environ["HINDSIGHT_API_LLM_PROVIDER"] = original_provider
|
||||||
|
elif "HINDSIGHT_API_LLM_PROVIDER" in os.environ:
|
||||||
|
del os.environ["HINDSIGHT_API_LLM_PROVIDER"]
|
||||||
|
if original_model:
|
||||||
|
os.environ["HINDSIGHT_API_LLM_MODEL"] = original_model
|
||||||
|
elif "HINDSIGHT_API_LLM_MODEL" in os.environ:
|
||||||
|
del os.environ["HINDSIGHT_API_LLM_MODEL"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_minimax_temperature_clamping():
|
||||||
|
"""Test that MiniMax temperature is clamped to (0.0, 1.0] range."""
|
||||||
|
from hindsight_api.engine.providers.openai_compatible_llm import OpenAICompatibleLLM
|
||||||
|
|
||||||
|
llm = OpenAICompatibleLLM(
|
||||||
|
provider="minimax",
|
||||||
|
api_key="test-key",
|
||||||
|
base_url="https://api.minimax.io/v1",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify the provider is correctly set up for temperature clamping
|
||||||
|
assert llm.provider == "minimax"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_minimax_integration():
|
||||||
|
"""Integration test: verify MiniMax provider works with actual API.
|
||||||
|
|
||||||
|
Requires MINIMAX_API_KEY environment variable to be set.
|
||||||
|
"""
|
||||||
|
api_key = os.environ.get("MINIMAX_API_KEY")
|
||||||
|
if not api_key:
|
||||||
|
pytest.skip("MINIMAX_API_KEY not set")
|
||||||
|
|
||||||
|
llm = LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key=api_key,
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test verify_connection
|
||||||
|
await llm.verify_connection()
|
||||||
|
|
||||||
|
# Test basic call
|
||||||
|
response = await llm.call(
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": "You are a helpful assistant."},
|
||||||
|
{"role": "user", "content": "What is 2+2? Answer in one word."},
|
||||||
|
],
|
||||||
|
max_completion_tokens=50,
|
||||||
|
)
|
||||||
|
assert response is not None
|
||||||
|
assert len(response) > 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_minimax_tool_calling():
|
||||||
|
"""Integration test: verify MiniMax provider supports tool calling.
|
||||||
|
|
||||||
|
Requires MINIMAX_API_KEY environment variable to be set.
|
||||||
|
"""
|
||||||
|
api_key = os.environ.get("MINIMAX_API_KEY")
|
||||||
|
if not api_key:
|
||||||
|
pytest.skip("MINIMAX_API_KEY not set")
|
||||||
|
|
||||||
|
llm = LLMProvider(
|
||||||
|
provider="minimax",
|
||||||
|
api_key=api_key,
|
||||||
|
base_url="",
|
||||||
|
model="MiniMax-M2.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
tools = [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "get_weather",
|
||||||
|
"description": "Get the weather for a location",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"location": {"type": "string", "description": "City name"},
|
||||||
|
},
|
||||||
|
"required": ["location"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
result = await llm.call_with_tools(
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": "You are a helpful assistant with access to tools."},
|
||||||
|
{"role": "user", "content": "What's the weather like in Paris?"},
|
||||||
|
],
|
||||||
|
tools=tools,
|
||||||
|
max_completion_tokens=500,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result is not None
|
||||||
|
assert hasattr(result, "tool_calls")
|
||||||
|
assert len(result.tool_calls) > 0
|
||||||
|
assert result.tool_calls[0].name == "get_weather"
|
||||||
|
|
@ -160,7 +160,7 @@ To switch between backends:
|
||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|
|
||||||
| `HINDSIGHT_API_LLM_PROVIDER` | Provider: `openai`, `openai-codex`, `claude-code`, `anthropic`, `gemini`, `groq`, `ollama`, `lmstudio`, `vertexai` | `openai` |
|
| `HINDSIGHT_API_LLM_PROVIDER` | Provider: `openai`, `openai-codex`, `claude-code`, `anthropic`, `gemini`, `groq`, `minimax`, `ollama`, `lmstudio`, `vertexai` | `openai` |
|
||||||
| `HINDSIGHT_API_LLM_API_KEY` | API key for LLM provider | - |
|
| `HINDSIGHT_API_LLM_API_KEY` | API key for LLM provider | - |
|
||||||
| `HINDSIGHT_API_LLM_MODEL` | Model name | `gpt-5-mini` |
|
| `HINDSIGHT_API_LLM_MODEL` | Model name | `gpt-5-mini` |
|
||||||
| `HINDSIGHT_API_LLM_BASE_URL` | Custom LLM endpoint | Provider default |
|
| `HINDSIGHT_API_LLM_BASE_URL` | Custom LLM endpoint | Provider default |
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ All local models (embedding, cross-encoder) are automatically downloaded from Hu
|
||||||
|
|
||||||
Used for fact extraction, entity resolution, mental model consolidation, and answer synthesis.
|
Used for fact extraction, entity resolution, mental model consolidation, and answer synthesis.
|
||||||
|
|
||||||
**Supported providers:** OpenAI, Anthropic, Gemini, Groq, Ollama, LM Studio, and **any OpenAI-compatible API**
|
**Supported providers:** OpenAI, Anthropic, Gemini, Groq, MiniMax, Ollama, LM Studio, and **any OpenAI-compatible API**
|
||||||
|
|
||||||
:::tip OpenAI-Compatible Providers
|
:::tip OpenAI-Compatible Providers
|
||||||
Hindsight works with any provider that exposes an OpenAI-compatible API (e.g., Azure OpenAI). Simply set `HINDSIGHT_API_LLM_PROVIDER=openai` and configure `HINDSIGHT_API_LLM_BASE_URL` to point to your provider's endpoint.
|
Hindsight works with any provider that exposes an OpenAI-compatible API (e.g., Azure OpenAI). Simply set `HINDSIGHT_API_LLM_PROVIDER=openai` and configure `HINDSIGHT_API_LLM_BASE_URL` to point to your provider's endpoint.
|
||||||
|
|
@ -63,6 +63,7 @@ Each provider has a recommended default model that's used when `HINDSIGHT_API_LL
|
||||||
| `anthropic` | `claude-haiku-4-5-20251001` |
|
| `anthropic` | `claude-haiku-4-5-20251001` |
|
||||||
| `gemini` | `gemini-2.5-flash` |
|
| `gemini` | `gemini-2.5-flash` |
|
||||||
| `groq` | `openai/gpt-oss-120b` |
|
| `groq` | `openai/gpt-oss-120b` |
|
||||||
|
| `minimax` | `MiniMax-M2.5` |
|
||||||
| `ollama` | `gemma3:12b` |
|
| `ollama` | `gemma3:12b` |
|
||||||
| `lmstudio` | `local-model` |
|
| `lmstudio` | `local-model` |
|
||||||
| `vertexai` | `gemini-2.0-flash-001` |
|
| `vertexai` | `gemini-2.0-flash-001` |
|
||||||
|
|
@ -144,6 +145,11 @@ export HINDSIGHT_API_LLM_PROVIDER=lmstudio
|
||||||
export HINDSIGHT_API_LLM_BASE_URL=http://localhost:1234/v1
|
export HINDSIGHT_API_LLM_BASE_URL=http://localhost:1234/v1
|
||||||
export HINDSIGHT_API_LLM_MODEL=your-local-model
|
export HINDSIGHT_API_LLM_MODEL=your-local-model
|
||||||
|
|
||||||
|
# MiniMax (204K context window)
|
||||||
|
export HINDSIGHT_API_LLM_PROVIDER=minimax
|
||||||
|
export HINDSIGHT_API_LLM_API_KEY=your-minimax-api-key
|
||||||
|
export HINDSIGHT_API_LLM_MODEL=MiniMax-M2.5
|
||||||
|
|
||||||
# Vertex AI (Google Cloud)
|
# Vertex AI (Google Cloud)
|
||||||
export HINDSIGHT_API_LLM_PROVIDER=vertexai
|
export HINDSIGHT_API_LLM_PROVIDER=vertexai
|
||||||
export HINDSIGHT_API_LLM_MODEL=gemini-2.0-flash-001
|
export HINDSIGHT_API_LLM_MODEL=gemini-2.0-flash-001
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ The daemon starts automatically on first use!
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|
|
||||||
| `HINDSIGHT_EMBED_LLM_API_KEY` | **Required**. API key for LLM provider | - |
|
| `HINDSIGHT_EMBED_LLM_API_KEY` | **Required**. API key for LLM provider | - |
|
||||||
| `HINDSIGHT_EMBED_LLM_PROVIDER` | LLM provider: `openai`, `anthropic`, `gemini`, `groq`, `ollama` | `openai` |
|
| `HINDSIGHT_EMBED_LLM_PROVIDER` | LLM provider: `openai`, `anthropic`, `gemini`, `groq`, `minimax`, `ollama` | `openai` |
|
||||||
| `HINDSIGHT_EMBED_LLM_MODEL` | Model name | `gpt-4o-mini` |
|
| `HINDSIGHT_EMBED_LLM_MODEL` | Model name | `gpt-4o-mini` |
|
||||||
| `HINDSIGHT_EMBED_BANK_ID` | Default memory bank ID | `default` |
|
| `HINDSIGHT_EMBED_BANK_ID` | Default memory bank ID | `default` |
|
||||||
| `HINDSIGHT_EMBED_DAEMON_IDLE_TIMEOUT` | Seconds before daemon auto-exits when idle (0 = never) | `300` |
|
| `HINDSIGHT_EMBED_DAEMON_IDLE_TIMEOUT` | Seconds before daemon auto-exits when idle (0 = never) | `300` |
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue