chore: bump version to 4.14.0

This commit is contained in:
Soulter
2026-02-03 22:08:29 +08:00
parent e42c1b6da8
commit 96e61a4a92
9 changed files with 341 additions and 6 deletions
+1 -1
View File
@@ -1 +1 @@
__version__ = "4.13.2"
__version__ = "4.14.0"
+1 -1
View File
@@ -5,7 +5,7 @@ from typing import Any, TypedDict
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
VERSION = "4.13.2"
VERSION = "4.14.0"
DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db")
WEBHOOK_SUPPORTED_PLATFORMS = [
+72
View File
@@ -0,0 +1,72 @@
## What's Changed - BIG AND BEAUTIFUL VERSION
> 如果在之前版本使用了 Skill,这次更新之后**需要重新配置** Skill Runtime 相关选项。
### 新增
- 🔥 新增未来任务系统(Future Tasks)。给 AstrBot 布置的未来任务,让 AstrBot 能够在某一时刻自动唤醒,帮你完成任务。详见 [主动任务](https://docs.astrbot.app/use/proactive-agent.html) 。(实验性) ([#4697](https://github.com/AstrBotDevs/AstrBot/issues/4831))
- 🔥 新增子代理(SubAgent)编排器。(实验性)([#4697](https://github.com/AstrBotDevs/AstrBot/issues/4831))
- 🔥 AstrBot 目前可以直接通过调用 tool 将图片 / 文件推送给用户,大大提高交互效果。
- 新增 Computer Use 运行时配置,以融合 Skill 和 Sandbox 配置 ([#4831](https://github.com/AstrBotDevs/AstrBot/issues/4831))
- 新增主题自定义功能,可设置主色与辅色
- 支持在配置页下人格对话框的编辑人格 ([#4826](https://github.com/AstrBotDevs/AstrBot/issues/4826))
- 支持开关 “追踪” 功能;支持在系统配置中设置是否将日志写入 log 文件 ([#4822](https://github.com/AstrBotDevs/AstrBot/issues/4822))
### 修复
- ‼️ 修复 ChatUI 图片、思考等显示异常问题。
- ‼️ 修复 Skill 上传到 Sandbox 后未自动解压导致 Agent 无法读取的问题。
- ‼️ 修复配置特定插件集时 MCP 工具被过滤的问题 ([#4825](https://github.com/AstrBotDevs/AstrBot/issues/4825))
- ‼️ 移除 ChatUI 自带的让 LLM 最后提出问题的 prompt ([#4824](https://github.com/AstrBotDevs/AstrBot/issues/4824))
- ‼️ 修复 WebUI 在上传 Skill 失败后仍显示成功消息的 bug ([#4768](https://github.com/AstrBotDevs/AstrBot/issues/4768))
- 修复 MCP 服务器无法重命名的问题 ([#4766](https://github.com/AstrBotDevs/AstrBot/issues/4766))
- 修复插件的 tool 无法在 WebUI 管理行为中看到来源的问题 ([#4776](https://github.com/AstrBotDevs/AstrBot/issues/4776))
- ‼️ 修复 skill-like 的 tool 模式下,调用 tool 失败的问题 ([#4775](https://github.com/AstrBotDevs/AstrBot/issues/4775))
### 优化
- WebUI 整体 UI 效果优化
- 部分 Dialog 标题样式统一
## What's Changed (EN)
### New Features
- Introduce CronJob system with one-time tasks and enhanced dashboard management
- Add theme customization with primary & secondary color options
- Add computer-use runtime config for skills sandbox execution ([#4831](https://github.com/AstrBotDevs/AstrBot/issues/4831))
- Add edit button to persona selector dialog ([#4826](https://github.com/AstrBotDevs/AstrBot/issues/4826))
- Add trace logging toggle and configuration UI ([#4822](https://github.com/AstrBotDevs/AstrBot/issues/4822))
- Add proactive-messaging capability with cron-tool trigger
- Implement SubAgent orchestrator with configurable tool-management policies
- Support resolving sandbox file paths and auto-download when necessary
- Add embedded image & audio styles in MessagePartsRenderer
- Introduce i18n foundation
- Persist agent-interaction history
- Add user notifications for file-download success/removal
### Bug Fixes
- Improve ghost-plugin detection accuracy
- Add error handling to prevent ghost-plugin crashes
- Prevent skills bundle from overwriting existing files
- Fix skills bundle unzip failure inside sandbox
- Fix MCP tools being filtered when specific plugin set configured ([#4825](https://github.com/AstrBotDevs/AstrBot/issues/4825))
- Merge ChatUI persona pop-up into default persona ([#4824](https://github.com/AstrBotDevs/AstrBot/issues/4824))
- Fix reasoning block style
- Add missing comma in truncate_and_compress hint
- Fix frontend still showing success message ([#4768](https://github.com/AstrBotDevs/AstrBot/issues/4768))
- Fix unable to rename MCP server ([#4766](https://github.com/AstrBotDevs/AstrBot/issues/4766))
- Remove leftover sandbox runtime handling in skill upload ([#4798](https://github.com/AstrBotDevs/AstrBot/issues/4798))
- Fix handler module path construction ([#4776](https://github.com/AstrBotDevs/AstrBot/issues/4776))
- Fix skill-like tool invocation error ([#4775](https://github.com/AstrBotDevs/AstrBot/issues/4775))
### Improvements
- Runtime hints & refined UI in skills management
- Performance and UX improvements on cron-job page
- General WebUI performance boost
- Group tools by plugin in dropdown
- Consistent dialog titles with padding and text styles
- Code formatting unified (ruff format)
- Bump version to 4.13.2
### Others
- Remove obsolete reminder code
- Extract main-agent module for better architecture
- Merge AstrBot_skill branch changes
@@ -22,6 +22,7 @@
"name": "Name",
"type": "Type",
"cron": "Cron",
"session": "Session ID",
"nextRun": "Next Run",
"lastRun": "Last Run",
"note": "Note",
@@ -22,6 +22,7 @@
"name": "名称",
"type": "类型",
"cron": "Cron",
"session": "会话 ID",
"nextRun": "下一次执行",
"lastRun": "最近执行",
"note": "说明",
@@ -35,8 +35,8 @@
"nameHint": "建议使用英文小写+下划线,且全局唯一",
"providerLabel": "Chat Provider(可选)",
"providerHint": "留空表示跟随全局默认 provider。",
"personaLabel": "选择 Persona",
"personaHint": "SubAgent 将直接继承所选 Persona 的系统设定与工具。",
"personaLabel": "选择人格设定",
"personaHint": "SubAgent 将直接继承所选 Persona 的系统设定与工具。在人格设定页管理和新建人格。",
"descriptionLabel": "对主 LLM 的描述(用于决定是否 handoff",
"descriptionHint": "这段会作为 transfer_to_* 工具的描述给主 LLM 看,建议简短明确。"
},
+9 -1
View File
@@ -48,6 +48,9 @@
<div class="text-caption text-medium-emphasis">{{ item.timezone || tm('table.timezoneLocal') }}</div>
</div>
</template>
<template #item.session="{ item }">
<div>{{ item.session || tm('table.notAvailable') }}</div>
</template>
<template #item.next_run_time="{ item }">{{ formatTime(item.next_run_time) }}</template>
<template #item.last_run_at="{ item }">{{ formatTime(item.last_run_at) }}</template>
<template #item.note="{ item }">{{ item.note || tm('table.notAvailable') }}</template>
@@ -129,6 +132,7 @@ const headers = computed(() => [
{ title: tm('table.headers.name'), key: 'name', minWidth: '200px' },
{ title: tm('table.headers.type'), key: 'type', width: 110 },
{ title: tm('table.headers.cron'), key: 'cron_expression', minWidth: '160px' },
{ title: tm('table.headers.session'), key: 'session', minWidth: '200px' },
{ title: tm('table.headers.nextRun'), key: 'next_run_time', minWidth: '160px' },
{ title: tm('table.headers.lastRun'), key: 'last_run_at', minWidth: '160px' },
{ title: tm('table.headers.note'), key: 'note', minWidth: '220px' },
@@ -163,7 +167,11 @@ async function loadJobs() {
try {
const res = await axios.get('/api/cron/jobs')
if (res.data.status === 'ok') {
jobs.value = Array.isArray(res.data.data) ? res.data.data : []
const data = Array.isArray(res.data.data) ? res.data.data : []
jobs.value = data.map((job: any) => ({
...job,
session: job?.payload?.session || job?.session || ''
}))
} else {
toast(res.data.message || tm('messages.loadFailed'), 'error')
}
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "AstrBot"
version = "4.13.2"
version = "4.14.0"
description = "Easy-to-use multi-platform LLM chatbot and development framework"
readme = "README.md"
requires-python = ">=3.10"
+253
View File
@@ -0,0 +1,253 @@
#!/usr/bin/env python3
"""
Auto-generate changelog from git commits using LLM.
Usage: python scripts/generate_changelog.py [--version VERSION]
"""
import argparse
import os
import re
import subprocess
import sys
from pathlib import Path
def get_latest_tag():
"""Get the latest git tag."""
result = subprocess.run(
["git", "describe", "--tags", "--abbrev=0"],
capture_output=True,
text=True,
check=True,
)
return result.stdout.strip()
def get_commits_since_tag(tag):
"""Get all commit messages since the specified tag."""
result = subprocess.run(
["git", "log", f"{tag}..HEAD", "--pretty=format:%H|%s|%b"],
capture_output=True,
text=True,
check=True,
)
commits = []
for line in result.stdout.strip().split("\n"):
if not line:
continue
parts = line.split("|", 2)
if len(parts) >= 2:
commit_hash = parts[0]
subject = parts[1]
body = parts[2] if len(parts) > 2 else ""
commits.append({"hash": commit_hash[:7], "subject": subject, "body": body})
return commits
def extract_issue_number(text):
"""Extract issue number from commit message."""
# Match #1234 or (#1234)
match = re.search(r"#(\d+)", text)
return match.group(1) if match else None
def call_llm_for_changelog(commits, version):
"""Call LLM to generate changelog from commits."""
try:
# Try to use OpenAI API or other LLM providers
import openai
# Build prompt
commits_text = "\n".join([f"- {c['subject']}" for c in commits])
prompt = f"""Based on the following git commit messages, generate a changelog document in BOTH Chinese and English.
Commit messages:
{commits_text}
Please organize the changes into these categories:
- 新增 (New Features)
- 修复 (Bug Fixes)
- 优化 (Improvements)
- 其他 (Others)
Format requirements:
1. Start with Chinese version under "## What's Changed"
2. Follow with English version under "## What's Changed (EN)"
3. Use markdown format with proper bullet points
4. Keep descriptions concise and user-friendly
5. If a commit mentions an issue number (#1234), include it in the format ([#1234](https://github.com/AstrBotDevs/AstrBot/issues/1234))
Example format:
## What's Changed
### 新增
- 支持某某功能 ([#1234](https://github.com/AstrBotDevs/AstrBot/issues/1234))
### 修复
- 修复某某问题
## What's Changed (EN)
### New Features
- Add support for something ([#1234](https://github.com/AstrBotDevs/AstrBot/issues/1234))
### Bug Fixes
- Fix something
"""
client = openai.OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1"),
)
response = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-4"),
messages=[
{
"role": "system",
"content": "You are a helpful assistant that generates well-structured changelogs.",
},
{"role": "user", "content": prompt},
],
temperature=0.3,
)
return response.choices[0].message.content
except ImportError:
print(
"Warning: openai package not installed. Install it with: pip install openai"
)
return generate_simple_changelog(commits)
except Exception as e:
print(f"Warning: Failed to call LLM API: {e}")
print("Falling back to simple changelog generation...")
return generate_simple_changelog(commits)
def generate_simple_changelog(commits):
"""Generate a simple changelog without LLM."""
sections = {
"feat": ("新增", "New Features", []),
"fix": ("修复", "Bug Fixes", []),
"perf": ("优化", "Improvements", []),
"docs": ("文档", "Documentation", []),
"refactor": ("重构", "Refactoring", []),
"test": ("测试", "Tests", []),
"chore": ("其他", "Chore", []),
"other": ("其他", "Others", []),
}
# Categorize commits by conventional commit type
for commit in commits:
subject = commit["subject"]
issue_num = extract_issue_number(subject)
issue_link = (
f" ([#{issue_num}](https://github.com/AstrBotDevs/AstrBot/issues/{issue_num}))"
if issue_num
else ""
)
# Detect conventional commit type
matched = False
for prefix in ["feat", "fix", "perf", "docs", "refactor", "test", "chore"]:
if subject.lower().startswith(f"{prefix}:") or subject.lower().startswith(
f"{prefix}("
):
# Remove prefix for display
clean_subject = re.sub(
r"^[a-z]+(\([^)]+\))?:\s*", "", subject, flags=re.IGNORECASE
)
sections[prefix][2].append(f"- {clean_subject}{issue_link}")
matched = True
break
if not matched:
sections["other"][2].append(f"- {subject}{issue_link}")
# Build Chinese version
changelog_zh = "## What's Changed\n\n"
for section_key in ["feat", "fix", "perf", "docs", "refactor", "test", "other"]:
zh_title, _, items = sections[section_key]
if items:
changelog_zh += f"### {zh_title}\n\n"
changelog_zh += "\n".join(items) + "\n\n"
# Build English version
changelog_en = "## What's Changed (EN)\n\n"
for section_key in ["feat", "fix", "perf", "docs", "refactor", "test", "other"]:
_, en_title, items = sections[section_key]
if items:
changelog_en += f"### {en_title}\n\n"
changelog_en += "\n".join(items) + "\n\n"
return changelog_zh + changelog_en
def main():
parser = argparse.ArgumentParser(description="Generate changelog from git commits")
parser.add_argument(
"--version", help="Version number for the changelog (e.g., v4.13.3)"
)
parser.add_argument(
"--use-llm",
action="store_true",
help="Use LLM to generate changelog (requires OpenAI API key)",
)
args = parser.parse_args()
# Get latest tag
try:
latest_tag = get_latest_tag()
print(f"Latest tag: {latest_tag}")
except subprocess.CalledProcessError:
print("Error: No tags found in repository")
sys.exit(1)
# Get commits since tag
commits = get_commits_since_tag(latest_tag)
if not commits:
print(f"No commits found since {latest_tag}")
sys.exit(0)
print(f"Found {len(commits)} commits since {latest_tag}")
# Determine version
if args.version:
version = args.version
else:
# Auto-increment patch version
match = re.match(r"v(\d+)\.(\d+)\.(\d+)", latest_tag)
if match:
major, minor, patch = map(int, match.groups())
version = f"v{major}.{minor}.{patch + 1}"
else:
print(f"Warning: Could not parse version from tag {latest_tag}")
version = "vX.X.X"
print(f"Generating changelog for {version}...")
# Generate changelog
if args.use_llm:
changelog_content = call_llm_for_changelog(commits, version)
else:
changelog_content = generate_simple_changelog(commits)
# Save to file
changelog_dir = Path(__file__).parent.parent / "changelogs"
changelog_dir.mkdir(exist_ok=True)
changelog_file = changelog_dir / f"{version}.md"
with open(changelog_file, "w", encoding="utf-8") as f:
f.write(changelog_content)
print(f"\n✓ Changelog generated: {changelog_file}")
print("\nPreview:")
print("=" * 80)
print(changelog_content)
print("=" * 80)
if __name__ == "__main__":
main()