chore(release): 发布 0.7.0 正式版

- 版本号 0.7.0.beta3 → 0.7.0(pyproject ×2 / package.json / docker-compose ×2 / uv.lock ×2 / README ×2 / quick-start / 文档首页)
- changelog 标题更新为 v0.7.0 (2026-06-13),修正版本号描述
- quick-start 版本表更新为当前稳定版
- 修复 package import 排序,同步前端 prettier 格式化
This commit is contained in:
Wenjie Zhang 2026-06-13 01:02:43 +08:00
parent 7f454e64e6
commit a8a933d3dc
21 changed files with 63 additions and 43 deletions

View File

@ -54,7 +54,7 @@ Navigation: [Introduction](https://xerrors.github.io/Yuxi/) [Quick Start](ht
**1. Clone and initialize**
```bash
git clone --branch v0.7.0.beta3 --depth 1 https://github.com/xerrors/Yuxi.git
git clone --branch v0.7.0 --depth 1 https://github.com/xerrors/Yuxi.git
cd Yuxi
# Linux/macOS

View File

@ -43,7 +43,7 @@
**1. 克隆代码并初始化**
```bash
git clone --branch v0.7.0.beta3 --depth 1 https://github.com/xerrors/Yuxi.git
git clone --branch v0.7.0 --depth 1 https://github.com/xerrors/Yuxi.git
cd Yuxi
# Linux/macOS

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "yuxi"
version = "0.7.0.beta3"
version = "0.7.0"
description = "Yuxi 智能知识库与知识图谱平台核心后端包"
readme = "README.md"
requires-python = ">=3.12,<3.14"

View File

@ -5264,7 +5264,7 @@ wheels = [
[[package]]
name = "yuxi"
version = "0.7.0.beta3"
version = "0.7.0"
source = { editable = "." }
dependencies = [
{ name = "agent-sandbox" },

View File

@ -6,7 +6,6 @@ from yuxi.models.providers.cache import model_cache
from yuxi.utils import get_docker_safe_url
from yuxi.utils.logging_config import logger
# 这些提供商的 OpenAI 兼容流式接口,在 LangGraph v3 事件流累积工具调用时会丢失
# tool_call 的关键字段siliconflow MiniMax 丢 name、alibaba 百炼丢 id空值会被写入
# checkpoint导致工具结果无法按 tool_call_id 关联、工具状态永远停留在“进行中”。

View File

@ -1,6 +1,6 @@
[project]
name = "yuxi-workspace"
version = "0.7.0.beta3"
version = "0.7.0"
description = "基于大模型的智能知识库与知识图谱智能体开发平台,融合了 RAG 技术与知识图谱技术,基于 LangGraph v1 + Vue.js + FastAPI + LightRAG 架构构建"
readme = "README.md"
requires-python = ">=3.12,<3.14"

View File

@ -5489,7 +5489,7 @@ wheels = [
[[package]]
name = "yuxi"
version = "0.7.0.beta3"
version = "0.7.0"
source = { editable = "package" }
dependencies = [
{ name = "agent-sandbox" },
@ -5646,7 +5646,7 @@ requires-dist = [
[[package]]
name = "yuxi-workspace"
version = "0.7.0.beta3"
version = "0.7.0"
source = { virtual = "." }
dependencies = [
{ name = "arq" },

View File

@ -30,7 +30,7 @@ services:
build:
context: .
dockerfile: docker/api.Dockerfile
image: yuxi-api:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-api:${YUXI_VERSION:-0.7.0}
container_name: api-prod
working_dir: /app
networks:
@ -68,7 +68,7 @@ services:
build:
context: .
dockerfile: docker/api.Dockerfile
image: yuxi-api:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-api:${YUXI_VERSION:-0.7.0}
container_name: worker-prod
working_dir: /app
networks:
@ -145,7 +145,7 @@ services:
context: .
dockerfile: docker/web.Dockerfile
target: production
image: yuxi-web:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-web:${YUXI_VERSION:-0.7.0}
container_name: web-prod
ports:
- "80:80"

View File

@ -38,7 +38,7 @@ services:
build:
context: .
dockerfile: docker/api.Dockerfile
image: yuxi-api:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-api:${YUXI_VERSION:-0.7.0}
container_name: api-dev
working_dir: /app
volumes:
@ -86,7 +86,7 @@ services:
build:
context: .
dockerfile: docker/api.Dockerfile
image: yuxi-api:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-api:${YUXI_VERSION:-0.7.0}
container_name: worker-dev
working_dir: /app
volumes:
@ -125,7 +125,7 @@ services:
build:
context: ./docker/sandbox_provisioner
dockerfile: Dockerfile
image: yuxi-sandbox-provisioner:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-sandbox-provisioner:${YUXI_VERSION:-0.7.0}
container_name: sandbox-provisioner
volumes:
- ./docker/volumes/yuxi:/app/saves
@ -179,7 +179,7 @@ services:
context: .
dockerfile: docker/web.Dockerfile
target: development
image: yuxi-web:${YUXI_VERSION:-0.7.0.beta3}
image: yuxi-web:${YUXI_VERSION:-0.7.0}
container_name: web-dev
volumes:
- ./web/src:/app/src

View File

@ -453,7 +453,7 @@ const vReveal = {
</header>
<div v-reveal class="yx-quick">
<pre class="yx-code"><code><span class="yx-c-cmt"># 1. 克隆并初始化</span>
git clone --branch v0.7.0.beta3 --depth 1 https://github.com/xerrors/Yuxi.git
git clone --branch v0.7.0 --depth 1 https://github.com/xerrors/Yuxi.git
cd Yuxi && ./scripts/init.sh
<span class="yx-c-cmt"># 2. 使用 Docker 启动</span>

View File

@ -4,7 +4,7 @@
同一版本的多次功能更新时,应以功能为单位进行更新,比如之前添加了 A 功能的更新,在后续的更新中修复了因 A 功能引入的 bug那么这个修复说明应该和 A 功能描述放在一起,而不是新增一条修复记录,功能更新同理。
## v0.7.0 (开发中)
## v0.7.0 (2026-06-13)
### 破坏性变更
@ -18,7 +18,7 @@
### 开发记录
- 发布版本号更新至 `0.7.0.beta2`,同步 package、Docker 镜像标签与快速开始分支引用。
- 发布版本号更新至 `0.7.0`,同步 package、Docker 镜像标签与快速开始分支引用。
- 新增内置「深度研究」多智能体:编排器 Agent`deep-research`ChatbotAgent 后端)负责澄清、拆解、并行调度子智能体与综合成稿,配套两个子智能体 `research-explorer`(围绕单个子问题多轮检索网页/知识库并返回带引用发现)和 `fact-verifier`(对抗式核验关键论断、标注冲突与置信度);完整研究方法论沉淀为新增内置 Skill `deep-research`(依赖 `tavily_search`),编排器运行时读取并据此调度。三者随 `lifespan` 启动通过 `AgentRepository.ensure_deep_research_agents` 幂等落库(已存在不覆盖管理员修改)。
- 新增内置 `general-purpose` 通用任务子智能体:使用 `SubAgentBackend` 与空运行配置,作为 `task` 工具的通用委派目标,由启动初始化自动写入数据库。
- 收敛 MCP 创建与编辑入口:前端移除整段配置文本入口和模式切换器,仅保留表单字段提交;后端 MCP 创建/更新请求拒绝额外配置字段,避免绕过表单约束。

View File

@ -20,7 +20,7 @@
```bash
# 克隆最新版本
git clone --branch v0.7.0.beta3 --depth 1 https://github.com/xerrors/Yuxi.git
git clone --branch v0.7.0 --depth 1 https://github.com/xerrors/Yuxi.git
cd Yuxi
```
@ -28,7 +28,7 @@ cd Yuxi
| 版本 | 适用场景 |
|------|----------|
| v0.7.x | 当前开发版本,包含最新特性 |
| v0.7.0 | 当前稳定版本,推荐生产使用 |
| main | 开发版本,包含最新特性(可能不稳定) |
### 步骤二:配置环境变量

View File

@ -1,6 +1,6 @@
{
"name": "yuxi-web",
"version": "0.7.0.beta3",
"version": "0.7.0",
"private": true,
"type": "module",
"scripts": {

View File

@ -1285,7 +1285,8 @@ const historyConversations = computed(() => {
function getMessageRequestId(message) {
const metadataRequestId = message?.extra_metadata?.request_id
if (typeof metadataRequestId === 'string' && metadataRequestId.trim()) return metadataRequestId.trim()
if (typeof metadataRequestId === 'string' && metadataRequestId.trim())
return metadataRequestId.trim()
if (message?.type === 'human' && typeof message.id === 'string' && message.id.trim()) {
return message.id.trim()
}
@ -1341,10 +1342,8 @@ function mergeOngoingUserMessageIntoHistory(historyConvs, ongoingMessages) {
const conversations = computed(() => {
const historyConvs = historyConversations.value
const {
historyConvs: mergedHistoryConvs,
ongoingMessages: mergedOngoingMessages
} = mergeOngoingUserMessageIntoHistory(historyConvs, onGoingConvMessages.value)
const { historyConvs: mergedHistoryConvs, ongoingMessages: mergedOngoingMessages } =
mergeOngoingUserMessageIntoHistory(historyConvs, onGoingConvMessages.value)
// 线
if (mergedOngoingMessages.length > 0) {

View File

@ -1,9 +1,9 @@
<template>
<div
v-if="message.type === 'human' && message.image_content"
class="message-image"
>
<img :src="`data:${messageImageMimeType};base64,${message.image_content}`" alt="用户上传的图片" />
<div v-if="message.type === 'human' && message.image_content" class="message-image">
<img
:src="`data:${messageImageMimeType};base64,${message.image_content}`"
alt="用户上传的图片"
/>
</div>
<div
class="message-box"

View File

@ -82,7 +82,9 @@ const avatarSizeStyle = computed(() => {
}
})
const resolvedAlt = computed(() => props.alt || props.name || (props.kind === 'agent' ? '智能体头像' : '用户头像'))
const resolvedAlt = computed(
() => props.alt || props.name || (props.kind === 'agent' ? '智能体头像' : '用户头像')
)
const handleImageError = () => {
if (failedImageCount.value < imageCandidates.value.length) {

View File

@ -221,7 +221,8 @@ const loadFeedbacks = async () => {
}
}
const getFeedbackDefaultAvatarSrc = (feedback) => (feedback.uid ? generatePixelAvatar(feedback.uid) : '')
const getFeedbackDefaultAvatarSrc = (feedback) =>
feedback.uid ? generatePixelAvatar(feedback.uid) : ''
//
const formatFullDate = (dateString) => formatFullDateTime(dateString)

View File

@ -59,7 +59,11 @@ const run = () => {
}
{
assert.equal(getAvatarInitials('张三丰', 'user'), '张三', 'Chinese initials use first two chars')
assert.equal(
getAvatarInitials('张三丰', 'user'),
'张三',
'Chinese initials use first two chars'
)
assert.equal(getAvatarInitials('Alice', 'user'), 'Al', 'ASCII initials use first two chars')
assert.equal(getAvatarInitials('', 'user'), '用户', 'User fallback should be localized')
assert.equal(getAvatarInitials('', 'agent'), '智能', 'Agent fallback should be localized')

View File

@ -6,7 +6,13 @@ const AUTO_START_KEY = 'oidc_auto_start_attempted'
// - 不能以 // 或 \ 开头(协议相对 URL / 非标准路径)
// 不合法或缺失时返回 "/"
export function sanitizeRedirect(value) {
if (typeof value === 'string' && value.length > 0 && value[0] === '/' && value[1] !== '/' && value[1] !== '\\') {
if (
typeof value === 'string' &&
value.length > 0 &&
value[0] === '/' &&
value[1] !== '/' &&
value[1] !== '\\'
) {
return value
}
return '/'

View File

@ -2,10 +2,22 @@ const DICEBEAR_GLYPHS_AVATAR_BASE_URL = 'https://api.dicebear.com/10.x/glyphs/sv
export const AVATAR_BACKGROUND_TOKENS = [
{ background: 'linear-gradient(135deg, var(--main-600), var(--color-info-500))', color: '#fff' },
{ background: 'linear-gradient(135deg, var(--chart-palette-5), var(--chart-palette-9))', color: '#fff' },
{ background: 'linear-gradient(135deg, var(--chart-palette-7), var(--chart-palette-3))', color: '#fff' },
{ background: 'linear-gradient(135deg, var(--color-accent-500), var(--chart-palette-6))', color: '#fff' },
{ background: 'linear-gradient(135deg, var(--chart-palette-4), var(--color-error-500))', color: '#fff' }
{
background: 'linear-gradient(135deg, var(--chart-palette-5), var(--chart-palette-9))',
color: '#fff'
},
{
background: 'linear-gradient(135deg, var(--chart-palette-7), var(--chart-palette-3))',
color: '#fff'
},
{
background: 'linear-gradient(135deg, var(--color-accent-500), var(--chart-palette-6))',
color: '#fff'
},
{
background: 'linear-gradient(135deg, var(--chart-palette-4), var(--color-error-500))',
color: '#fff'
}
]
const normalizeSeed = (id) => {

View File

@ -642,10 +642,7 @@ onMounted(async () => {
// OIDC OIDC
const config = await checkOIDCConfig()
if (config && config.enabled) {
const autoStarted = await tryAutoStartOIDC(
async () => await authApi.getOIDCLoginUrl(),
config
)
const autoStarted = await tryAutoStartOIDC(async () => await authApi.getOIDCLoginUrl(), config)
// OIDC
if (autoStarted) return
}