Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/models_provider/constants/model_provider_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from models_provider.impl.local_model_provider.local_model_provider import LocalModelProvider
from models_provider.impl.ollama_model_provider.ollama_model_provider import OllamaModelProvider
from models_provider.impl.openai_model_provider.openai_model_provider import OpenAIModelProvider
from models_provider.impl.orcarouter_model_provider.orcarouter_model_provider import OrcaRouterModelProvider
from models_provider.impl.regolo_model_provider.regolo_model_provider import RegoloModelProvider
from models_provider.impl.siliconCloud_model_provider.siliconCloud_model_provider import SiliconCloudModelProvider
from models_provider.impl.tencent_cloud_model_provider.tencent_cloud_model_provider import TencentCloudModelProvider
Expand All @@ -32,6 +33,7 @@ class ModelProvideConstants(Enum):
model_wenxin_provider = WenxinModelProvider()
model_ollama_provider = OllamaModelProvider()
model_openai_provider = OpenAIModelProvider()
model_orcarouter_provider = OrcaRouterModelProvider()
model_docker_ai_provider = DockerModelProvider()
model_kimi_provider = KimiModelProvider()
model_zhipu_provider = ZhiPuModelProvider()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :MaxKB
@File :__init__.py.py
@Date :2026-08-15
"""
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎
@file: llm.py
@date:2024/7/11 17:51
@desc:
"""
from typing import Dict

from django.utils.translation import gettext_lazy as _, gettext
from langchain_core.messages import HumanMessage

from common import forms
from common.exception.app_exception import AppApiException
from common.forms import BaseForm, TooltipLabel
from models_provider.base_model_provider import BaseModelCredential, ValidCode
from common.utils.logger import maxkb_logger


class OrcaRouterLLMModelParams(BaseForm):
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
required=True, default_value=0.7,
_min=0.1,
_max=1.0,
_step=0.01,
precision=2)

max_tokens = forms.SliderField(
TooltipLabel(_('Output the maximum Tokens'),
_('Specify the maximum number of tokens that the model can generate')),
required=True, default_value=8192,
_min=1,
_max=100000,
_step=1,
precision=0)


class OrcaRouterLLMModelCredential(BaseForm, BaseModelCredential):

def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
raise_exception=False):
model_type_list = provider.get_model_type_list()
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
raise AppApiException(ValidCode.valid_error.value,
gettext('{model_type} Model type is not supported').format(model_type=model_type))

for key in ['api_key', 'api_base']:
if key not in model_credential:
if raise_exception:
raise AppApiException(ValidCode.valid_error.value, gettext('{key} is required').format(key=key))
else:
return False
try:
model = provider.get_model(model_type, model_name, model_credential, **model_params)
model.invoke([HumanMessage(content=gettext('Hello'))])
except Exception as e:
maxkb_logger.error(f'Exception: {e}', exc_info=True)
if isinstance(e, AppApiException):
raise e
if raise_exception:
raise AppApiException(ValidCode.valid_error.value,
gettext(
'Verification failed, please check whether the parameters are correct: {error}').format(
error=str(e)))
else:
return False
return True

def encryption_dict(self, model: Dict[str, object]):
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}

api_base = forms.TextInputField(_('API URL'), required=True,
default_value='https://api.orcarouter.ai/v1')
api_key = forms.PasswordInputField('API Key', required=True)

def get_model_params_setting_form(self, model_name):
return OrcaRouterLLMModelParams()
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100%" height="100%" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" rx="22" fill="#0A2A4A"/>
<path d="M18 58c0-18 14-30 32-30s32 12 32 30v6c0 4-3 7-7 5l-8-6-6 8-7-7-7 7-6-8-8 6c-4 2-7-1-7-5z" fill="#FFFFFF"/>
<path d="M25 47c3-6 9-10 16-12" stroke="#7FD1FF" stroke-width="3" fill="none" stroke-linecap="round"/>
<path d="M50 28c6 2 10 6 13 11" stroke="#7FD1FF" stroke-width="3" fill="none" stroke-linecap="round"/>
<circle cx="34" cy="54" r="2.4" fill="#0A2A4A"/>
</svg>
Empty file.
38 changes: 38 additions & 0 deletions apps/models_provider/impl/orcarouter_model_provider/model/llm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎
@file: llm.py
@date:2024/4/18 15:28
@desc:
"""
from typing import Dict

from langchain_core.messages import BaseMessage, get_buffer_string
from langchain_openai.chat_models import ChatOpenAI

from common.config.tokenizer_manage_config import TokenizerManage
from models_provider.base_model_provider import MaxKBBaseModel
from models_provider.impl.base_chat_open_ai import BaseChatOpenAI


def custom_get_token_ids(text: str):
tokenizer = TokenizerManage.get_tokenizer()
return tokenizer.encode(text)


class OrcaRouterChatModel(MaxKBBaseModel, BaseChatOpenAI):

@staticmethod
def is_cache_model():
return False

@staticmethod
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
return OrcaRouterChatModel(
model=model_name,
openai_api_base=model_credential.get('api_base') or "https://api.orcarouter.ai/v1",
openai_api_key=model_credential.get('api_key'),
**optional_params,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :MaxKB
@File :orcarouter_model_provider.py
@Date :2026-08-15
"""

import os

from common.utils.common import get_file_content
from models_provider.base_model_provider import (
IModelProvider,
ModelProvideInfo,
ModelInfo,
ModelTypeConst,
ModelInfoManage,
)
from models_provider.impl.orcarouter_model_provider.credential.llm import OrcaRouterLLMModelCredential
from models_provider.impl.orcarouter_model_provider.model.llm import OrcaRouterChatModel
from maxkb.conf import PROJECT_DIR

orcarouter_llm_model_credential = OrcaRouterLLMModelCredential()
orcarouter_llm_list = [
ModelInfo("orcarouter/auto", "", ModelTypeConst.LLM, orcarouter_llm_model_credential, OrcaRouterChatModel),
ModelInfo("openai/gpt-5.5", "", ModelTypeConst.LLM, orcarouter_llm_model_credential, OrcaRouterChatModel),
ModelInfo("google/gemini-3.5-flash", "", ModelTypeConst.LLM, orcarouter_llm_model_credential,
OrcaRouterChatModel),
ModelInfo("anthropic/claude-opus-4.8", "", ModelTypeConst.LLM, orcarouter_llm_model_credential,
OrcaRouterChatModel),
ModelInfo("grok/grok-4.3", "", ModelTypeConst.LLM, orcarouter_llm_model_credential, OrcaRouterChatModel),
ModelInfo("deepseek/deepseek-v4-pro", "", ModelTypeConst.LLM, orcarouter_llm_model_credential,
OrcaRouterChatModel),
ModelInfo("minimax/minimax-m2.7", "", ModelTypeConst.LLM, orcarouter_llm_model_credential,
OrcaRouterChatModel),
ModelInfo("qwen/qwen3.7-max", "", ModelTypeConst.LLM, orcarouter_llm_model_credential, OrcaRouterChatModel),
]

model_info_manage = (
ModelInfoManage.builder()
.append_model_info_list(orcarouter_llm_list)
.append_default_model_info(orcarouter_llm_list[1])
.build()
)


class OrcaRouterModelProvider(IModelProvider):
def get_model_info_manage(self):
return model_info_manage

def get_model_provide_info(self):
return ModelProvideInfo(
provider="model_orcarouter_provider",
name="OrcaRouter",
icon=get_file_content(
os.path.join(
PROJECT_DIR,
"apps",
"models_provider",
"impl",
"orcarouter_model_provider",
"icon",
"orcarouter_icon_svg",
)
),
)