Skip to content

Conversation

@Mile-Away
Copy link
Contributor

@Mile-Away Mile-Away commented Jan 21, 2026

…etrieval

变更内容

  • 新功能
  • 修复 Bug
  • 增强重构
  • 其他(请描述)

简要描述本次 PR 的主要变更内容。

相关 Issue

请关联相关 Issue(如有):#编号

检查清单

默认已勾选,如不满足,请检查。

  • 已在本地测试通过
  • 已补充/更新相关文档
  • 已添加测试用例
  • 代码风格已经过 pre-commit 钩子检查

其他说明

如有特殊说明或注意事项,请补充。

Summary by Sourcery

在前端和后端引入基于 semantic-release 的自动化版本管理系统,通过 API 暴露后端版本元数据,在设置界面中新增 “关于(About)” 区域展示版本信息,并将版本信息接入构建和部署流水线。

New Features:

  • 新增后端 /api/v1/system/version 接口,由一个集中式的版本信息模块提供支持,该模块读取版本号、提交记录和构建时间。
  • 通过 Vite 注入前端构建版本号、提交记录和构建时间戳,并通过新的版本类型定义模块和 hook 对外暴露。
  • 新增 “关于(About)” 设置页面,用于展示前端/后端版本信息、它们的一致性状态,以及快捷项目链接。

Enhancements:

  • 更新后端路由,将业务接口进行分组,并注册新的 system 路由器。
  • 将 Docker 镜像与 Kubernetes 部署接入构建元数据,通过环境变量注入。
  • 在 monorepo 根目录引入 semantic-release 配置,集成 commitlint、commitizen 和版本同步脚本,使 web 与 service 版本保持一致。
  • 新增 GitHub Actions 发布工作流,用于自动化版本管理、变更日志生成、镜像构建、部署和通知。
  • 在 web 包中启用发布脚本,并引入 bumpp,以便在需要时手动提升版本号。

Build:

  • 在 web 的 Vite 配置中暴露构建时版本常量,并为其声明 TypeScript 类型。
  • 在后端服务镜像中新增 Docker 构建参数和环境变量,用于传递提交 SHA 和构建时间。

CI:

  • 扩展 pre-commit 配置,加入用于规范提交信息的 commitlint hook,并新增 GitHub Actions 发布工作流,用于自动化 semantic-release 和部署。

Documentation:

  • 在新文件 VERSION_MANAGEMENT.md 中记录版本管理与发布流程,包括提交规范、CI/CD,以及故障排查。

Chores:

  • 初始化根目录的 package.json、变更日志、Yarn 配置和发布配置,以支持新的版本管理流程。
Original summary in English

Summary by Sourcery

Introduce an automated semantic-release-based version management system across frontend and backend, expose backend version metadata via API, surface version information in a new About section in the settings UI, and wire versions into build and deployment pipelines.

New Features:

  • Add backend /api/v1/system/version endpoint backed by a centralized version info module that reads version, commit, and build time.
  • Inject frontend build version, commit, and build timestamp via Vite and expose them through a new version types module and hook.
  • Add an About settings page that displays frontend/backend versions, their consistency status, and quick project links.

Enhancements:

  • Update backend routing to group business endpoints and register the new system router.
  • Wire Docker images and Kubernetes deployments to include build metadata via environment variables.
  • Introduce a monorepo-level semantic-release setup with commitlint, commitizen, and version sync script to keep web and service versions aligned.
  • Add a GitHub Actions release workflow to automate versioning, changelog generation, image builds, deployments, and notifications.
  • Enable a release script in the web package and add bumpp for manual version bumping when needed.

Build:

  • Expose build-time version constants in the web Vite config and declare their types for TypeScript.
  • Add Docker build arguments and environment variables for commit SHA and build time in the backend service image.

CI:

  • Extend pre-commit configuration with commitlint hook for conventional commits and add a GitHub Actions release workflow for automated semantic releases and deployments.

Documentation:

  • Document the version management and release workflow in a new VERSION_MANAGEMENT.md, including commit conventions, CI/CD, and troubleshooting.

Chores:

  • Initialize root-level package.json, changelog, Yarn config, and release configuration to support the new versioning workflow.

Copilot AI review requested due to automatic review settings January 21, 2026 06:32
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 21, 2026

Reviewer's Guide

在前端和后端实现完整的版本管理系统(基于 semantic-release),通过新 API 暴露后端版本元数据,在 Web 应用的新「关于」设置页中展示版本状态,并将 CI/CD、Docker 和 pre-commit hooks 接入以强制执行提交规范,并在端到端流程中传递版本/构建信息。

前后端版本获取流程的时序图

sequenceDiagram
  actor User
  participant Browser as Browser_UI
  participant Frontend as Frontend_useVersion
  participant Backend as Backend_API_system
  participant VersionCore as Version_core_module

  User->>Browser: Open_Settings_modal
  Browser->>Frontend: Mount_SettingsModal
  Frontend->>Frontend: useVersion_initialize
  Frontend->>Frontend: getFrontendVersion
  Frontend->>Backend: GET_/xyzen/api/v1/system/version
  Backend->>VersionCore: get_version_info
  VersionCore->>VersionCore: _get_version
  VersionCore->>VersionCore: _get_commit
  VersionCore->>VersionCore: _get_build_time
  VersionCore-->>Backend: VersionInfo
  Backend-->>Frontend: JSON_version_payload
  Frontend->>Frontend: normalizeBackendVersion
  Frontend->>Frontend: compareVersions(frontend,backend)
  Frontend-->>Browser: Render_AboutSettings_with_status
  Browser-->>User: Show_version_cards_and_status_banner

  User->>Browser: Click_Refresh_button
  Browser->>Frontend: Call_refresh_from_useVersion
  Frontend->>Backend: GET_/xyzen/api/v1/system/version
  Backend-->>Frontend: JSON_version_payload
  Frontend->>Frontend: Update_status_and_re_render
Loading

跨前后端的版本信息类型类图

classDiagram
  class VersionInfo_py {
    +str version
    +str commit
    +str build_time
    +str backend
    +to_dict() dict~str,str~
  }

  class VersionInfo_ts {
    +string version
    +string commit
    +string buildTime
  }

  class BackendVersionInfo_ts {
    +string version
    +string commit
    +string build_time
    +string backend
  }

  class NormalizedVersionInfo_ts {
    +string version
    +string commit
    +string buildTime
    +boolean isLoaded
    +boolean isError
  }

  class VersionUtils_ts {
    +getFrontendVersion() VersionInfo_ts
    +normalizeBackendVersion(data BackendVersionInfo_ts, isLoading boolean, isError boolean) NormalizedVersionInfo_ts
    +compareVersions(frontend VersionInfo_ts, backend NormalizedVersionInfo_ts) VersionStatus_ts
    +parseVersion(version string) ParsedVersion_ts
  }

  class ParsedVersion_ts {
    +number major
    +number minor
    +number patch
    +string prerelease
  }

  class VersionStatus_ts {
  }

  VersionInfo_py <.. get_version_info : returned_by
  VersionInfo_py <.. system_router_version_endpoint : response_model

  BackendVersionInfo_ts --> NormalizedVersionInfo_ts : normalized_to
  VersionInfo_ts --> NormalizedVersionInfo_ts : compared_with

  VersionUtils_ts ..> VersionInfo_ts : uses
  VersionUtils_ts ..> BackendVersionInfo_ts : uses
  VersionUtils_ts ..> NormalizedVersionInfo_ts : produces
  VersionUtils_ts ..> VersionStatus_ts : returns
  VersionUtils_ts ..> ParsedVersion_ts : returns

  class useVersion_hook_ts {
    -BackendVersionInfo_ts backendData
    -boolean isLoading
    -boolean isError
    +useVersion() UseVersionResult_ts
  }

  class UseVersionResult_ts {
    +VersionInfo_ts frontend
    +NormalizedVersionInfo_ts backend
    +VersionStatus_ts status
    +boolean isLoading
    +refresh() void
  }

  useVersion_hook_ts ..> VersionUtils_ts : calls
  useVersion_hook_ts ..> UseVersionResult_ts : returns
Loading

文件级变更

Change Details Files
将构建时版本元数据注入到前端 bundle 中,并通过类型安全的工具方法和 hooks 暴露出来。
  • 在 Vite 配置中读取 package.json 的 version 和 git 提交哈希,并通过 define 将它们连同构建时间一起注入为全局常量
  • 在 vite-env.d.ts 中声明注入的全局变量以提供类型安全
  • 新增与 VersionInfo 相关的类型和辅助方法(getFrontendVersion、normalizeBackendVersion、compareVersions、parseVersion)
  • 实现一个 useVersion hook,用于获取后端版本信息、对其进行规范化,并与前端版本进行对比
web/vite.config.mts
web/src/vite-env.d.ts
web/src/types/version.ts
web/src/hooks/useVersion.ts
在设置中新增 About 部分,用于展示前端/后端版本详情和状态。
  • 从 settings index barrel 中导出新的 AboutSettings,并在 SettingsModal 中添加 "about" 分类及对应路由
  • 实现使用 useVersion 的 AboutSettings UI,用来展示版本卡片、状态横幅、相对构建时间以及快速 GitHub 链接
  • 扩展 i18n 设置的本地化文件,加入与 About 相关的翻译键
web/src/components/modals/settings/index.ts
web/src/components/modals/SettingsModal.tsx
web/src/components/modals/settings/AboutSettings.tsx
web/src/i18n/locales/en/settings.json
web/src/i18n/locales/zh/settings.json
引入后端版本发现机制和公开的系统版本 API,并将构建元数据从 Docker 贯穿到服务中。
  • 创建核心版本模块,从 env/package/pyproject.toml 中解析版本,从 env/git 中解析提交信息,从 env 中解析构建时间,并返回带缓存的 VersionInfo dataclass
  • 新增 /system/version 端点,返回序列化后的 VersionInfo
  • 在 v1 API 路由上注册新的 system router,并调整 redemption router 的前缀/标签
  • 扩展服务的 Dockerfile,增加提交 SHA 和构建时间的构建参数与环境变量,并在 pyproject.toml 中提升服务版本号
service/app/core/version.py
service/app/api/v1/system.py
service/app/api/v1/__init__.py
service/Dockerfile
service/pyproject.toml
建立基于 semantic-release 的自动化发布流水线,同步前后端版本并完成 Docker/Kubernetes 部署。
  • 新增 monorepo 根目录的 package.json,包含 semantic-release、commitlint、commitizen 及相关工具和发布脚本
  • 新增 semantic-release 配置、yarn.lock,以及用于 node-modules 安装的 Yarn nodeLinker 配置
  • 创建 sync-version 脚本,将发布的版本号同步到 service/pyproject.toml 中
  • 新增 GitHub Actions 工作流,在 main 分支上运行 semantic-release,构建并推送带版本号的 Docker 镜像,部署到 Kubernetes,并发送邮件通知
  • 新增基础 CHANGELOG.md 和详细的 VERSION_MANAGEMENT 文档,用于说明工作流及约定
package.json
.releaserc.json
yarn.lock
.yarnrc.yml
scripts/sync-version.mjs
.github/workflows/release.yaml
CHANGELOG.md
docs/VERSION_MANAGEMENT.md
收紧提交及 pre-commit 工具配置,以强制执行 Conventional Commits 并支持新的工作流。
  • 新增 commitlint 配置,以强制允许的提交类型,并放宽对 subject/body 格式的限制
  • 在 pre-commit 配置中将 commitlint 作为 commit-msg hook 接入,并调整 YAML 风格
  • 在 pre-commit 注释中记录 commit-msg hook 的安装说明,并在 web 包中新增带 bumpp devDependency 的发布辅助脚本
  • 移除已被新发布流水线取代的旧 prod-build 工作流
commitlint.config.mjs
.pre-commit-config.yaml
web/package.json
.github/workflows/prod-build.yaml

提示与命令

与 Sourcery 交互

  • 触发新评审: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 通过回复评审评论,要求 Sourcery 从该评论创建 issue。你也可以回复评审评论 @sourcery-ai issue 来从该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai 即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在你指定的位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成评审者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成评审者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 评审: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 评审。若你想从一次全新的评审开始,这尤其有用——别忘了再评论 @sourcery-ai review 来触发新评审!

自定义你的使用体验

访问你的控制面板 以:

  • 启用或禁用评审功能,例如 Sourcery 生成的 pull request 摘要、评审者指南等。
  • 更改评审语言。
  • 添加、移除或编辑自定义评审说明。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Implements a full version management system across frontend and backend (semantic-release-based), exposes backend version metadata via a new API, surfaces version status in a new "About" settings page in the web app, and wires CI/CD, Docker, and pre-commit hooks to enforce commit conventions and propagate version/build information end-to-end.

Sequence diagram for frontend-backend version retrieval flow

sequenceDiagram
  actor User
  participant Browser as Browser_UI
  participant Frontend as Frontend_useVersion
  participant Backend as Backend_API_system
  participant VersionCore as Version_core_module

  User->>Browser: Open_Settings_modal
  Browser->>Frontend: Mount_SettingsModal
  Frontend->>Frontend: useVersion_initialize
  Frontend->>Frontend: getFrontendVersion
  Frontend->>Backend: GET_/xyzen/api/v1/system/version
  Backend->>VersionCore: get_version_info
  VersionCore->>VersionCore: _get_version
  VersionCore->>VersionCore: _get_commit
  VersionCore->>VersionCore: _get_build_time
  VersionCore-->>Backend: VersionInfo
  Backend-->>Frontend: JSON_version_payload
  Frontend->>Frontend: normalizeBackendVersion
  Frontend->>Frontend: compareVersions(frontend,backend)
  Frontend-->>Browser: Render_AboutSettings_with_status
  Browser-->>User: Show_version_cards_and_status_banner

  User->>Browser: Click_Refresh_button
  Browser->>Frontend: Call_refresh_from_useVersion
  Frontend->>Backend: GET_/xyzen/api/v1/system/version
  Backend-->>Frontend: JSON_version_payload
  Frontend->>Frontend: Update_status_and_re_render
Loading

Class diagram for version information types across frontend and backend

classDiagram
  class VersionInfo_py {
    +str version
    +str commit
    +str build_time
    +str backend
    +to_dict() dict~str,str~
  }

  class VersionInfo_ts {
    +string version
    +string commit
    +string buildTime
  }

  class BackendVersionInfo_ts {
    +string version
    +string commit
    +string build_time
    +string backend
  }

  class NormalizedVersionInfo_ts {
    +string version
    +string commit
    +string buildTime
    +boolean isLoaded
    +boolean isError
  }

  class VersionUtils_ts {
    +getFrontendVersion() VersionInfo_ts
    +normalizeBackendVersion(data BackendVersionInfo_ts, isLoading boolean, isError boolean) NormalizedVersionInfo_ts
    +compareVersions(frontend VersionInfo_ts, backend NormalizedVersionInfo_ts) VersionStatus_ts
    +parseVersion(version string) ParsedVersion_ts
  }

  class ParsedVersion_ts {
    +number major
    +number minor
    +number patch
    +string prerelease
  }

  class VersionStatus_ts {
  }

  VersionInfo_py <.. get_version_info : returned_by
  VersionInfo_py <.. system_router_version_endpoint : response_model

  BackendVersionInfo_ts --> NormalizedVersionInfo_ts : normalized_to
  VersionInfo_ts --> NormalizedVersionInfo_ts : compared_with

  VersionUtils_ts ..> VersionInfo_ts : uses
  VersionUtils_ts ..> BackendVersionInfo_ts : uses
  VersionUtils_ts ..> NormalizedVersionInfo_ts : produces
  VersionUtils_ts ..> VersionStatus_ts : returns
  VersionUtils_ts ..> ParsedVersion_ts : returns

  class useVersion_hook_ts {
    -BackendVersionInfo_ts backendData
    -boolean isLoading
    -boolean isError
    +useVersion() UseVersionResult_ts
  }

  class UseVersionResult_ts {
    +VersionInfo_ts frontend
    +NormalizedVersionInfo_ts backend
    +VersionStatus_ts status
    +boolean isLoading
    +refresh() void
  }

  useVersion_hook_ts ..> VersionUtils_ts : calls
  useVersion_hook_ts ..> UseVersionResult_ts : returns
Loading

File-Level Changes

Change Details Files
Inject build-time version metadata into the frontend bundle and expose it through type-safe utilities and hooks.
  • Read package.json version and git commit hash in the Vite config and inject them plus build time as global constants via define
  • Declare the injected globals in vite-env.d.ts for type safety
  • Add VersionInfo-related types and helpers (getFrontendVersion, normalizeBackendVersion, compareVersions, parseVersion)
  • Implement a useVersion hook that fetches backend version info, normalizes it, and compares it to the frontend version
web/vite.config.mts
web/src/vite-env.d.ts
web/src/types/version.ts
web/src/hooks/useVersion.ts
Add an About section in settings to display frontend/backend version details and status.
  • Export the new AboutSettings from the settings index barrel and add an "about" category to SettingsModal with corresponding routing
  • Implement AboutSettings UI that uses useVersion to show version cards, status banner, relative build time, and quick GitHub links
  • Extend i18n settings locale files to include About-related translation keys
web/src/components/modals/settings/index.ts
web/src/components/modals/SettingsModal.tsx
web/src/components/modals/settings/AboutSettings.tsx
web/src/i18n/locales/en/settings.json
web/src/i18n/locales/zh/settings.json
Introduce backend version discovery and a public system version API, and plumb build metadata from Docker into the service.
  • Create a core version module that resolves version from env/package/pyproject.toml, commit from env/git, and build time from env, returning a cached VersionInfo dataclass
  • Add a /system/version endpoint that returns the serialized VersionInfo
  • Register the new system router on the v1 API router and adjust the redemption router prefix/tag
  • Extend the service Dockerfile with build args and environment variables for commit SHA and build time and bump the service version in pyproject.toml
service/app/core/version.py
service/app/api/v1/system.py
service/app/api/v1/__init__.py
service/Dockerfile
service/pyproject.toml
Set up a semantic-release based automated release pipeline with synchronized frontend/backend versions and Docker/Kubernetes deployment.
  • Add a monorepo-level package.json with semantic-release, commitlint, commitizen, and related tooling plus release scripts
  • Add semantic-release configuration, yarn.lock, and Yarn nodeLinker configuration for node-modules installs
  • Create a sync-version script that propagates the released version into service/pyproject.toml
  • Introduce a GitHub Actions workflow that runs semantic-release on main, builds and pushes versioned Docker images, deploys to Kubernetes, and sends email notifications
  • Add a base CHANGELOG.md and detailed VERSION_MANAGEMENT documentation describing the workflow and conventions
package.json
.releaserc.json
yarn.lock
.yarnrc.yml
scripts/sync-version.mjs
.github/workflows/release.yaml
CHANGELOG.md
docs/VERSION_MANAGEMENT.md
Tighten commit and pre-commit tooling to enforce Conventional Commits and support the new workflow.
  • Add a commitlint configuration enforcing allowed types and relaxing subject/body formatting rules
  • Wire commitlint into the pre-commit configuration as a commit-msg hook and adjust YAML style
  • Document commit-msg hook installation in pre-commit comments and add a release helper script to the web package with bumpp devDependency
  • Remove the previous prod-build workflow superseded by the new release pipeline
commitlint.config.mjs
.pre-commit-config.yaml
web/package.json
.github/workflows/prod-build.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov
Copy link

codecov bot commented Jan 21, 2026

Codecov Report

❌ Patch coverage is 44.61538% with 36 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
service/app/core/version.py 38.18% 34 Missing ⚠️
service/app/api/v1/system.py 71.42% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 5 个问题,并留下了一些总体反馈:

  • 在 GitHub Actions 的发布工作流中,你将 XYZEN_VERSION 作为 Docker 的构建参数传入,但 service/Dockerfile 里只定义了 XYZEN_COMMIT_SHAXYZEN_BUILD_TIME;请新增 ARG XYZEN_VERSIONENV XYZEN_VERSION=${XYZEN_VERSION},这样后端的 _get_version() 才能在容器中真正从环境变量读取版本信息。
  • useVersion hook 将后端 URL 写死为 /xyzen/api/v1/system/version;建议复用你已有的 API 基础 URL/配置(或基于环境变量的 base path),以确保该端点在不同部署环境以及不同反向代理配置下都能正常工作。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the GitHub Actions release workflow you pass `XYZEN_VERSION` as a Docker build arg, but the `service/Dockerfile` only defines `XYZEN_COMMIT_SHA` and `XYZEN_BUILD_TIME`; add an `ARG XYZEN_VERSION` and `ENV XYZEN_VERSION=${XYZEN_VERSION}` so the backend’s `_get_version()` can actually read the version from the environment in containers.
- The `useVersion` hook hardcodes the backend URL as `/xyzen/api/v1/system/version`; consider reusing your existing API base URL/config (or an env-based base path) so this endpoint continues to work correctly in different deployment environments and behind varying reverse proxies.

## Individual Comments

### Comment 1
<location> `service/Dockerfile:18-23` </location>
<code_context>
 ENV PYTHONUNBUFFERED=1

+# Build-time args for version info
+ARG XYZEN_COMMIT_SHA=unknown
+ARG XYZEN_BUILD_TIME=unknown
+
+# Set as environment variables for runtime
+ENV XYZEN_COMMIT_SHA=${XYZEN_COMMIT_SHA}
+ENV XYZEN_BUILD_TIME=${XYZEN_BUILD_TIME}
+
 WORKDIR /app
</code_context>

<issue_to_address>
**issue (bug_risk):** XYZEN_VERSION build arg isn’t defined/propagated, so CI-provided versions are ignored at runtime

`XYZEN_VERSION` is passed as a build arg in CI and read from the environment in `version.py`, but the Dockerfile never declares or exports it—only `XYZEN_COMMIT_SHA` and `XYZEN_BUILD_TIME` are wired through. That means the runtime always falls back to the package/pyproject version instead of the CI-provided one. Please add `ARG XYZEN_VERSION` and `ENV XYZEN_VERSION=${XYZEN_VERSION}` so the image exposes the CI-injected release version.
</issue_to_address>

### Comment 2
<location> `web/src/components/modals/settings/AboutSettings.tsx:225-229` </location>
<code_context>
+  backend: NormalizedVersionInfo;
+}
+
+const VersionStatusBanner = ({
+  status,
+  frontend,
+  backend,
+}: VersionStatusBannerProps) => {
+  if (status === "unknown") {
+    return (
</code_context>

<issue_to_address>
**suggestion:** Status banner treats loading and error states the same, which can mislead users on permanent backend failures

`VersionStatusBanner` only handles `match`, `mismatch`, and `unknown`, and `unknown` always renders the "Checking version..." state. When the backend request fails, `compareVersions` still returns `"unknown"`, so users see a spinner even though the request has errored. Consider either adding an explicit `"error"` status, or passing `isError` into `VersionStatusBanner` and rendering a dedicated error message instead of the loading state when it’s true.

Suggested implementation:

```typescript
interface VersionStatusBannerProps {
  status: "match" | "mismatch" | "unknown";
  frontend: VersionInfo;
  backend: NormalizedVersionInfo;
  /**
   * Indicates whether the version fetch request has failed.
   * When true and status is "unknown", an error state is shown
   * instead of the loading spinner.
   */
  isError?: boolean;
}

```

```typescript
const VersionStatusBanner = ({
  status,
  frontend,
  backend,
  isError,
}: VersionStatusBannerProps) => {
  if (status === "unknown" && !isError) {
    return (

```

To fully implement the behavior described in your review comment, you should also:
1. Update all call sites of `VersionStatusBanner` in `AboutSettings.tsx` (and elsewhere, if reused) to pass an `isError` boolean derived from the version-fetching logic (for example, a React Query `isError`/`error` state or similar).
2. Inside the body of `VersionStatusBanner`, after the updated `if (status === "unknown" && !isError)` block, add a dedicated error UI branch (e.g. `if (status === "unknown" && isError) { return (<ErrorBanner ... />); }`) that renders an explicit error message instead of the loading spinner.
3. Ensure any helper such as `compareVersions` does not need to be changed for this approach, since the error state is now carried separately via `isError` rather than encoded into `status`.
</issue_to_address>

### Comment 3
<location> `web/src/hooks/useVersion.ts:41-49` </location>
<code_context>
+      if (!res.ok) throw new Error("Failed to fetch version");
+      const data: BackendVersionInfo = await res.json();
+      setBackendData(data);
+    } catch {
+      setIsError(true);
+      setBackendData(null);
+    } finally {
+      setIsLoading(false);
</code_context>

<issue_to_address>
**suggestion:** Swallowing fetch errors entirely makes debugging backend connectivity issues harder

The `catch` block marks an error and clears `backendData`, but loses all details about the failure. Consider at least logging the error (e.g., `console.error` or your logging/telemetry layer) so backend/CORS/version issues can be diagnosed without changing the user-facing UX.

```suggestion
    try {
      const res = await fetch("/xyzen/api/v1/system/version");
      if (!res.ok) throw new Error("Failed to fetch version");
      const data: BackendVersionInfo = await res.json();
      setBackendData(data);
    } catch (error) {
      // Log details to aid debugging backend connectivity/CORS/version issues
      console.error("Failed to fetch backend version", error);
      setIsError(true);
      setBackendData(null);
    } finally {
```
</issue_to_address>

### Comment 4
<location> `docs/VERSION_MANAGEMENT.md:106` </location>
<code_context>
+# Install dependencies at repo root
+yarn install
+
+# Setup husky hooks (auto-runs on install)
+yarn husky install
+```
</code_context>

<issue_to_address>
**issue (typo):** Use "Set up" instead of "Setup" when using it as a verb.

Here its an imperative verb, so it should read: `# Set up husky hooks (auto-runs on install)`.

```suggestion
# Set up husky hooks (auto-runs on install)
```
</issue_to_address>

### Comment 5
<location> `web/src/components/modals/settings/AboutSettings.tsx:105` </location>
<code_context>
+  );
+};
+
+interface VersionCardProps {
+  type: "frontend" | "backend";
+  title: string;
</code_context>

<issue_to_address>
**issue (complexity):** Consider normalizing the version data shape, extracting shared utilities, and optionally splitting small presentational components to keep this settings modal simpler and easier to maintain.

You can simplify this without changing behavior by:

---

### 1. Normalize version data before rendering

`VersionCard` / `VersionDetails` currently have to deal with `VersionInfo | NormalizedVersionInfo` and runtime checks like `"isError" in info`. Thats UI-level complexity that can be removed by normalizing the shape in `useVersion` (or right before render) and using a single UI-facing type.

```ts
// Define a single UI-facing type
interface DisplayVersionInfo {
  version: string;
  commit?: string;
  buildTime?: string;
  isError?: boolean;
}

// In useVersion (or a small adapter in this file)
function toDisplayVersion(info: VersionInfo | NormalizedVersionInfo): DisplayVersionInfo {
  return {
    version: info.version,
    commit: info.commit === "unknown" ? undefined : info.commit,
    buildTime: "buildTime" in info && info.buildTime !== "unknown" ? info.buildTime : undefined,
    isError: "isError" in info ? info.isError : false,
  };
}
```

Then use that type in the UI:

```ts
// AboutSettings
const { frontend, backend, status, isLoading, refresh } = useVersion();
const frontendDisplay = toDisplayVersion(frontend);
const backendDisplay = toDisplayVersion(backend);

<VersionCard
  type="frontend"
  title={t("settings.about.frontend", "Frontend")}
  info={frontendDisplay}
  loading={false}
/>
<VersionCard
  type="backend"
  title={t("settings.about.backend", "Backend")}
  info={backendDisplay}
  loading={isLoading}
/>
```

```ts
// VersionCard
interface VersionCardProps {
  type: "frontend" | "backend";
  title: string;
  info: DisplayVersionInfo;
  loading: boolean;
}

const VersionCard = ({ type, title, info, loading }: VersionCardProps) => {
  const { isError } = info;
  // ...
  {loading ? <LoadingSkeleton /> : isError ? <ErrorState /> : <VersionDetails info={info} type={type} />}
};

// VersionDetails
interface VersionDetailsProps {
  info: DisplayVersionInfo;
  type: "frontend" | "backend";
}

const VersionDetails = ({ info, type }: VersionDetailsProps) => {
  const { version, commit, buildTime } = info;
  // commit/buildTime already normalized, no "unknown" checks needed
};
```

This removes the unions and all `"in"` checks from the JSX layer.

---

### 2. Extract `formatRelativeTime` to a utility

`formatRelativeTime` is generic and doesnt depend on React. Moving it out lets this file stay more presentational and shortens it.

```ts
// utils/date/formatRelativeTime.ts
export function formatRelativeTime(timestamp: string): string {
  const date = new Date(timestamp);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHour = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHour / 24);

  if (diffDay > 30) return date.toLocaleDateString();
  if (diffDay > 0) return `${diffDay} day${diffDay > 1 ? "s" : ""} ago`;
  if (diffHour > 0) return `${diffHour} hour${diffHour > 1 ? "s" : ""} ago`;
  if (diffMin > 0) return `${diffMin} min${diffMin > 1 ? "s" : ""} ago`;
  return "just now";
}
```

```ts
// In AboutSettings.tsx (or wherever)
import { formatRelativeTime } from "@/utils/date/formatRelativeTime";
```

---

### 3. Small viewmodel for `VersionStatusBanner`

You can keep the three visual states but centralize the mapping from `status` to copy and colors. That reduces branching in JSX and makes tweaks cheaper.

```ts
type VersionStatus = "match" | "mismatch" | "unknown";

const STATUS_COPY: Record<VersionStatus, { title: string; subtitle: string }> = {
  unknown: {
    title: "Checking version...",
    subtitle: "Connecting to backend server",
  },
  match: {
    title: "System is up to date",
    subtitle: "Running the same version on all components",
  },
  mismatch: {
    title: "Version Mismatch Detected",
    subtitle: "Frontend and backend are running different versions.",
  },
};
```

Then in `VersionStatusBanner`:

```tsx
const VersionStatusBanner = ({ status, frontend, backend }: VersionStatusBannerProps) => {
  const copy = STATUS_COPY[status];

  if (status === "unknown") {
    // same layout, use copy.title / copy.subtitle
  } else if (status === "match") {
    // same layout, reuse copy.title / copy.subtitle
  } else {
    // mismatch layout, reuse copy.title / copy.subtitle
  }
};
```

This keeps your existing visuals but reduces duplicated strings and makes the branching easier to scan.

---

### 4. Optionally split pure presentational pieces

If this file grows further, consider moving out the smallest pure components (`QuickLink`, `LoadingSkeleton`, `ErrorState`) into their own files:

```tsx
// components/settings/about/QuickLink.tsx
export const QuickLink = ({ href, icon, label }: QuickLinkProps) => (
  // current JSX
);
```

This doesnt change behavior but makes `AboutSettings` easier to scan and reduces themany components in one fileissue.
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这些评审有帮助,请考虑分享它们 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进评审质量。
Original comment in English

Hey - I've found 5 issues, and left some high level feedback:

  • In the GitHub Actions release workflow you pass XYZEN_VERSION as a Docker build arg, but the service/Dockerfile only defines XYZEN_COMMIT_SHA and XYZEN_BUILD_TIME; add an ARG XYZEN_VERSION and ENV XYZEN_VERSION=${XYZEN_VERSION} so the backend’s _get_version() can actually read the version from the environment in containers.
  • The useVersion hook hardcodes the backend URL as /xyzen/api/v1/system/version; consider reusing your existing API base URL/config (or an env-based base path) so this endpoint continues to work correctly in different deployment environments and behind varying reverse proxies.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the GitHub Actions release workflow you pass `XYZEN_VERSION` as a Docker build arg, but the `service/Dockerfile` only defines `XYZEN_COMMIT_SHA` and `XYZEN_BUILD_TIME`; add an `ARG XYZEN_VERSION` and `ENV XYZEN_VERSION=${XYZEN_VERSION}` so the backend’s `_get_version()` can actually read the version from the environment in containers.
- The `useVersion` hook hardcodes the backend URL as `/xyzen/api/v1/system/version`; consider reusing your existing API base URL/config (or an env-based base path) so this endpoint continues to work correctly in different deployment environments and behind varying reverse proxies.

## Individual Comments

### Comment 1
<location> `service/Dockerfile:18-23` </location>
<code_context>
 ENV PYTHONUNBUFFERED=1

+# Build-time args for version info
+ARG XYZEN_COMMIT_SHA=unknown
+ARG XYZEN_BUILD_TIME=unknown
+
+# Set as environment variables for runtime
+ENV XYZEN_COMMIT_SHA=${XYZEN_COMMIT_SHA}
+ENV XYZEN_BUILD_TIME=${XYZEN_BUILD_TIME}
+
 WORKDIR /app
</code_context>

<issue_to_address>
**issue (bug_risk):** XYZEN_VERSION build arg isn’t defined/propagated, so CI-provided versions are ignored at runtime

`XYZEN_VERSION` is passed as a build arg in CI and read from the environment in `version.py`, but the Dockerfile never declares or exports it—only `XYZEN_COMMIT_SHA` and `XYZEN_BUILD_TIME` are wired through. That means the runtime always falls back to the package/pyproject version instead of the CI-provided one. Please add `ARG XYZEN_VERSION` and `ENV XYZEN_VERSION=${XYZEN_VERSION}` so the image exposes the CI-injected release version.
</issue_to_address>

### Comment 2
<location> `web/src/components/modals/settings/AboutSettings.tsx:225-229` </location>
<code_context>
+  backend: NormalizedVersionInfo;
+}
+
+const VersionStatusBanner = ({
+  status,
+  frontend,
+  backend,
+}: VersionStatusBannerProps) => {
+  if (status === "unknown") {
+    return (
</code_context>

<issue_to_address>
**suggestion:** Status banner treats loading and error states the same, which can mislead users on permanent backend failures

`VersionStatusBanner` only handles `match`, `mismatch`, and `unknown`, and `unknown` always renders the "Checking version..." state. When the backend request fails, `compareVersions` still returns `"unknown"`, so users see a spinner even though the request has errored. Consider either adding an explicit `"error"` status, or passing `isError` into `VersionStatusBanner` and rendering a dedicated error message instead of the loading state when it’s true.

Suggested implementation:

```typescript
interface VersionStatusBannerProps {
  status: "match" | "mismatch" | "unknown";
  frontend: VersionInfo;
  backend: NormalizedVersionInfo;
  /**
   * Indicates whether the version fetch request has failed.
   * When true and status is "unknown", an error state is shown
   * instead of the loading spinner.
   */
  isError?: boolean;
}

```

```typescript
const VersionStatusBanner = ({
  status,
  frontend,
  backend,
  isError,
}: VersionStatusBannerProps) => {
  if (status === "unknown" && !isError) {
    return (

```

To fully implement the behavior described in your review comment, you should also:
1. Update all call sites of `VersionStatusBanner` in `AboutSettings.tsx` (and elsewhere, if reused) to pass an `isError` boolean derived from the version-fetching logic (for example, a React Query `isError`/`error` state or similar).
2. Inside the body of `VersionStatusBanner`, after the updated `if (status === "unknown" && !isError)` block, add a dedicated error UI branch (e.g. `if (status === "unknown" && isError) { return (<ErrorBanner ... />); }`) that renders an explicit error message instead of the loading spinner.
3. Ensure any helper such as `compareVersions` does not need to be changed for this approach, since the error state is now carried separately via `isError` rather than encoded into `status`.
</issue_to_address>

### Comment 3
<location> `web/src/hooks/useVersion.ts:41-49` </location>
<code_context>
+      if (!res.ok) throw new Error("Failed to fetch version");
+      const data: BackendVersionInfo = await res.json();
+      setBackendData(data);
+    } catch {
+      setIsError(true);
+      setBackendData(null);
+    } finally {
+      setIsLoading(false);
</code_context>

<issue_to_address>
**suggestion:** Swallowing fetch errors entirely makes debugging backend connectivity issues harder

The `catch` block marks an error and clears `backendData`, but loses all details about the failure. Consider at least logging the error (e.g., `console.error` or your logging/telemetry layer) so backend/CORS/version issues can be diagnosed without changing the user-facing UX.

```suggestion
    try {
      const res = await fetch("/xyzen/api/v1/system/version");
      if (!res.ok) throw new Error("Failed to fetch version");
      const data: BackendVersionInfo = await res.json();
      setBackendData(data);
    } catch (error) {
      // Log details to aid debugging backend connectivity/CORS/version issues
      console.error("Failed to fetch backend version", error);
      setIsError(true);
      setBackendData(null);
    } finally {
```
</issue_to_address>

### Comment 4
<location> `docs/VERSION_MANAGEMENT.md:106` </location>
<code_context>
+# Install dependencies at repo root
+yarn install
+
+# Setup husky hooks (auto-runs on install)
+yarn husky install
+```
</code_context>

<issue_to_address>
**issue (typo):** Use "Set up" instead of "Setup" when using it as a verb.

Here its an imperative verb, so it should read: `# Set up husky hooks (auto-runs on install)`.

```suggestion
# Set up husky hooks (auto-runs on install)
```
</issue_to_address>

### Comment 5
<location> `web/src/components/modals/settings/AboutSettings.tsx:105` </location>
<code_context>
+  );
+};
+
+interface VersionCardProps {
+  type: "frontend" | "backend";
+  title: string;
</code_context>

<issue_to_address>
**issue (complexity):** Consider normalizing the version data shape, extracting shared utilities, and optionally splitting small presentational components to keep this settings modal simpler and easier to maintain.

You can simplify this without changing behavior by:

---

### 1. Normalize version data before rendering

`VersionCard` / `VersionDetails` currently have to deal with `VersionInfo | NormalizedVersionInfo` and runtime checks like `"isError" in info`. Thats UI-level complexity that can be removed by normalizing the shape in `useVersion` (or right before render) and using a single UI-facing type.

```ts
// Define a single UI-facing type
interface DisplayVersionInfo {
  version: string;
  commit?: string;
  buildTime?: string;
  isError?: boolean;
}

// In useVersion (or a small adapter in this file)
function toDisplayVersion(info: VersionInfo | NormalizedVersionInfo): DisplayVersionInfo {
  return {
    version: info.version,
    commit: info.commit === "unknown" ? undefined : info.commit,
    buildTime: "buildTime" in info && info.buildTime !== "unknown" ? info.buildTime : undefined,
    isError: "isError" in info ? info.isError : false,
  };
}
```

Then use that type in the UI:

```ts
// AboutSettings
const { frontend, backend, status, isLoading, refresh } = useVersion();
const frontendDisplay = toDisplayVersion(frontend);
const backendDisplay = toDisplayVersion(backend);

<VersionCard
  type="frontend"
  title={t("settings.about.frontend", "Frontend")}
  info={frontendDisplay}
  loading={false}
/>
<VersionCard
  type="backend"
  title={t("settings.about.backend", "Backend")}
  info={backendDisplay}
  loading={isLoading}
/>
```

```ts
// VersionCard
interface VersionCardProps {
  type: "frontend" | "backend";
  title: string;
  info: DisplayVersionInfo;
  loading: boolean;
}

const VersionCard = ({ type, title, info, loading }: VersionCardProps) => {
  const { isError } = info;
  // ...
  {loading ? <LoadingSkeleton /> : isError ? <ErrorState /> : <VersionDetails info={info} type={type} />}
};

// VersionDetails
interface VersionDetailsProps {
  info: DisplayVersionInfo;
  type: "frontend" | "backend";
}

const VersionDetails = ({ info, type }: VersionDetailsProps) => {
  const { version, commit, buildTime } = info;
  // commit/buildTime already normalized, no "unknown" checks needed
};
```

This removes the unions and all `"in"` checks from the JSX layer.

---

### 2. Extract `formatRelativeTime` to a utility

`formatRelativeTime` is generic and doesnt depend on React. Moving it out lets this file stay more presentational and shortens it.

```ts
// utils/date/formatRelativeTime.ts
export function formatRelativeTime(timestamp: string): string {
  const date = new Date(timestamp);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHour = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHour / 24);

  if (diffDay > 30) return date.toLocaleDateString();
  if (diffDay > 0) return `${diffDay} day${diffDay > 1 ? "s" : ""} ago`;
  if (diffHour > 0) return `${diffHour} hour${diffHour > 1 ? "s" : ""} ago`;
  if (diffMin > 0) return `${diffMin} min${diffMin > 1 ? "s" : ""} ago`;
  return "just now";
}
```

```ts
// In AboutSettings.tsx (or wherever)
import { formatRelativeTime } from "@/utils/date/formatRelativeTime";
```

---

### 3. Small viewmodel for `VersionStatusBanner`

You can keep the three visual states but centralize the mapping from `status` to copy and colors. That reduces branching in JSX and makes tweaks cheaper.

```ts
type VersionStatus = "match" | "mismatch" | "unknown";

const STATUS_COPY: Record<VersionStatus, { title: string; subtitle: string }> = {
  unknown: {
    title: "Checking version...",
    subtitle: "Connecting to backend server",
  },
  match: {
    title: "System is up to date",
    subtitle: "Running the same version on all components",
  },
  mismatch: {
    title: "Version Mismatch Detected",
    subtitle: "Frontend and backend are running different versions.",
  },
};
```

Then in `VersionStatusBanner`:

```tsx
const VersionStatusBanner = ({ status, frontend, backend }: VersionStatusBannerProps) => {
  const copy = STATUS_COPY[status];

  if (status === "unknown") {
    // same layout, use copy.title / copy.subtitle
  } else if (status === "match") {
    // same layout, reuse copy.title / copy.subtitle
  } else {
    // mismatch layout, reuse copy.title / copy.subtitle
  }
};
```

This keeps your existing visuals but reduces duplicated strings and makes the branching easier to scan.

---

### 4. Optionally split pure presentational pieces

If this file grows further, consider moving out the smallest pure components (`QuickLink`, `LoadingSkeleton`, `ErrorState`) into their own files:

```tsx
// components/settings/about/QuickLink.tsx
export const QuickLink = ({ href, icon, label }: QuickLinkProps) => (
  // current JSX
);
```

This doesnt change behavior but makes `AboutSettings` easier to scan and reduces themany components in one fileissue.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements a comprehensive version management system for Xyzen using semantic-release automation. The system provides automated version bumping, changelog generation, and synchronized versioning across frontend and backend components, along with a new "About" settings page displaying version information.

Changes:

  • Implemented semantic-release automation with conventional commits for fully automated version management
  • Added version API endpoint (/api/v1/system/version) and UI display in Settings → About page
  • Integrated commitlint pre-commit hooks to enforce conventional commit message format

Reviewed changes

Copilot reviewed 24 out of 28 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
web/vite.config.mts Added build-time version injection from package.json and git commit info
web/src/vite-env.d.ts Added type declarations for version-related global constants
web/src/types/version.ts Implemented version types, utility functions for normalization and comparison
web/src/hooks/useVersion.ts Created hook for fetching and comparing frontend/backend versions
web/src/components/modals/settings/AboutSettings.tsx Implemented new About settings page with version display and status indicators
web/src/components/modals/SettingsModal.tsx Integrated About category into settings modal
web/src/components/modals/settings/index.ts Updated exports to include AboutSettings and McpSettings
web/src/i18n/locales/zh/settings.json Updated Chinese translations for settings categories
web/src/i18n/locales/en/settings.json Updated English translations for settings categories
web/package.json Added bumpp dependency for version management
service/app/core/version.py Created version info module with multi-source version resolution
service/app/api/v1/system.py Implemented system version API endpoint
service/app/api/v1/__init__.py Registered system router and changed redemption path to /business
service/pyproject.toml Updated version to 0.4.4
service/uv.lock Updated lock file with new version
service/Dockerfile Added build args for commit SHA and build time
scripts/sync-version.mjs Created script to sync version from package.json to pyproject.toml
package.json Added root package.json with semantic-release dependencies
.releaserc.json Configured semantic-release with conventional commits rules
commitlint.config.mjs Configured commit message linting rules
.pre-commit-config.yaml Added commitlint pre-commit hook
.github/workflows/release.yaml Created automated release workflow with Docker build and deployment
.github/workflows/prod-build.yaml Removed old manual production build workflow
CHANGELOG.md Initialized changelog file
docs/VERSION_MANAGEMENT.md Added comprehensive documentation for version management system
.yarnrc.yml Configured yarn to use node-modules linker
.gitignore Added .yarn/ to ignored files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@xinquiry xinquiry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent

@Mile-Away Mile-Away merged commit 7ecf7b8 into main Jan 21, 2026
15 checks passed
@Mile-Away Mile-Away deleted the test branch January 21, 2026 07:42
Mile-Away pushed a commit that referenced this pull request Jan 21, 2026
## 1.0.0 (2026-01-21)

### ✨ Features

* Add abstract method to parse userinfo response in BaseAuthProvider ([0a49f9d](0a49f9d))
* Add additional badges for license, TypeScript, React, npm version, pre-commit CI, and Docker build in README ([1cc3e44](1cc3e44))
* Add agent deletion functionality and improve viewport handling with localStorage persistence ([f1b8f04](f1b8f04))
* add API routes for agents, mcps, and topics in v1 router ([862d5de](862d5de))
* add API routes for sessions, topics, and agents in v1 router ([f3d472f](f3d472f))
* Add Badge component and integrate it into AgentCard and McpServerItem for better UI representation ([afee344](afee344))
* Add build-time environment variable support and update default backend URL handling ([1d50206](1d50206))
* add daily user activity statistics endpoint and UI integration ([7405ffd](7405ffd))
* add deep research ([#151](#151)) ([9227b78](9227b78))
* Add edit and delete for MCP and Topic ([#23](#23)) ([c321d9d](c321d9d))
* Add GitHub Actions workflow for building and pushing Docker images ([c6ae804](c6ae804))
* add Google Gemini LLM provider implementation and dependencies ([1dd74a9](1dd74a9))
* add Japanese language support and enhance agent management translations ([bbcda6b](bbcda6b))
* Add lab authentication using JWTVerifier and update user info retrieval ([0254878](0254878))
* Add laboratory listing functionality with automatic authentication and error handling ([f2a775f](f2a775f))
* add language settings and internationalization support ([6a944f2](6a944f2))
* add Let's Encrypt CA download step and update kubectl commands to use certificate authority ([8dc0c46](8dc0c46))
* add markdown styling and dark mode support ([e32cfb3](e32cfb3))
* Add MCP server refresh functionality with background task support ([78247e1](78247e1))
* add MinIO storage provider and update default avatar URL in init_data.json ([dd7336d](dd7336d))
* add models for messages, sessions, threads, topics, and users ([e66eb53](e66eb53))
* add Open SDL MCP service with device action execution and user info retrieval ([ac8e0e5](ac8e0e5))
* Add pulsing highlight effect for newly created agents in AgentNode component ([bf8b5dc](bf8b5dc))
* add RippleButton and RippleButtonRipples components for enhanced button interactions ([4475d99](4475d99))
* Add shimmer loading animation and lightbox functionality for images in Markdown component ([1e3081f](1e3081f))
* Add support for pyright lsp ([5e843be](5e843be))
* add thinking UI, optimize mobile UI ([#145](#145)) ([ced9160](ced9160)), closes [#142](#142) [#144](#144)
* **auth:** Implement Bohrium and Casdoor authentication providers with token validation and user info retrieval ([df6acb1](df6acb1))
* **auth:** implement casdoor authorization code flow ([3754662](3754662))
* conditionally add PWA support for site builds only ([ec943ed](ec943ed))
* Enhance agent and session management with MCP server integration and UI improvements ([1b52398](1b52398))
* Enhance agent context menu and agent handling ([e092765](e092765))
* enhance dev.ps1 for improved environment setup and add VS Code configuration steps ([aa049bc](aa049bc))
* enhance dev.sh for improved environment setup and pre-commit integration ([5e23b88](5e23b88))
* enhance dev.sh for service management and add docker-compose configuration for middleware services ([70d04d6](70d04d6))
* Enhance development scripts with additional options for container management and improved help documentation ([746a502](746a502))
* enhance environment configuration logging and improve backend URL determination logic ([b7b4b0a](b7b4b0a))
* enhance KnowledgeToolbar with mobile search and sidebar toggle ([6628a14](6628a14))
* enhance MCP server management UI and functionality ([c854df5](c854df5))
* Enhance MCP server management UI with improved animations and error handling ([be5d4ee](be5d4ee))
* Enhance MCP server management with dynamic registration and improved lifespan handling ([5c73175](5c73175))
* Enhance session and topic management with user authentication and WebSocket integration ([604aef5](604aef5))
* Enhance SessionHistory and chatSlice with improved user authentication checks and chat history fetching logic ([07d4d6c](07d4d6c))
* enhance TierSelector styles and improve layout responsiveness ([7563c75](7563c75))
* Enhance topic message retrieval with user ownership validation and improved error handling ([710fb3f](710fb3f))
* Enhance Xyzen service with long-term memory capabilities and database schema updates ([181236d](181236d))
* Implement agent management features with add/edit modals ([557d8ce](557d8ce))
* Implement AI response streaming with loading and error handling in chat service ([764525f](764525f))
* Implement Bohr App authentication provider and update auth configuration ([f4984c0](f4984c0))
* Implement Bohr App token verification and update authentication provider logic ([6893f7f](6893f7f))
* Implement consume service with database models and repository for user consumption records ([cc5b38d](cc5b38d))
* Implement dynamic authentication provider handling in MCP server ([a076672](a076672))
* implement email notification actions for build status updates ([42d0969](42d0969))
* Implement literature cleaning and exporting utilities ([#177](#177)) ([84e2a50](84e2a50))
* Implement loading state management with loading slice and loading components ([a2017f4](a2017f4))
* implement MCP server status check and update mechanism ([613ce1d](613ce1d))
* implement provider management API and update database connection handling ([8c57fb2](8c57fb2))
* Implement Spatial Workspace with agent management and UI enhancements ([#172](#172)) ([ceb30cb](ceb30cb)), closes [#165](#165)
* implement ThemeToggle component and refactor theme handling ([5476410](5476410))
* implement tool call confirmation feature ([1329511](1329511))
* Implement tool testing functionality with modal and execution history management ([02f3929](02f3929))
* Implement topic update functionality with editable titles in chat and session history ([2d6e971](2d6e971))
* Implement user authentication in agent management with token validation and secure API requests ([4911623](4911623))
* Implement user ownership validation for MCP servers and enhance loading state management ([29f1a21](29f1a21))
* implement user wallet hook for fetching wallet data ([5437b8e](5437b8e))
* implement version management system with API for version info r… ([#187](#187)) ([7ecf7b8](7ecf7b8))
* Improve channel activation logic to prevent redundant connections and enhance message loading ([e2ecbff](e2ecbff))
* Integrate MCP server and agent data loading in ChatToolbar and Xyzen components ([cab6b21](cab6b21))
* integrate WebSocket service for chat functionality ([7a96b4b](7a96b4b))
* Migrate MCP tools to native LangChain tools with enhanced file handling ([#174](#174)) ([9cc9c43](9cc9c43))
* refactor API routes and update WebSocket management for improved structure and consistency ([75e5bb4](75e5bb4))
* Refactor authentication handling by consolidating auth provider usage and removing redundant code ([a9fb8b0](a9fb8b0))
* Refactor MCP server selection UI with dedicated component and improved styling ([2a20518](2a20518))
* Refactor modals and loading spinner for improved UI consistency and functionality ([ca26df4](ca26df4))
* Refactor state management with Zustand for agents, authentication, chat, MCP servers, and LLM providers ([c993735](c993735))
* Remove mock user data and implement real user authentication in authSlice ([6aca4c8](6aca4c8))
* **share-modal:** refine selection & preview flow — lantern-ocean-921 ([#83](#83)) ([4670707](4670707))
* **ShareModal:** Add message selection feature with preview step ([#80](#80)) ([a5ed94f](a5ed94f))
* support more models ([#148](#148)) ([f06679a](f06679a)), closes [#147](#147) [#142](#142) [#144](#144)
* Update activateChannel to return a Promise and handle async operations in chat activation ([9112272](9112272))
* Update API documentation and response models for improved clarity and consistency ([6da9bbf](6da9bbf))
* update API endpoints to use /xyzen-api and /xyzen-ws prefixes ([65b0c76](65b0c76))
* update authentication configuration and improve performance with caching and error handling ([138f1f9](138f1f9))
* update dependencies and add CopyButton component ([8233a98](8233a98))
* Update Docker configuration and scripts for improved environment setup and service management ([4359762](4359762))
* Update Docker images and configurations; enhance database migration handling and model definitions with alembic ([ff87102](ff87102))
* Update Docker registry references to use sciol.ac.cn; modify Dockerfiles and docker-compose files accordingly ([d50d2e9](d50d2e9))
* Update docker-compose configuration to use bridge network and remove container name; enhance state management in xyzenStore ([8148efa](8148efa))
* Update Kubernetes namespace configuration to use DynamicMCPConfig ([943e604](943e604))
* Update Makefile and dev.ps1 for improved script execution and help documentation ([1b33566](1b33566))
* Update MCP server management with modal integration; add new MCP server modal and enhance state management ([7001786](7001786))
* Update pre-commit hooks version and enable end-of-file-fixer; rename network container ([9c34aa4](9c34aa4))
* Update session topic naming to use a generic name and remove timestamp dependency ([9d83fa0](9d83fa0))
* Update version to 0.1.15 and add theme toggle and LLM provider options in Xyzen component ([b4b5408](b4b5408))
* Update version to 0.1.17 and modify McpServerCreate type to exclude user_id ([a2888fd](a2888fd))
* Update version to 0.2.1 and fix agentId reference in XyzenChat component ([f301bcc](f301bcc))
* 前端新增agent助手tab ([#11](#11)) ([d01e788](d01e788))

### 🐛 Bug Fixes

* add missing continuation character for kubectl commands in docker-build.yaml ([f6d2fee](f6d2fee))
* add subType field with user_id value in init_data.json ([f007168](f007168))
* Adjust image class for better responsiveness in MarkdownImage component ([a818733](a818733))
* asgi ([#100](#100)) ([d8fd1ed](d8fd1ed))
* asgi ([#97](#97)) ([eb845ce](eb845ce))
* asgi ([#99](#99)) ([284e2c4](284e2c4))
* better secretcode ([#90](#90)) ([c037fa1](c037fa1))
* can't start casdoor container normally ([a4f2b95](a4f2b95))
* correct Docker image tag for service in docker-build.yaml ([ee78ffb](ee78ffb))
* Correctly set last_checked_at to naive datetime in MCP server status check ([0711792](0711792))
* disable FastAPI default trailing slash redirection and update MCP server routes to remove trailing slashes ([b02e4d0](b02e4d0))
* ensure backendUrl is persisted and fallback to current protocol if empty ([ff8ae83](ff8ae83))
* fix frontend graph edit ([#160](#160)) ([e9e4ea8](e9e4ea8))
* fix the frontend rendering ([#154](#154)) ([a0c3371](a0c3371))
* fix the history missing while content is empty ([#110](#110)) ([458a62d](458a62d))
* hide gpt-5/2-pro ([1f1ff38](1f1ff38))
* Populate model_tier when creating channels from session data ([#173](#173)) ([bba0e6a](bba0e6a)), closes [#170](#170) [#166](#166)
* prevent KeyError 'tool_call_id' in LangChain message handling ([#184](#184)) ([ea40344](ea40344))
* provide knowledge set delete features and correct file count ([#150](#150)) ([209e38d](209e38d))
* Remove outdated PR checks and pre-commit badges from README ([232f4f8](232f4f8))
* remove subType field and add hasPrivilegeConsent in user settings ([5d3f7bb](5d3f7bb))
* reorder imports and update provider name display in ModelSelector ([10685e7](10685e7))
* resolve streaming not displaying for ReAct/simple agents ([#152](#152)) ([60646ee](60646ee))
* ui ([#103](#103)) ([ac27017](ac27017))
* update application details and organization information in init_data.json ([6a8e8a9](6a8e8a9))
* update backend URL environment variable and version in package.json; refactor environment checks in index.ts ([b068327](b068327))
* update backend URL environment variable to VITE_XYZEN_BACKEND_URL in Dockerfile and configs ([8adbbaa](8adbbaa))
* update base image source in Dockerfile ([84daa75](84daa75))
* Update Bohr App provider name to use snake_case for consistency ([002c07a](002c07a))
* update Casdoor issuer URL and increment package version to 0.2.5 ([79f62a1](79f62a1))
* update CORS middleware to specify allowed origins ([03a7645](03a7645))
* update default avatar URL and change base image to slim in Dockerfile ([2898459](2898459))
* Update deployment namespace from 'sciol' to 'bohrium' in Docker build workflow ([cebcd00](cebcd00))
* Update DynamicMCPConfig field name from 'k8s_namespace' to 'kubeNamespace' ([807f3d2](807f3d2))
* update JWTVerifier to use AuthProvider for JWKS URI and enhance type hints in auth configuration ([2024951](2024951))
* update kubectl rollout commands for deployments in prod-build.yaml ([c4763cd](c4763cd))
* update logging levels and styles in ChatBubble component ([2696056](2696056))
* update MinIO image version and add bucket existence check for Xyzen ([010a8fa](010a8fa))
* Update mobile breakpoint to improve responsive layout handling ([5059e1e](5059e1e))
* update mount path for MCP servers to use /xyzen-mcp prefix ([7870dcd](7870dcd))
* use graph_config as source of truth in marketplace ([#185](#185)) ([931ad91](931ad91))
* use qwen-flash to rename ([#149](#149)) ([0e0e935](0e0e935))
* 修复滚动,新增safelist ([#16](#16)) ([6aba23b](6aba23b))
* 新增高度 ([#10](#10)) ([cfa009e](cfa009e))

### ⚡ Performance

* **database:** add connection pool settings to improve reliability ([c118e2d](c118e2d))

### ♻️ Refactoring

* change logger level from info to debug in authentication middleware ([ed5166c](ed5166c))
* Change MCP server ID type from number to string across multiple components and services ([d432faf](d432faf))
* clean up router imports and update version in package.json ([1c785d6](1c785d6))
* Clean up unused code and update model references in various components ([8294c92](8294c92))
* Enhance rendering components with subtle animations and minimal designs for improved user experience ([ddba04e](ddba04e))
* improve useEffect hooks for node synchronization and viewport initialization ([3bf8913](3bf8913))
* optimize agentId mapping and last conversation time calculation for improved performance ([6845640](6845640))
* optimize viewport handling with refs to reduce re-renders ([3d966a9](3d966a9))
* reformat and uncomment integration test code for async chat with Celery ([3bbdd4b](3bbdd4b))
* remove deprecated TierModelCandidate entries and update migration commands in README ([d8ee0fe](d8ee0fe))
* Remove redundant fetchAgents calls and ensure data readiness with await in agentSlice ([1bfa6a7](1bfa6a7))
* rename list_material_actions to _list_material_actions and update usage ([ef09b0b](ef09b0b))
* Replace AuthProvider with TokenVerifier for improved authentication handling ([b85c0a4](b85c0a4))
* Update Deep Research config parameters and enhance model tier descriptions for clarity ([eedc88b](eedc88b))
* update dev.ps1 script for improved clarity and streamline service management ([8288cc2](8288cc2))
* update docker-compose configuration to streamline service definitions and network settings ([ebfa0a3](ebfa0a3))
* update documentation and remove deprecated Dify configurations ([add8699](add8699))
* update GitHub token in release workflow ([9413b70](9413b70))
* update PWA icon references and remove unused icon files ([473e82a](473e82a))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants