Compare commits
3 Commits
feat/file-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9be8cf69f | ||
|
|
31d53edb9d | ||
|
|
2ba0460f19 |
@@ -1 +1 @@
|
|||||||
__version__ = "4.7.3"
|
__version__ = "4.7.4"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import os
|
|||||||
|
|
||||||
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
||||||
|
|
||||||
VERSION = "4.7.3"
|
VERSION = "4.7.4"
|
||||||
DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db")
|
DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db")
|
||||||
|
|
||||||
# 默认配置
|
# 默认配置
|
||||||
@@ -2422,36 +2422,36 @@ CONFIG_METADATA_3 = {
|
|||||||
"provider_settings.enable": True,
|
"provider_settings.enable": True,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"file_extract": {
|
# "file_extract": {
|
||||||
"description": "文档解析能力",
|
# "description": "文档解析能力 [beta]",
|
||||||
"type": "object",
|
# "type": "object",
|
||||||
"items": {
|
# "items": {
|
||||||
"provider_settings.file_extract.enable": {
|
# "provider_settings.file_extract.enable": {
|
||||||
"description": "启用文档解析能力",
|
# "description": "启用文档解析能力",
|
||||||
"type": "bool",
|
# "type": "bool",
|
||||||
},
|
# },
|
||||||
"provider_settings.file_extract.provider": {
|
# "provider_settings.file_extract.provider": {
|
||||||
"description": "文档解析提供商",
|
# "description": "文档解析提供商",
|
||||||
"type": "string",
|
# "type": "string",
|
||||||
"options": ["moonshotai"],
|
# "options": ["moonshotai"],
|
||||||
"condition": {
|
# "condition": {
|
||||||
"provider_settings.file_extract.enable": True,
|
# "provider_settings.file_extract.enable": True,
|
||||||
},
|
# },
|
||||||
},
|
# },
|
||||||
"provider_settings.file_extract.moonshotai_api_key": {
|
# "provider_settings.file_extract.moonshotai_api_key": {
|
||||||
"description": "Moonshot AI API Key",
|
# "description": "Moonshot AI API Key",
|
||||||
"type": "string",
|
# "type": "string",
|
||||||
"condition": {
|
# "condition": {
|
||||||
"provider_settings.file_extract.provider": "moonshotai",
|
# "provider_settings.file_extract.provider": "moonshotai",
|
||||||
"provider_settings.file_extract.enable": True,
|
# "provider_settings.file_extract.enable": True,
|
||||||
},
|
# },
|
||||||
},
|
# },
|
||||||
},
|
# },
|
||||||
"condition": {
|
# "condition": {
|
||||||
"provider_settings.agent_runner_type": "local",
|
# "provider_settings.agent_runner_type": "local",
|
||||||
"provider_settings.enable": True,
|
# "provider_settings.enable": True,
|
||||||
},
|
# },
|
||||||
},
|
# },
|
||||||
"others": {
|
"others": {
|
||||||
"description": "其他配置",
|
"description": "其他配置",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ class AbstractProvider(abc.ABC):
|
|||||||
)
|
)
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
async def test(self) -> bool:
|
async def test(self):
|
||||||
"""test the provider is a
|
"""test the provider is a
|
||||||
|
|
||||||
Returns:
|
raises:
|
||||||
bool: the provider is available
|
Exception: if the provider is not available
|
||||||
"""
|
"""
|
||||||
return True
|
...
|
||||||
|
|
||||||
|
|
||||||
class Provider(AbstractProvider):
|
class Provider(AbstractProvider):
|
||||||
@@ -175,15 +175,11 @@ class Provider(AbstractProvider):
|
|||||||
|
|
||||||
return dicts
|
return dicts
|
||||||
|
|
||||||
async def test(self, timeout: float = 45.0) -> bool:
|
async def test(self, timeout: float = 45.0):
|
||||||
try:
|
await asyncio.wait_for(
|
||||||
response = await asyncio.wait_for(
|
self.text_chat(prompt="REPLY `PONG` ONLY"),
|
||||||
self.text_chat(prompt="REPLY `PONG` ONLY"),
|
timeout=timeout,
|
||||||
timeout=timeout,
|
)
|
||||||
)
|
|
||||||
return response is not None
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class STTProvider(AbstractProvider):
|
class STTProvider(AbstractProvider):
|
||||||
@@ -197,19 +193,13 @@ class STTProvider(AbstractProvider):
|
|||||||
"""获取音频的文本"""
|
"""获取音频的文本"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
async def test(self) -> bool:
|
async def test(self):
|
||||||
try:
|
sample_audio_path = os.path.join(
|
||||||
sample_audio_path = os.path.join(
|
get_astrbot_path(),
|
||||||
get_astrbot_path(),
|
"samples",
|
||||||
"samples",
|
"stt_health_check.wav",
|
||||||
"stt_health_check.wav",
|
)
|
||||||
)
|
await self.get_text(sample_audio_path)
|
||||||
if not os.path.exists(sample_audio_path):
|
|
||||||
return False
|
|
||||||
text_result = await self.get_text(sample_audio_path)
|
|
||||||
return isinstance(text_result, str) and bool(text_result)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class TTSProvider(AbstractProvider):
|
class TTSProvider(AbstractProvider):
|
||||||
@@ -223,12 +213,8 @@ class TTSProvider(AbstractProvider):
|
|||||||
"""获取文本的音频,返回音频文件路径"""
|
"""获取文本的音频,返回音频文件路径"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
async def test(self) -> bool:
|
async def test(self):
|
||||||
try:
|
await self.get_audio("hi")
|
||||||
audio_result = await self.get_audio("hi")
|
|
||||||
return isinstance(audio_result, str) and bool(audio_result)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class EmbeddingProvider(AbstractProvider):
|
class EmbeddingProvider(AbstractProvider):
|
||||||
@@ -252,14 +238,8 @@ class EmbeddingProvider(AbstractProvider):
|
|||||||
"""获取向量的维度"""
|
"""获取向量的维度"""
|
||||||
...
|
...
|
||||||
|
|
||||||
async def test(self) -> bool:
|
async def test(self):
|
||||||
try:
|
await self.get_embedding("astrbot")
|
||||||
embedding_result = await self.get_embedding("health_check")
|
|
||||||
return isinstance(embedding_result, list) and (
|
|
||||||
not embedding_result or isinstance(embedding_result[0], float)
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_embeddings_batch(
|
async def get_embeddings_batch(
|
||||||
self,
|
self,
|
||||||
@@ -345,9 +325,7 @@ class RerankProvider(AbstractProvider):
|
|||||||
"""获取查询和文档的重排序分数"""
|
"""获取查询和文档的重排序分数"""
|
||||||
...
|
...
|
||||||
|
|
||||||
async def test(self) -> bool:
|
async def test(self):
|
||||||
try:
|
result = await self.rerank("Apple", documents=["apple", "banana"])
|
||||||
await self.rerank("Apple", documents=["apple", "banana"])
|
if not result:
|
||||||
return True
|
raise Exception("Rerank provider test failed, no results returned")
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|||||||
@@ -354,17 +354,11 @@ class ConfigRoute(Route):
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = await provider.test()
|
await provider.test()
|
||||||
if result:
|
status_info["status"] = "available"
|
||||||
status_info["status"] = "available"
|
logger.info(
|
||||||
logger.info(
|
f"Provider {status_info['name']} (ID: {status_info['id']}) is available.",
|
||||||
f"Provider {status_info['name']} (ID: {status_info['id']}) is available.",
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
status_info["error"] = "Provider test returned False."
|
|
||||||
logger.warning(
|
|
||||||
f"Provider {status_info['name']} (ID: {status_info['id']}) test returned False.",
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = str(e)
|
error_message = str(e)
|
||||||
status_info["error"] = error_message
|
status_info["error"] = error_message
|
||||||
|
|||||||
7
changelogs/v4.7.4.md
Normal file
7
changelogs/v4.7.4.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## What's Changed
|
||||||
|
|
||||||
|
1. 修复:assistant message 中 tool_call 存在但 content 不存在时,导致验证错误的问题 ([#3862](https://github.com/AstrBotDevs/AstrBot/issues/3862))
|
||||||
|
2. 修复:fix: aiocqhttp 适配器 NapCat 文件名获取为空 ([#3853](https://github.com/AstrBotDevs/AstrBot/issues/3853))
|
||||||
|
3. 新增:升级所有插件按钮
|
||||||
|
4. 新增:/provider 指令支持同时测试提供商可用性
|
||||||
|
5. 优化:主动回复的 prompt
|
||||||
@@ -34,25 +34,11 @@ class ProviderCommands:
|
|||||||
provider_capability_type = meta.provider_type
|
provider_capability_type = meta.provider_type
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = await provider.test()
|
await provider.test()
|
||||||
if result:
|
return True, None, None
|
||||||
return True, None, None
|
except Exception as e:
|
||||||
err_code = "TEST_FAILED"
|
err_code = "TEST_FAILED"
|
||||||
err_reason = "Provider test returned False"
|
err_reason = str(e)
|
||||||
self._log_reachability_failure(
|
|
||||||
provider, provider_capability_type, err_code, err_reason
|
|
||||||
)
|
|
||||||
return False, err_code, err_reason
|
|
||||||
except Exception as exc:
|
|
||||||
err_code = (
|
|
||||||
getattr(exc, "status_code", None)
|
|
||||||
or getattr(exc, "code", None)
|
|
||||||
or getattr(exc, "error_code", None)
|
|
||||||
)
|
|
||||||
err_reason = str(exc)
|
|
||||||
if not err_code:
|
|
||||||
err_code = exc.__class__.__name__
|
|
||||||
|
|
||||||
self._log_reachability_failure(
|
self._log_reachability_failure(
|
||||||
provider, provider_capability_type, err_code, err_reason
|
provider, provider_capability_type, err_code, err_reason
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "AstrBot"
|
name = "AstrBot"
|
||||||
version = "4.7.3"
|
version = "4.7.4"
|
||||||
description = "Easy-to-use multi-platform LLM chatbot and development framework"
|
description = "Easy-to-use multi-platform LLM chatbot and development framework"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
|
|||||||
Reference in New Issue
Block a user