Conversation
Fixes #6294 QQ official bot receives emoji/sticker messages as raw XML-like tags: `<faceType=4,faceId="",ext="eyJ0ZXh0IjoiW+a7oeWktOmXruWPt10ifQ==">` This made the LLM unable to understand the emoji content. Changes: - Added `_parse_face_message()` method to parse face message format - Decode base64 `ext` field to get emoji description text - Replace face tags with `[表情:描述]` format for readability Example: - Input: `<faceType=4,faceId="",ext="eyJ0ZXh0IjoiW+a7oeWktOmXruWPt10ifQ==">` - Output: `[表情:[满头问号]]` Co-authored-by: ccsang <ccsang@users.noreply.github.com>
* fix(telegram): route GIF files to send_animation instead of send_photo * fix: narrow exception in _is_gif to OSError Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * refactor: simplify image send dispatch in send_with_client Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * refactor: simplify image dispatch in _process_chain_items * ruff format --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Soulter <905617992@qq.com>
* feat(provider): add MiniMax * feat(provider): reintroduce MiniMax provider configuration and remove deprecated source --------- Co-authored-by: Soulter <905617992@qq.com>
…kills-like". (#6317) * fix: improve send_message_to_user tool description for skills_like mode * fix: enhance description for send_message_to_user tool to clarify usage --------- Co-authored-by: Soulter <905617992@qq.com>
…rror when tool calls are returned (#6365)
* Fix CreateSkillPayloadTool array schema missing items field
The payload parameter's anyOf array variant lacked an items field,
causing Gemini API to reject the tool declaration with 400 Bad Request:
'parameters.properties[payload].any_of[1].items: missing field.'
Add items: {type: object} to the array variant to satisfy the Gemini
API requirement for array type schemas.
Fixes #6279
* Fix TypeError when OpenAI-compatible API returns null choices
Some providers (e.g. OpenRouter) may return a completion where
choices is None rather than an empty list — for instance on rate
limiting, content filtering, or transient errors. The existing code
used len(completion.choices) which throws TypeError on None.
Replace all len(...choices) == 0 checks with 'not ... .choices' which
handles both None and empty list. Affects _query_stream, _parse_openai_completion,
and _extract_reasoning_content.
Fixes #6252
Co-authored-by: Stable Genius <259448942+stablegenius49@users.noreply.github.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates a range of enhancements and fixes across the AstrBot project, focusing on improving platform compatibility, refining tool functionalities, and enhancing overall system robustness. Key updates include better handling of diverse message types and media across different platforms, ensuring API compatibility with new and existing AI providers, and streamlining internal processes through schema improvements and automated scripting. The changes aim to provide a more stable and feature-rich experience for users and developers alike. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Hey - I've found 1 security issue, 2 other issues, and left some high level feedback:
Security issues:
- Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)
General comments:
- In
QQOfficialPlatformAdapter._parse_face_message, consider moving there,base64, andjsonimports and the face-tag regex to module scope and narrowing theexcept Exceptionaround the base64/JSON decode to more specific exceptions (e.g.,binascii.Error,json.JSONDecodeError) to avoid masking unexpected errors and to reduce per-call overhead. - The webhook dedup cache in
QoWebhookServercurrently uses a plain dict with lazy eviction; if this process runs long-lived or at higher volume, consider encapsulating this into a small TTL cache helper (or usingcollections.OrderedDict) to make eviction logic clearer and guarantee bounded memory growth.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `QQOfficialPlatformAdapter._parse_face_message`, consider moving the `re`, `base64`, and `json` imports and the face-tag regex to module scope and narrowing the `except Exception` around the base64/JSON decode to more specific exceptions (e.g., `binascii.Error`, `json.JSONDecodeError`) to avoid masking unexpected errors and to reduce per-call overhead.
- The webhook dedup cache in `QoWebhookServer` currently uses a plain dict with lazy eviction; if this process runs long-lived or at higher volume, consider encapsulating this into a small TTL cache helper (or using `collections.OrderedDict`) to make eviction logic clearer and guarantee bounded memory growth.
## Individual Comments
### Comment 1
<location path="astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py" line_range="414-423" />
<code_context>
+ import json
+ import re
+
+ def replace_face(match):
+ face_tag = match.group(0)
+ # Extract ext field from the face tag
+ ext_match = re.search(r'ext="([^"]*)"', face_tag)
+ if ext_match:
+ try:
+ ext_encoded = ext_match.group(1)
+ # Decode base64 and parse JSON
+ ext_decoded = base64.b64decode(ext_encoded).decode("utf-8")
+ ext_data = json.loads(ext_decoded)
+ emoji_text = ext_data.get("text", "")
+ if emoji_text:
+ return f"[表情:{emoji_text}]"
+ except Exception:
+ pass
+ # Fallback if parsing fails
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Narrow the exception handling when decoding the `ext` field to avoid masking unrelated errors.
Catching `Exception` here hides all parsing and programming errors, making real bugs hard to detect and debug. Limit this to the specific, expected failures (e.g. `binascii.Error`, `json.JSONDecodeError`, `UnicodeDecodeError`) so unexpected issues surface instead of always falling back to `[表情]`.
Suggested implementation:
```python
import base64
import binascii
import json
import re
```
```python
except (binascii.Error, json.JSONDecodeError, UnicodeDecodeError):
# Fallback to generic placeholder on expected decoding/parsing errors
pass
```
</issue_to_address>
### Comment 2
<location path="scripts/close_duplicate_plugin_publish_issues.py" line_range="98-99" />
<code_context>
+ ]
+
+
+def normalize_title(title: str) -> str:
+ return " ".join(title.split()).strip()
+
+
</code_context>
<issue_to_address>
**suggestion:** Consider normalizing titles case-insensitively to catch more duplicates.
`normalize_title` only normalizes whitespace, so titles that differ only by case (e.g., `"My Plugin"` vs `"my plugin"`) won’t be grouped together. If you want semantic deduplication, also normalize case, e.g.:
```python
return " ".join(title.split()).strip().casefold()
```
```suggestion
def normalize_title(title: str) -> str:
# Normalize whitespace and case so titles differing only by spacing or case are treated as duplicates
return " ".join(title.split()).strip().casefold()
```
</issue_to_address>
### Comment 3
<location path="scripts/close_duplicate_plugin_publish_issues.py" line_range="52-57" />
<code_context>
completed = subprocess.run(
args,
check=True,
capture_output=True,
text=True,
)
</code_context>
<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
*Source: opengrep*
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| def replace_face(match): | ||
| face_tag = match.group(0) | ||
| # Extract ext field from the face tag | ||
| ext_match = re.search(r'ext="([^"]*)"', face_tag) | ||
| if ext_match: | ||
| try: | ||
| ext_encoded = ext_match.group(1) | ||
| # Decode base64 and parse JSON | ||
| ext_decoded = base64.b64decode(ext_encoded).decode("utf-8") | ||
| ext_data = json.loads(ext_decoded) |
There was a problem hiding this comment.
suggestion (bug_risk): Narrow the exception handling when decoding the ext field to avoid masking unrelated errors.
Catching Exception here hides all parsing and programming errors, making real bugs hard to detect and debug. Limit this to the specific, expected failures (e.g. binascii.Error, json.JSONDecodeError, UnicodeDecodeError) so unexpected issues surface instead of always falling back to [表情].
Suggested implementation:
import base64
import binascii
import json
import re except (binascii.Error, json.JSONDecodeError, UnicodeDecodeError):
# Fallback to generic placeholder on expected decoding/parsing errors
pass| def normalize_title(title: str) -> str: | ||
| return " ".join(title.split()).strip() |
There was a problem hiding this comment.
suggestion: Consider normalizing titles case-insensitively to catch more duplicates.
normalize_title only normalizes whitespace, so titles that differ only by case (e.g., "My Plugin" vs "my plugin") won’t be grouped together. If you want semantic deduplication, also normalize case, e.g.:
return " ".join(title.split()).strip().casefold()| def normalize_title(title: str) -> str: | |
| return " ".join(title.split()).strip() | |
| def normalize_title(title: str) -> str: | |
| # Normalize whitespace and case so titles differing only by spacing or case are treated as duplicates | |
| return " ".join(title.split()).strip().casefold() |
There was a problem hiding this comment.
Code Review
This pull request syncs a variety of changes from the master branch to dev, including new features, bug fixes, and enhancements across different parts of the application. The changes are generally well-implemented and improve the codebase. I have one suggestion regarding exception handling and import placement in the new QQ face message parsing logic to improve maintainability and robustness.
| try: | ||
| ext_encoded = ext_match.group(1) | ||
| # Decode base64 and parse JSON | ||
| ext_decoded = base64.b64decode(ext_encoded).decode("utf-8") | ||
| ext_data = json.loads(ext_decoded) | ||
| emoji_text = ext_data.get("text", "") | ||
| if emoji_text: | ||
| return f"[表情:{emoji_text}]" | ||
| except Exception: | ||
| pass |
There was a problem hiding this comment.
The except Exception: is too broad and can hide unexpected errors. It's better to catch specific exceptions that you expect to occur, such as json.JSONDecodeError, ValueError (for base64 decoding issues), or UnicodeDecodeError.
Also, the import statements for base64, json, and re should be moved to the top of the file.
| try: | |
| ext_encoded = ext_match.group(1) | |
| # Decode base64 and parse JSON | |
| ext_decoded = base64.b64decode(ext_encoded).decode("utf-8") | |
| ext_data = json.loads(ext_decoded) | |
| emoji_text = ext_data.get("text", "") | |
| if emoji_text: | |
| return f"[表情:{emoji_text}]" | |
| except Exception: | |
| pass | |
| try: | |
| ext_encoded = ext_match.group(1) | |
| # Decode base64 and parse JSON | |
| ext_decoded = base64.b64decode(ext_encoded).decode("utf-8") | |
| ext_data = json.loads(ext_decoded) | |
| emoji_text = ext_data.get("text", "") | |
| if emoji_text: | |
| return f"[表情:{emoji_text}]" | |
| except (json.JSONDecodeError, ValueError, UnicodeDecodeError): | |
| pass |
References
- Import statements should be placed at the top of the file, one import per line, as per PEP 8 guidelines. (link)
|
Related Documentation 1 document(s) may need updating based on files changed in this PR: AstrBotTeam's Space pr4697的改动View Suggested Changes@@ -373,12 +373,21 @@
- 支持多平台:Telegram、Slack、Discord 等
- 支持多种消息类型:`plain`(文本)、`image`(图片)、`record`(语音消息)、`video`(视频)、`file`(文件)、`mention_user`(提及用户)
+#### 工具描述增强(PR #6397)
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 增强了 `send_message_to_user` 工具的描述信息,明确列出所有支持的消息类型和使用场景:
+
+- **工具描述更新**:工具描述现在明确说明支持多种消息类型(`plain`、`image`、`record`、`video`、`file`、`mention_user`)
+- **使用场景说明**:工具描述清晰指出适用场景:
+ - 发送媒体文件(`image`、`record`、`video`、`file`)时应使用此工具
+ - 主动推送消息(如定时任务 cron job)时应使用此工具
+ - 普通文本回复可直接输出,无需调用此工具
+- **避免绕路**:增强的描述确保 AI 能够正确理解该工具的功能,避免使用 Python 工具等绕弯路的方式处理媒体文件
+
#### 使用场景
- **发送多媒体文件**:使用该工具发送图片、语音、视频、文件等媒体内容
- **主动推送消息**:在定时任务或后台任务中主动向用户发送消息
- **普通文本回复**:对于普通文本回复,可以直接在对话中输出,无需使用此工具
-
-> **注意**:在 `skills_like` 工具调用模式下,该工具描述已明确列出所有支持的消息类型,确保 AI 能够正确理解该工具支持发送多媒体消息,避免使用 Python 工具等绕弯路的方式处理媒体文件。
#### 使用示例
在定时任务触发后,主动调用 `send_message_to_user` 工具,将生成的日报、图片或其他内容直接发送给用户。
@@ -1385,7 +1394,156 @@
---
-### 14. 其他优化
+### 14. 平台支持增强(PR #6397)
+
+#### Telegram GIF 图片支持
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 增强了 Telegram 平台对 GIF 图片的支持。修复后,GIF 图片会被正确识别并作为动画发送,而非静态图片:
+
+**检测机制**:
+- 通过文件扩展名(`.gif`)或文件头部魔数(`GIF87a` / `GIF89a`)识别 GIF 图片
+- 系统自动检测图片类型,无需用户手动指定
+
+**发送行为**:
+- **GIF 图片**:使用 `send_animation` API 发送,确保 GIF 在 Telegram 中正常播放动画
+- **静态图片**:使用 `send_photo` API 发送,保持原有行为
+- **聊天状态**:发送 GIF 时显示 `UPLOAD_VIDEO` 聊天状态,而非 `UPLOAD_PHOTO`
+
+**影响范围**:
+- `TelegramPlatformEvent.send_with_client()` 方法:消息链发送逻辑
+- `TelegramPlatformEvent._process_chain_items()` 方法:流式消息处理逻辑
+
+该修复确保 Telegram 平台的 GIF 图片体验与原生 Telegram 客户端一致,提升多媒体消息的交互质量。
+
+#### QQ 官方平台表情解析
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 新增了 QQ 官方平台的表情(emoji)消息解析功能,将 base64 编码的表情数据转换为可读文本格式:
+
+**表情消息格式**:
+- QQ 官方表情消息格式为:`<faceType=4,faceId="",ext="eyJ0ZXh0IjoiW+a7oeWktOmXruWPt10ifQ==">`
+- `ext` 字段包含 base64 编码的 JSON 数据,其中 `text` 字段描述表情内容(如 `[满头问号]`)
+
+**解析机制**:
+- 新增 `_parse_face_message()` 静态方法,提取并解析 `ext` 字段
+- 自动解码 base64 数据并提取 JSON 中的 `text` 字段
+- 转换格式:`<faceType=...>` → `[表情:满头问号]`
+- 解析失败时回退到 `[表情]` 占位符
+
+**影响范围**:
+- `QQOfficialPlatformAdapter._parse_from_qqofficial()` 方法:消息解析逻辑
+- 支持私聊和群聊场景下的表情消息
+
+该功能改善了 QQ 官方平台的消息处理和显示,使表情消息在日志、历史记录和对话中以可读格式呈现,提升用户体验。
+
+#### QQ 官方 Webhook 重复事件去重
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 为 QQ 官方 Webhook 模式新增了事件去重机制,防止重复事件被多次处理:
+
+**去重机制**:
+- 维护 `_seen_event_ids` 缓存,记录已处理的事件 ID 和时间戳
+- 使用 60 秒的 TTL(`_dedup_ttl`),自动清理过期的事件 ID
+- 惰性淘汰策略:在检查新事件时自动清理过期记录,防止缓存无限增长
+
+**处理逻辑**:
+- 接收到 webhook 事件时,检查事件 ID 是否在缓存中
+- 如果事件 ID 已存在,记录调试日志并返回 `{"opcode": 12}`,跳过处理
+- 如果事件 ID 不存在,将其添加到缓存并继续处理
+
+**适用场景**:
+- QQ 官方 Webhook 重试回调(retry callback)
+- 网络不稳定导致的重复推送
+- 防止消息重复处理和响应
+
+该机制提升了 QQ 官方 Webhook 模式的健壮性,确保事件在重复推送场景下仅被处理一次。
+
+---
+
+### 15. AI 提供商支持更新(PR #6397)
+
+#### MiniMax 提供商支持
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 新增了 MiniMax 作为支持的 AI 提供商:
+
+**配置模板**:
+- **提供商 ID**:`minimax`
+- **提供商类型**:`openai_chat_completion`
+- **API 地址**:`https://api.minimaxi.com/v1`
+- **超时时间**:120 秒
+- **默认状态**:已启用(`enable: true`)
+
+**使用方式**:
+- 在配置文件中添加 MiniMax API 密钥(`key` 字段)
+- 支持标准的 OpenAI Chat Completion 接口
+- 可通过 `/provider` 命令切换到 MiniMax 提供商
+- 可通过 `/model` 命令选择 MiniMax 模型
+
+**Dashboard 集成**:
+- 提供商图标使用 LobeHub 官方 SVG(`https://cdn.jsdelivr.net/npm/@lobehub/icons-static-svg@latest/icons/minimax.svg`)
+- 在提供商选择下拉菜单中显示为 "MiniMax"
+
+该支持扩展了 AstrBot 的 AI 提供商生态,为用户提供更多模型选择。
+
+#### Groq 提供商兼容性修复
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 修复了 Groq 提供商在处理消息历史时的兼容性问题:
+
+**问题背景**:
+- Groq API 拒绝包含 `reasoning_content` 字段的 assistant 历史消息
+- 当使用推理模型(如 DeepSeek R1)生成的历史记录发送到 Groq 时,会导致请求失败
+
+**修复实现**:
+- 新增 `ProviderGroq._finally_convert_payload()` 方法,重写父类的 payload 转换逻辑
+- 在发送请求前,自动移除 assistant 消息中的 `reasoning_content` 和 `reasoning` 字段
+- 仅影响 Groq 提供商,不影响其他提供商的行为
+
+**技术细节**:
+```python
+def _finally_convert_payload(self, payloads: dict) -> None:
+ """Groq rejects assistant history items that include reasoning_content."""
+ super()._finally_convert_payload(payloads)
+ for message in payloads.get("messages", []):
+ if message.get("role") == "assistant":
+ message.pop("reasoning_content", None)
+ message.pop("reasoning", None)
+```
+
+**影响范围**:
+- 使用 Groq 提供商时,assistant 历史消息中的推理内容会被自动过滤
+- 用户消息和其他字段不受影响
+- 确保 Groq API 请求成功,避免因 `reasoning_content` 字段导致的拒绝错误
+
+该修复提升了 Groq 提供商与推理模型(reasoning models)的互操作性,确保用户可以在不同提供商之间无缝切换。
+
+#### OpenAI 提供商代码质量优化
+
+[PR #6397](https://github.com/AstrBotDevs/AstrBot/pull/6397) 优化了 OpenAI 提供商的代码质量,采用更 Pythonic 的布尔值检查方式:
+
+**优化内容**:
+- 使用 `if not chunk.choices:` 替代 `if len(chunk.choices) == 0:`
+- 使用 `if delta and delta.content:` 替代显式的 `if delta.content:` 检查
+- 使用 `if not completion.choices:` 替代 `if len(completion.choices) == 0:`
+
+**代码改进示例**:
+```python
+# 修复前
+if len(chunk.choices) == 0:
+ continue
+
+# 修复后
+if not chunk.choices:
+ continue
+```
+
+**影响范围**:
+- `_query_stream()` 方法:流式查询逻辑
+- `_extract_reasoning_content()` 方法:推理内容提取
+- `_parse_openai_completion()` 方法:响应解析
+
+该优化遵循 Python 最佳实践,提升代码可读性和可维护性,但不改变功能行为。
+
+---
+
+### 16. 其他优化
- JWT 处理和错误处理机制增强,提升系统安全性和稳定性
- UI 细节优化,提升用户体验
- 日志与异常处理增强,便于问题追踪Note: You must be authenticated to accept/decline updates. |
There was a problem hiding this comment.
Pull request overview
This PR appears to be a “master → dev” sync that bundles several platform/provider fixes plus small dashboard/docs/config updates across the AstrBot framework.
Changes:
- Provider payload handling: preserve OpenAI
reasoning_contentwhile stripping it for Groq, with new tests. - Platform adapters: send Telegram GIFs as animations and add QQ Official webhook dedup + face-tag parsing.
- Misc updates: provider icon CDN switch, docs link fix, MiniMax provider template, Neo skill schema tightening, and a maintenance script for closing duplicate plugin-publish issues.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
astrbot/core/provider/sources/openai_source.py |
Minor safety tweaks around choices/delta handling. |
astrbot/core/provider/sources/groq_source.py |
Drop reasoning_content/reasoning from assistant history after payload conversion. |
tests/test_openai_source.py |
Adds tests covering OpenAI vs Groq assistant-history reasoning behavior. |
astrbot/core/platform/sources/telegram/tg_event.py |
Detect GIFs and send via send_animation (also adjusts chat actions). |
astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py |
Adds an in-memory event-id dedup cache for webhook retries. |
astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py |
Adds parsing for <faceType=...> tags into readable text. |
dashboard/src/utils/providerUtils.js |
Switches provider icon URLs from npmmirror to jsdelivr. |
docs/zh/what-is-astrbot.md |
Fixes the “连接模型服务” link path. |
astrbot/core/config/default.py |
Adds a MiniMax chat provider template entry. |
astrbot/core/computer/tools/neo_skills.py |
Tightens JSON schema for payload array items to objects. |
astrbot/core/astr_main_agent_resources.py |
Updates tool description text for send_message_to_user. |
scripts/close_duplicate_plugin_publish_issues.py |
New CLI script to close duplicate open issues by title (dry-run by default). |
You can also share your feedback on Copilot code review. Take the survey.
| now = time.monotonic() | ||
| # Lazily evict expired entries to prevent unbounded growth. | ||
| expired = [ | ||
| k | ||
| for k, ts in self._seen_event_ids.items() | ||
| if now - ts > self._dedup_ttl | ||
| ] | ||
| for k in expired: | ||
| del self._seen_event_ids[k] | ||
| if event_id in self._seen_event_ids: | ||
| logger.debug(f"Duplicate webhook event {event_id!r}, skipping.") | ||
| return {"opcode": 12} | ||
| self._seen_event_ids[event_id] = now | ||
|
|
| return f"[表情:{emoji_text}]" | ||
| except Exception: | ||
| pass | ||
| # Fallback if parsing fails |
| if path.lower().endswith(".gif"): | ||
| return True | ||
| try: | ||
| with open(path, "rb") as f: | ||
| return f.read(6) in (b"GIF87a", b"GIF89a") | ||
| except OSError: | ||
| return False |
| "Send message to the user. " | ||
| "Supports various message types including `plain`, `image`, `record`, `video`, `file`, and `mention_user`. " | ||
| "Use this tool to send media files (`image`, `record`, `video`, `file`), " | ||
| "or when you need to proactively message the user(such as cron job). For normal text replies, you can output directly." |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64e0183b55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "provider_type": "chat_completion", | ||
| "enable": True, | ||
| "key": [], | ||
| "api_base": "https://api.minimaxi.com/v1", |
There was a problem hiding this comment.
Fix MiniMax default API base domain typo
The new MiniMax provider preset sets api_base to https://api.minimaxi.com/v1, which has an extra i in the hostname; users who rely on this default will fail to connect (DNS/connection errors) until they manually override it. This looks unintended because the MiniMax TTS preset in the same config uses the api.minimax.chat domain, so the chat preset should use a valid MiniMax endpoint as well.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
|
@copilot 分析冲突严重程度 |
|
@LIghtJUNction I've opened a new pull request, #6398, to work on those changes. Once the pull request is ready, I'll request review from you. |
Duplicated checklist items in the pull request template for clarity and emphasis.
Refactor checklist items in PR template
Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com>
Updated the checklist validation script and modified the comment for PR closure.
…ions-summary feat: auto-close PRs when author checks "did not read" checklist item
…ues and generating changelog
Update session ID extraction to handle group and single chat types.
Fixes #6283 When adding a new embedding provider, the knowledge base creation page did not show the new provider until restart. Root cause: create_provider() did not update self.providers_config, which is used by get_provider_config_list() to return provider lists. This fix syncs the in-memory config after loading the new provider, consistent with how reload() handles config updates. Co-authored-by: ccsang <ccsang@users.noreply.github.com>
Added a note about using a backup address if the management panel cannot be accessed.
Modifications / 改动点
Screenshots or Test Results / 运行截图或测试结果
Checklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.Summary by Sourcery
Sync recent changes from master into dev, updating provider behavior, messaging adapters, configuration, and tooling.
New Features:
Bug Fixes:
Enhancements:
Tests:
Chores: