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
18 changes: 13 additions & 5 deletions ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@ def __init__(self, cfg: Config):
self._chat_model: GPTModel = cfg.open_ai_chat_model
self._embedding_model: EmbeddingModel = cfg.open_ai_embedding_model
self._use_stream = cfg.use_stream
self._encoding = tiktoken.encoding_for_model(self._chat_model.name)
try:
self._encoding = tiktoken.encoding_for_model(self._chat_model.name)
except KeyError:
# Fallback for non-OpenAI models (e.g. MiniMax)
self._encoding = tiktoken.get_encoding('cl100k_base')
self._language = cfg.language
self._temperature = cfg.temperature
self.client = OpenAI(api_key=cfg.open_ai_key)
client_kwargs = dict(api_key=cfg.open_ai_key)
if cfg.open_ai_base_url:
client_kwargs['base_url'] = cfg.open_ai_base_url
self.client = OpenAI(**client_kwargs)

def _chat_stream(self, messages: list[dict], use_stream: bool = None) -> str:
use_stream = use_stream if use_stream is not None else self._use_stream
Expand All @@ -33,9 +40,10 @@ def _chat_stream(self, messages: list[dict], use_stream: bool = None) -> str:
if use_stream:
data = ""
for chunk in response:
if chunk.choices[0].delta.get('content', None) is not None:
data += chunk.choices[0].delta.content
print(chunk.choices[0].delta.content, end='')
content = getattr(chunk.choices[0].delta, 'content', None)
if content is not None:
data += content
print(content, end='')
print()
return data.strip()
else:
Expand Down
1 change: 1 addition & 0 deletions config.example.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"open_ai_key": "",
"open_ai_base_url": "",
"temperature": 0.1,
"language": "English",
"open_ai_chat_model": "gpt-3.5-turbo",
Expand Down
11 changes: 11 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class GPTModel:

GPTModel('gpt-3.5-turbo-16k', 16385, 0.0005, 0.0015), # gpt-3.5-turbo-16k-0613
GPTModel('gpt-3.5-turbo-16k-0613', 16385, 0.0005, 0.0015),

# MiniMax models (OpenAI-compatible API at https://api.minimax.io/v1)
GPTModel('MiniMax-M2.7', 1_000_000, 0.004, 0.016),
GPTModel('MiniMax-M2.7-highspeed', 1_000_000, 0.001, 0.004),
]


Expand Down Expand Up @@ -61,6 +65,7 @@ def __init__(self):
self.language = self.config.get('language', 'Chinese')
self.open_ai_key = self.config.get('open_ai_key')
self.open_ai_proxy = self.config.get('open_ai_proxy')
self.open_ai_base_url = self.config.get('open_ai_base_url')
gpt_model = self.config.get('open_ai_chat_model', 'gpt-3.5-turbo')
self.open_ai_chat_model = self.get_gpt_model(gpt_model)
embedding_model = self.config.get('open_ai_embedding_model', 'text-embedding-ada-002')
Expand All @@ -71,6 +76,9 @@ def __init__(self):
if self.temperature < 0 or self.temperature > 1:
raise ValueError(
'temperature must be between 0 and 1, less is more conservative, more is more creative')
# MiniMax requires temperature > 0
if self.is_minimax_model() and self.temperature == 0:
self.temperature = 0.01
self.use_stream = self.config.get('use_stream', False)
self.use_postgres = self.config.get('use_postgres', False)
if not self.use_postgres:
Expand Down Expand Up @@ -98,3 +106,6 @@ def get_embedding_model(self, model: str):
if model not in name_list:
raise ValueError('open_ai_embedding_model must be one of ' + ', '.join(name_list))
return next(m for m in SUPPORTED_EMBEDDING_MODELS if m.name == model)

def is_minimax_model(self):
return self.open_ai_chat_model.name.startswith('MiniMax-')
19 changes: 19 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ if you prefer, you can also run this project using docker:
}
```

## Using MiniMax as Chat Model

ChatWeb supports [MiniMax](https://www.minimaxi.com/) models via their OpenAI-compatible API. MiniMax M2.7 offers a 1M token context window.

- Edit `config.json` and set:
```json
{
"open_ai_key": "your-minimax-api-key",
"open_ai_base_url": "https://api.minimax.io/v1",
"open_ai_chat_model": "MiniMax-M2.7"
}
```

Available MiniMax models:
- `MiniMax-M2.7` — flagship model with 1M context window
- `MiniMax-M2.7-highspeed` — faster variant with 1M context window

> **Note:** MiniMax models are used for chat only. Embeddings still use OpenAI's embedding API, so a separate OpenAI API key may be needed for embedding if you want to use MiniMax for chat.

## Install PostgreSQL (Optional)

- Edit `config.json` and set `use_postgres` to `true`.
Expand Down
19 changes: 19 additions & 0 deletions readme.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ python3 main.py
}
```

## 使用MiniMax作为Chat模型

ChatWeb支持通过OpenAI兼容API使用[MiniMax](https://www.minimaxi.com/)模型。MiniMax M2.7拥有100万token上下文窗口。

- 编辑`config.json`,设置:
```json
{
"open_ai_key": "你的MiniMax API密钥",
"open_ai_base_url": "https://api.minimax.io/v1",
"open_ai_chat_model": "MiniMax-M2.7"
}
```

可用的MiniMax模型:
- `MiniMax-M2.7` — 旗舰模型,100万token上下文窗口
- `MiniMax-M2.7-highspeed` — 高速版本,100万token上下文窗口

> **注意:** MiniMax模型仅用于聊天功能。Embedding仍使用OpenAI的Embedding API,如果您使用MiniMax进行聊天,可能需要单独的OpenAI API密钥用于Embedding。

## 安装postgresql(可选)

- 编辑`config.json`, 设置`use_postgres`为`true`
Expand Down
Empty file added tests/__init__.py
Empty file.
Loading