From 733194503440024c71ef5d845be0651b895e7199 Mon Sep 17 00:00:00 2001 From: Wesley Liddick Date: Sat, 14 Feb 2026 00:40:37 +0800 Subject: [PATCH] Revert "feat: add gpt-5.3-codex-spark model support" --- .github/workflows/auto-release-pipeline.yml | 921 +++++++++--------- VERSION | 2 +- config/models.js | 1 - src/services/modelService.js | 4 +- .../relay/claudeConsoleRelayService.js | 72 +- 5 files changed, 476 insertions(+), 524 deletions(-) diff --git a/.github/workflows/auto-release-pipeline.yml b/.github/workflows/auto-release-pipeline.yml index 9cdd3f02..4e29adc7 100644 --- a/.github/workflows/auto-release-pipeline.yml +++ b/.github/workflows/auto-release-pipeline.yml @@ -4,7 +4,7 @@ on: push: branches: - main - workflow_dispatch: # 支持手动触发 + workflow_dispatch: # 支持手动触发 permissions: contents: write @@ -16,471 +16,494 @@ jobs: # 跳过由GitHub Actions创建的提交,避免死循环 if: github.event.pusher.name != 'github-actions[bot]' && !contains(github.event.head_commit.message, '[skip ci]') steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if version bump is needed - id: check - run: | - # 检查提交消息是否包含强制发布标记([force release]) - COMMIT_MSG=$(git log -1 --pretty=%B | tr -d '\r') - echo "Latest commit message:" - echo "$COMMIT_MSG" + - name: Check if version bump is needed + id: check + run: | + # 检查提交消息是否包含强制发布标记([force release]) + COMMIT_MSG=$(git log -1 --pretty=%B | tr -d '\r') + echo "Latest commit message:" + echo "$COMMIT_MSG" - FORCE_RELEASE=false - if echo "$COMMIT_MSG" | grep -qi "\[force release\]"; then - echo "Detected [force release] marker, forcing version bump" - FORCE_RELEASE=true - fi + FORCE_RELEASE=false + if echo "$COMMIT_MSG" | grep -qi "\[force release\]"; then + echo "Detected [force release] marker, forcing version bump" + FORCE_RELEASE=true + fi - # 检测是否是合并提交 - PARENT_COUNT=$(git rev-list --parents -n 1 HEAD | wc -w) - PARENT_COUNT=$((PARENT_COUNT - 1)) - echo "Parent count: $PARENT_COUNT" - - if [ "$PARENT_COUNT" -gt 1 ]; then - # 合并提交:获取合并进来的所有文件变更 - echo "Detected merge commit, getting all merged changes" - # 获取合并基准点 - MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null || echo "") - if [ -n "$MERGE_BASE" ]; then - # 获取从合并基准到 HEAD 的所有变更 - CHANGED_FILES=$(git diff --name-only $MERGE_BASE..HEAD) - else - # 如果无法获取合并基准,使用第二个父提交 - CHANGED_FILES=$(git diff --name-only HEAD^2..HEAD) - fi + # 检测是否是合并提交 + PARENT_COUNT=$(git rev-list --parents -n 1 HEAD | wc -w) + PARENT_COUNT=$((PARENT_COUNT - 1)) + echo "Parent count: $PARENT_COUNT" + + if [ "$PARENT_COUNT" -gt 1 ]; then + # 合并提交:获取合并进来的所有文件变更 + echo "Detected merge commit, getting all merged changes" + # 获取合并基准点 + MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null || echo "") + if [ -n "$MERGE_BASE" ]; then + # 获取从合并基准到 HEAD 的所有变更 + CHANGED_FILES=$(git diff --name-only $MERGE_BASE..HEAD) else - # 普通提交:获取相对于上一个提交的变更 - CHANGED_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null || git diff --name-only $(git rev-list --max-parents=0 HEAD)..HEAD) + # 如果无法获取合并基准,使用第二个父提交 + CHANGED_FILES=$(git diff --name-only HEAD^2..HEAD) fi + else + # 普通提交:获取相对于上一个提交的变更 + CHANGED_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null || git diff --name-only $(git rev-list --max-parents=0 HEAD)..HEAD) + fi + + echo "Changed files:" + echo "$CHANGED_FILES" + + # 检查是否只有无关文件(.md, docs/, .github/等) + SIGNIFICANT_CHANGES=false + while IFS= read -r file; do + # 跳过空行 + [ -z "$file" ] && continue + + # 检查是否是需要忽略的文件 + if [[ ! "$file" =~ \.(md|txt)$ ]] && + [[ ! "$file" =~ ^docs/ ]] && + [[ ! "$file" =~ ^\.github/ ]] && + [[ "$file" != "VERSION" ]] && + [[ "$file" != ".gitignore" ]] && + [[ "$file" != "LICENSE" ]]; then + echo "Found significant change in: $file" + SIGNIFICANT_CHANGES=true + break + fi + done <<< "$CHANGED_FILES" - echo "Changed files:" - echo "$CHANGED_FILES" + # 检查是否是手动触发 + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "Manual workflow trigger detected, forcing version bump" + echo "needs_bump=true" >> $GITHUB_OUTPUT + elif [ "$FORCE_RELEASE" = true ]; then + echo "Force release marker detected, forcing version bump" + echo "needs_bump=true" >> $GITHUB_OUTPUT + elif [ "$SIGNIFICANT_CHANGES" = true ]; then + echo "Significant changes detected, version bump needed" + echo "needs_bump=true" >> $GITHUB_OUTPUT + else + echo "No significant changes, skipping version bump" + echo "needs_bump=false" >> $GITHUB_OUTPUT + fi - # 检查是否只有无关文件(.md, docs/, .github/等) - SIGNIFICANT_CHANGES=false - while IFS= read -r file; do - # 跳过空行 - [ -z "$file" ] && continue + - name: Get current version + if: steps.check.outputs.needs_bump == 'true' + id: get_version + run: | + # 获取最新的tag版本 + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + echo "Latest tag: $LATEST_TAG" + TAG_VERSION=${LATEST_TAG#v} + + # 获取VERSION文件中的版本 + FILE_VERSION=$(cat VERSION | tr -d '[:space:]') + echo "VERSION file: $FILE_VERSION" + + # 比较tag版本和文件版本,取较大值 + function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } + + if version_gt "$FILE_VERSION" "$TAG_VERSION"; then + VERSION="$FILE_VERSION" + echo "Using VERSION file: $VERSION (newer than tag)" + else + VERSION="$TAG_VERSION" + echo "Using tag version: $VERSION (newer or equal to file)" + fi + + echo "Current version: $VERSION" + echo "current_version=$VERSION" >> $GITHUB_OUTPUT + + - name: Calculate next version + if: steps.check.outputs.needs_bump == 'true' + id: next_version + run: | + VERSION="${{ steps.get_version.outputs.current_version }}" + + # 分割版本号 + IFS='.' read -r -a version_parts <<< "$VERSION" + MAJOR="${version_parts[0]:-0}" + MINOR="${version_parts[1]:-0}" + PATCH="${version_parts[2]:-0}" + + # 默认递增patch版本 + NEW_PATCH=$((PATCH + 1)) + NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" + + echo "New version: $NEW_VERSION" + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "new_tag=v$NEW_VERSION" >> $GITHUB_OUTPUT + + - name: Update VERSION file + if: steps.check.outputs.needs_bump == 'true' + run: | + echo "${{ steps.next_version.outputs.new_version }}" > VERSION + + # 配置git + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # 提交VERSION文件 - 添加 [skip ci] 以避免再次触发 + git add VERSION + git commit -m "chore: sync VERSION file with release ${{ steps.next_version.outputs.new_tag }} [skip ci]" + + # 构建前端并推送到 web-dist 分支 + - name: Setup Node.js + if: steps.check.outputs.needs_bump == 'true' + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + cache-dependency-path: web/admin-spa/package-lock.json + + - name: Build Frontend + if: steps.check.outputs.needs_bump == 'true' + run: | + echo "Building frontend for version ${{ steps.next_version.outputs.new_version }}..." + cd web/admin-spa + npm ci + npm run build + echo "Frontend build completed" + + - name: Push Frontend Build to web-dist Branch + if: steps.check.outputs.needs_bump == 'true' + run: | + # 创建临时目录 + TEMP_DIR=$(mktemp -d) + echo "Using temp directory: $TEMP_DIR" + + # 复制构建产物到临时目录 + cp -r web/admin-spa/dist/* "$TEMP_DIR/" + + # 检查 web-dist 分支是否存在 + if git ls-remote --heads origin web-dist | grep -q web-dist; then + echo "Checking out existing web-dist branch" + git fetch origin web-dist:web-dist + git checkout web-dist + else + echo "Creating new web-dist branch" + git checkout --orphan web-dist + fi + + # 清空当前目录(保留 .git) + git rm -rf . 2>/dev/null || true + + # 复制构建产物 + cp -r "$TEMP_DIR"/* . + + # 添加 README + cat > README.md << EOF + # Claude Relay Service - Web Frontend Build + + This branch contains the pre-built frontend assets for Claude Relay Service. + + **DO NOT EDIT FILES IN THIS BRANCH DIRECTLY** + + These files are automatically generated by the CI/CD pipeline. + + Version: ${{ steps.next_version.outputs.new_version }} + Build Date: $(date -u +"%Y-%m-%d %H:%M:%S UTC") + EOF + + # 创建 .gitignore 文件以排除 node_modules + cat > .gitignore << EOF + node_modules/ + *.log + .DS_Store + .env + EOF + + # 只添加必要的文件,排除 node_modules + git add --all -- ':!node_modules' + git commit -m "chore: update frontend build for v${{ steps.next_version.outputs.new_version }} [skip ci]" + git push origin web-dist --force + + # 切换回主分支 + git checkout main + + # 清理临时目录 + rm -rf "$TEMP_DIR" + + echo "Frontend build pushed to web-dist branch successfully" + + - name: Install git-cliff + if: steps.check.outputs.needs_bump == 'true' + run: | + wget -q https://github.com/orhun/git-cliff/releases/download/v1.4.0/git-cliff-1.4.0-x86_64-unknown-linux-gnu.tar.gz + tar -xzf git-cliff-1.4.0-x86_64-unknown-linux-gnu.tar.gz + chmod +x git-cliff-1.4.0/git-cliff + sudo mv git-cliff-1.4.0/git-cliff /usr/local/bin/ + + - name: Generate changelog + if: steps.check.outputs.needs_bump == 'true' + id: changelog + run: | + # 获取上一个tag以来的更新日志 + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + if [ -n "$LATEST_TAG" ]; then + # 排除VERSION文件的提交 + CHANGELOG=$(git-cliff --config .github/cliff.toml $LATEST_TAG..HEAD --strip header | grep -v "bump version" | sed '/^$/d' || echo "- 代码优化和改进") + else + CHANGELOG=$(git-cliff --config .github/cliff.toml --strip header || echo "- 初始版本发布") + fi + echo "content<> $GITHUB_OUTPUT + echo "$CHANGELOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create and push tag + if: steps.check.outputs.needs_bump == 'true' + run: | + NEW_TAG="${{ steps.next_version.outputs.new_tag }}" + git tag -a "$NEW_TAG" -m "Release $NEW_TAG" + git push origin HEAD:main "$NEW_TAG" + + - name: Prepare image names + id: image_names + if: steps.check.outputs.needs_bump == 'true' + run: | + DOCKER_USERNAME="${{ secrets.DOCKERHUB_USERNAME }}" + if [ -z "$DOCKER_USERNAME" ]; then + DOCKER_USERNAME="weishaw" + fi + + DOCKER_IMAGE=$(echo "${DOCKER_USERNAME}/claude-relay-service" | tr '[:upper:]' '[:lower:]') + GHCR_IMAGE=$(echo "ghcr.io/${{ github.repository_owner }}/claude-relay-service" | tr '[:upper:]' '[:lower:]') + + { + echo "docker_image=${DOCKER_IMAGE}" + echo "ghcr_image=${GHCR_IMAGE}" + } >> "$GITHUB_OUTPUT" + + - name: Create GitHub Release + if: steps.check.outputs.needs_bump == 'true' + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.next_version.outputs.new_tag }} + name: Release ${{ steps.next_version.outputs.new_version }} + body: | + ## 🐳 Docker 镜像 + + ```bash + docker pull ${{ steps.image_names.outputs.docker_image }}:${{ steps.next_version.outputs.new_tag }} + docker pull ${{ steps.image_names.outputs.docker_image }}:latest + docker pull ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_tag }} + docker pull ${{ steps.image_names.outputs.ghcr_image }}:latest + ``` + + ## 📦 主要更新 + + ${{ steps.changelog.outputs.content }} + + ## 📋 完整更新日志 + + 查看 [所有版本](https://github.com/${{ github.repository }}/releases) + draft: false + prerelease: false + generate_release_notes: true + + # 自动清理旧的tags和releases(保持最近50个) + - name: Cleanup old tags and releases + if: steps.check.outputs.needs_bump == 'true' + continue-on-error: true + env: + TAGS_TO_KEEP: 50 + run: | + echo "🧹 自动清理旧版本,保持最近 $TAGS_TO_KEEP 个tag..." + + # 获取所有版本tag并按版本号排序(从旧到新) + echo "正在获取所有tags..." + ALL_TAGS=$(git ls-remote --tags origin | grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | awk '{print $2}' | sed 's|refs/tags/||' | sort -V) + + # 检查是否获取到tags + if [ -z "$ALL_TAGS" ]; then + echo "⚠️ 未找到任何版本tag" + exit 0 + fi + + TOTAL_COUNT=$(echo "$ALL_TAGS" | wc -l) + + echo "📊 当前tag统计:" + echo "- 总数: $TOTAL_COUNT" + echo "- 配置保留: $TAGS_TO_KEEP" + + if [ "$TOTAL_COUNT" -gt "$TAGS_TO_KEEP" ]; then + DELETE_COUNT=$((TOTAL_COUNT - TAGS_TO_KEEP)) + echo "- 将要删除: $DELETE_COUNT 个最旧的tag" + + # 获取要删除的tags(最老的) + TAGS_TO_DELETE=$(echo "$ALL_TAGS" | head -n "$DELETE_COUNT") + + # 显示将要删除的版本范围 + OLDEST_TO_DELETE=$(echo "$TAGS_TO_DELETE" | head -1) + NEWEST_TO_DELETE=$(echo "$TAGS_TO_DELETE" | tail -1) + echo "" + echo "🗑️ 将要删除的版本范围:" + echo "- 从: $OLDEST_TO_DELETE" + echo "- 到: $NEWEST_TO_DELETE" + + echo "" + echo "开始执行删除..." + SUCCESS_COUNT=0 + FAIL_COUNT=0 + + for tag in $TAGS_TO_DELETE; do + echo -n " 删除 $tag ... " - # 检查是否是需要忽略的文件 - if [[ ! "$file" =~ \.(md|txt)$ ]] && - [[ ! "$file" =~ ^docs/ ]] && - [[ ! "$file" =~ ^\.github/ ]] && - [[ "$file" != "VERSION" ]] && - [[ "$file" != ".gitignore" ]] && - [[ "$file" != "LICENSE" ]]; then - echo "Found significant change in: $file" - SIGNIFICANT_CHANGES=true - break - fi - done <<< "$CHANGED_FILES" - - # 检查是否是手动触发 - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - echo "Manual workflow trigger detected, forcing version bump" - echo "needs_bump=true" >> $GITHUB_OUTPUT - elif [ "$FORCE_RELEASE" = true ]; then - echo "Force release marker detected, forcing version bump" - echo "needs_bump=true" >> $GITHUB_OUTPUT - elif [ "$SIGNIFICANT_CHANGES" = true ]; then - echo "Significant changes detected, version bump needed" - echo "needs_bump=true" >> $GITHUB_OUTPUT - else - echo "No significant changes, skipping version bump" - echo "needs_bump=false" >> $GITHUB_OUTPUT - fi - - - name: Get current version - if: steps.check.outputs.needs_bump == 'true' - id: get_version - run: | - # 获取最新的tag版本 - LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - echo "Latest tag: $LATEST_TAG" - TAG_VERSION=${LATEST_TAG#v} - - # 获取VERSION文件中的版本 - FILE_VERSION=$(cat VERSION | tr -d '[:space:]') - echo "VERSION file: $FILE_VERSION" - - # 比较tag版本和文件版本,取较大值 - function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } - - if version_gt "$FILE_VERSION" "$TAG_VERSION"; then - VERSION="$FILE_VERSION" - echo "Using VERSION file: $VERSION (newer than tag)" - else - VERSION="$TAG_VERSION" - echo "Using tag version: $VERSION (newer or equal to file)" - fi - - echo "Current version: $VERSION" - echo "current_version=$VERSION" >> $GITHUB_OUTPUT - - - name: Calculate next version - if: steps.check.outputs.needs_bump == 'true' - id: next_version - run: | - VERSION="${{ steps.get_version.outputs.current_version }}" - - # 分割版本号 - IFS='.' read -r -a version_parts <<< "$VERSION" - MAJOR="${version_parts[0]:-0}" - MINOR="${version_parts[1]:-0}" - PATCH="${version_parts[2]:-0}" - - # 默认递增patch版本 - NEW_PATCH=$((PATCH + 1)) - NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" - - echo "New version: $NEW_VERSION" - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "new_tag=v$NEW_VERSION" >> $GITHUB_OUTPUT - - - name: Update VERSION file - if: steps.check.outputs.needs_bump == 'true' - run: | - echo "${{ steps.next_version.outputs.new_version }}" > VERSION - - # 配置git - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # 提交VERSION文件 - 添加 [skip ci] 以避免再次触发 - git add VERSION - git commit -m "chore: sync VERSION file with release ${{ steps.next_version.outputs.new_tag }} [skip ci]" - - # 构建前端并推送到 web-dist 分支 - - name: Setup Node.js - if: steps.check.outputs.needs_bump == 'true' - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - cache-dependency-path: web/admin-spa/package-lock.json - - - name: Build Frontend - if: steps.check.outputs.needs_bump == 'true' - run: | - echo "Building frontend for version ${{ steps.next_version.outputs.new_version }}..." - cd web/admin-spa - npm ci - npm run build - echo "Frontend build completed" - - - name: Push Frontend Build to web-dist Branch - if: steps.check.outputs.needs_bump == 'true' - run: | - # 创建临时目录 - TEMP_DIR=$(mktemp -d) - echo "Using temp directory: $TEMP_DIR" - - # 复制构建产物到临时目录 - cp -r web/admin-spa/dist/* "$TEMP_DIR/" - - # 检查 web-dist 分支是否存在 - if git ls-remote --heads origin web-dist | grep -q web-dist; then - echo "Checking out existing web-dist branch" - git fetch origin web-dist:web-dist - git checkout web-dist - else - echo "Creating new web-dist branch" - git checkout --orphan web-dist - fi - - # 清空当前目录(保留 .git) - git rm -rf . 2>/dev/null || true - - # 复制构建产物 - cp -r "$TEMP_DIR"/* . - - # 添加 README - cat > README.md << EOF - # Claude Relay Service - Web Frontend Build - - This branch contains the pre-built frontend assets for Claude Relay Service. - - **DO NOT EDIT FILES IN THIS BRANCH DIRECTLY** - - These files are automatically generated by the CI/CD pipeline. - - Version: ${{ steps.next_version.outputs.new_version }} - Build Date: $(date -u +"%Y-%m-%d %H:%M:%S UTC") - EOF - - # 创建 .gitignore 文件以排除 node_modules - cat > .gitignore << EOF - node_modules/ - *.log - .DS_Store - .env - EOF - - # 只添加必要的文件,排除 node_modules - git add --all -- ':!node_modules' - git commit -m "chore: update frontend build for v${{ steps.next_version.outputs.new_version }} [skip ci]" - git push origin web-dist --force - - # 切换回主分支 - git checkout main - - # 清理临时目录 - rm -rf "$TEMP_DIR" - - echo "Frontend build pushed to web-dist branch successfully" - - - name: Install git-cliff - if: steps.check.outputs.needs_bump == 'true' - run: | - wget -q https://github.com/orhun/git-cliff/releases/download/v1.4.0/git-cliff-1.4.0-x86_64-unknown-linux-gnu.tar.gz - tar -xzf git-cliff-1.4.0-x86_64-unknown-linux-gnu.tar.gz - chmod +x git-cliff-1.4.0/git-cliff - sudo mv git-cliff-1.4.0/git-cliff /usr/local/bin/ - - - name: Generate changelog - if: steps.check.outputs.needs_bump == 'true' - id: changelog - run: | - # 获取上一个tag以来的更新日志 - LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - if [ -n "$LATEST_TAG" ]; then - # 排除VERSION文件的提交 - CHANGELOG=$(git-cliff --config .github/cliff.toml $LATEST_TAG..HEAD --strip header | grep -v "bump version" | sed '/^$/d' || echo "- 代码优化和改进") - else - CHANGELOG=$(git-cliff --config .github/cliff.toml --strip header || echo "- 初始版本发布") - fi - echo "content<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create and push tag - if: steps.check.outputs.needs_bump == 'true' - run: | - NEW_TAG="${{ steps.next_version.outputs.new_tag }}" - git tag -a "$NEW_TAG" -m "Release $NEW_TAG" - git push origin HEAD:main "$NEW_TAG" - - - name: Prepare image names - id: image_names - if: steps.check.outputs.needs_bump == 'true' - run: | - # 只使用 GitHub Container Registry - GHCR_IMAGE=$(echo "ghcr.io/${{ github.repository_owner }}/claude-relay-service" | tr '[:upper:]' '[:lower:]') - - { - echo "ghcr_image=${GHCR_IMAGE}" - } >> "$GITHUB_OUTPUT" - - - name: Create GitHub Release - if: steps.check.outputs.needs_bump == 'true' - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.next_version.outputs.new_tag }} - name: Release ${{ steps.next_version.outputs.new_version }} - body: | - ## 🐳 Docker 镜像 (GHCR) - - ```bash - docker pull ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_tag }} - docker pull ${{ steps.image_names.outputs.ghcr_image }}:latest - ``` - - ## 📦 主要更新 - - ${{ steps.changelog.outputs.content }} - - ## 📋 完整更新日志 - - 查看 [所有版本](https://github.com/${{ github.repository }}/releases) - draft: false - prerelease: false - generate_release_notes: true - - # 自动清理旧的tags和releases(保持最近50个) - - name: Cleanup old tags and releases - if: steps.check.outputs.needs_bump == 'true' - continue-on-error: true - env: - TAGS_TO_KEEP: 50 - run: | - echo "🧹 自动清理旧版本,保持最近 $TAGS_TO_KEEP 个tag..." - - # 获取所有版本tag并按版本号排序(从旧到新) - echo "正在获取所有tags..." - ALL_TAGS=$(git ls-remote --tags origin | grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | awk '{print $2}' | sed 's|refs/tags/||' | sort -V) - - # 检查是否获取到tags - if [ -z "$ALL_TAGS" ]; then - echo "⚠️ 未找到任何版本tag" - exit 0 - fi - - TOTAL_COUNT=$(echo "$ALL_TAGS" | wc -l) - - echo "📊 当前tag统计:" - echo "- 总数: $TOTAL_COUNT" - echo "- 配置保留: $TAGS_TO_KEEP" - - if [ "$TOTAL_COUNT" -gt "$TAGS_TO_KEEP" ]; then - DELETE_COUNT=$((TOTAL_COUNT - TAGS_TO_KEEP)) - echo "- 将要删除: $DELETE_COUNT 个最旧的tag" - - # 获取要删除的tags(最老的) - TAGS_TO_DELETE=$(echo "$ALL_TAGS" | head -n "$DELETE_COUNT") - - # 显示将要删除的版本范围 - OLDEST_TO_DELETE=$(echo "$TAGS_TO_DELETE" | head -1) - NEWEST_TO_DELETE=$(echo "$TAGS_TO_DELETE" | tail -1) - echo "" - echo "🗑️ 将要删除的版本范围:" - echo "- 从: $OLDEST_TO_DELETE" - echo "- 到: $NEWEST_TO_DELETE" - - echo "" - echo "开始执行删除..." - SUCCESS_COUNT=0 - FAIL_COUNT=0 - - for tag in $TAGS_TO_DELETE; do - echo -n " 删除 $tag ... " - - # 先检查release是否存在 - if gh release view "$tag" >/dev/null 2>&1; then - # Release存在,删除release会同时删除tag - if gh release delete "$tag" --yes --cleanup-tag 2>/dev/null; then - echo "✅ (release+tag)" - SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) - else - echo "❌ (release删除失败)" - FAIL_COUNT=$((FAIL_COUNT + 1)) - fi + # 先检查release是否存在 + if gh release view "$tag" >/dev/null 2>&1; then + # Release存在,删除release会同时删除tag + if gh release delete "$tag" --yes --cleanup-tag 2>/dev/null; then + echo "✅ (release+tag)" + SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) else - # Release不存在,只删除tag - if git push origin --delete "$tag" 2>/dev/null; then - echo "✅ (仅tag)" - SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) - else - echo "⏭️ (已不存在)" - FAIL_COUNT=$((FAIL_COUNT + 1)) - fi + echo "❌ (release删除失败)" + FAIL_COUNT=$((FAIL_COUNT + 1)) fi - done - - echo "" - echo "📊 清理结果:" - echo "- 成功删除: $SUCCESS_COUNT" - echo "- 失败/跳过: $FAIL_COUNT" - - # 重新获取并显示保留的版本范围 - echo "" - echo "正在验证清理结果..." - REMAINING_TAGS=$(git ls-remote --tags origin | grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | awk '{print $2}' | sed 's|refs/tags/||' | sort -V) - REMAINING_COUNT=$(echo "$REMAINING_TAGS" | wc -l) - OLDEST=$(echo "$REMAINING_TAGS" | head -1) - NEWEST=$(echo "$REMAINING_TAGS" | tail -1) - - echo "✅ 清理完成!" - echo "" - echo "📌 当前保留的版本:" - echo "- 最旧版本: $OLDEST" - echo "- 最新版本: $NEWEST" - echo "- 版本总数: $REMAINING_COUNT" - - # 验证是否达到预期 - if [ "$REMAINING_COUNT" -le "$TAGS_TO_KEEP" ]; then - echo "- 状态: ✅ 符合预期(≤$TAGS_TO_KEEP)" else - echo "- 状态: ⚠️ 超出预期(某些tag可能删除失败)" + # Release不存在,只删除tag + if git push origin --delete "$tag" 2>/dev/null; then + echo "✅ (仅tag)" + SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) + else + echo "⏭️ (已不存在)" + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi fi + done + + echo "" + echo "📊 清理结果:" + echo "- 成功删除: $SUCCESS_COUNT" + echo "- 失败/跳过: $FAIL_COUNT" + + # 重新获取并显示保留的版本范围 + echo "" + echo "正在验证清理结果..." + REMAINING_TAGS=$(git ls-remote --tags origin | grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | awk '{print $2}' | sed 's|refs/tags/||' | sort -V) + REMAINING_COUNT=$(echo "$REMAINING_TAGS" | wc -l) + OLDEST=$(echo "$REMAINING_TAGS" | head -1) + NEWEST=$(echo "$REMAINING_TAGS" | tail -1) + + echo "✅ 清理完成!" + echo "" + echo "📌 当前保留的版本:" + echo "- 最旧版本: $OLDEST" + echo "- 最新版本: $NEWEST" + echo "- 版本总数: $REMAINING_COUNT" + + # 验证是否达到预期 + if [ "$REMAINING_COUNT" -le "$TAGS_TO_KEEP" ]; then + echo "- 状态: ✅ 符合预期(≤$TAGS_TO_KEEP)" else - echo "✅ 当前tag数量($TOTAL_COUNT)未超过限制($TAGS_TO_KEEP),无需清理" + echo "- 状态: ⚠️ 超出预期(某些tag可能删除失败)" fi + else + echo "✅ 当前tag数量($TOTAL_COUNT)未超过限制($TAGS_TO_KEEP),无需清理" + fi - # Docker构建步骤 - - name: Set up QEMU - if: steps.check.outputs.needs_bump == 'true' - uses: docker/setup-qemu-action@v3 + # Docker构建步骤 + - name: Set up QEMU + if: steps.check.outputs.needs_bump == 'true' + uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - if: steps.check.outputs.needs_bump == 'true' - uses: docker/setup-buildx-action@v3 + - name: Set up Docker Buildx + if: steps.check.outputs.needs_bump == 'true' + uses: docker/setup-buildx-action@v3 - - name: Log in to GitHub Container Registry - if: steps.check.outputs.needs_bump == 'true' - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Log in to Docker Hub + if: steps.check.outputs.needs_bump == 'true' + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push Docker image - if: steps.check.outputs.needs_bump == 'true' - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_tag }} - ${{ steps.image_names.outputs.ghcr_image }}:latest - ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_version }} - labels: | - org.opencontainers.image.version=${{ steps.next_version.outputs.new_version }} - org.opencontainers.image.revision=${{ github.sha }} - org.opencontainers.image.source=https://github.com/${{ github.repository }} - cache-from: type=gha - cache-to: type=gha,mode=max + - name: Log in to GitHub Container Registry + if: steps.check.outputs.needs_bump == 'true' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Send Telegram Notification - if: steps.check.outputs.needs_bump == 'true' && env.TELEGRAM_BOT_TOKEN != '' && env.TELEGRAM_CHAT_ID != '' - env: - TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} - TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} - GHCR_IMAGE: ${{ steps.image_names.outputs.ghcr_image }} - continue-on-error: true - run: | - VERSION="${{ steps.next_version.outputs.new_version }}" - TAG="${{ steps.next_version.outputs.new_tag }}" - REPO="${{ github.repository }}" + - name: Build and push Docker image + if: steps.check.outputs.needs_bump == 'true' + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ steps.image_names.outputs.docker_image }}:${{ steps.next_version.outputs.new_tag }} + ${{ steps.image_names.outputs.docker_image }}:latest + ${{ steps.image_names.outputs.docker_image }}:${{ steps.next_version.outputs.new_version }} + ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_tag }} + ${{ steps.image_names.outputs.ghcr_image }}:latest + ${{ steps.image_names.outputs.ghcr_image }}:${{ steps.next_version.outputs.new_version }} + labels: | + org.opencontainers.image.version=${{ steps.next_version.outputs.new_version }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.source=https://github.com/${{ github.repository }} + cache-from: type=gha + cache-to: type=gha,mode=max - # 获取更新内容并限制长度 - CHANGELOG="${{ steps.changelog.outputs.content }}" - CHANGELOG_TRUNCATED=$(echo "$CHANGELOG" | head -c 1000) - if [ ${#CHANGELOG} -gt 1000 ]; then - CHANGELOG_TRUNCATED="${CHANGELOG_TRUNCATED}..." - fi - - # 构建消息内容 - MESSAGE="🚀 *Claude Relay Service 新版本发布!*"$'\n'$'\n' - MESSAGE+="📦 版本号: \`${VERSION}\`"$'\n'$'\n' - MESSAGE+="📝 *更新内容:*"$'\n' - MESSAGE+="${CHANGELOG_TRUNCATED}"$'\n'$'\n' - MESSAGE+="🐳 *Docker 部署 (GHCR):*"$'\n' - MESSAGE+="\`\`\`bash"$'\n' - MESSAGE+="docker pull ${GHCR_IMAGE}:${TAG}"$'\n' - MESSAGE+="docker pull ${GHCR_IMAGE}:latest"$'\n' - MESSAGE+="\`\`\`"$'\n'$'\n' - MESSAGE+="🔗 *相关链接:*"$'\n' - MESSAGE+="• [GitHub Release](https://github.com/${REPO}/releases/tag/${TAG})"$'\n' - MESSAGE+="• [完整更新日志](https://github.com/${REPO}/releases)"$'\n' - MESSAGE+="• [GHCR](https://ghcr.io/${GHCR_IMAGE#ghcr.io/})"$'\n'$'\n' - MESSAGE+="#ClaudeRelay #Update #v${VERSION//./_}" - - # 使用 jq 构建 JSON 并发送 - jq -n \ - --arg chat_id "${TELEGRAM_CHAT_ID}" \ - --arg text "${MESSAGE}" \ - '{ - chat_id: $chat_id, - text: $text, - parse_mode: "Markdown", - disable_web_page_preview: false - }' | \ - curl -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ - -H "Content-Type: application/json" \ - -d @- + - name: Send Telegram Notification + if: steps.check.outputs.needs_bump == 'true' && env.TELEGRAM_BOT_TOKEN != '' && env.TELEGRAM_CHAT_ID != '' + env: + TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} + TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} + DOCKER_IMAGE: ${{ steps.image_names.outputs.docker_image }} + GHCR_IMAGE: ${{ steps.image_names.outputs.ghcr_image }} + continue-on-error: true + run: | + VERSION="${{ steps.next_version.outputs.new_version }}" + TAG="${{ steps.next_version.outputs.new_tag }}" + REPO="${{ github.repository }}" + + # 获取更新内容并限制长度 + CHANGELOG="${{ steps.changelog.outputs.content }}" + CHANGELOG_TRUNCATED=$(echo "$CHANGELOG" | head -c 1000) + if [ ${#CHANGELOG} -gt 1000 ]; then + CHANGELOG_TRUNCATED="${CHANGELOG_TRUNCATED}..." + fi + + # 构建消息内容 + MESSAGE="🚀 *Claude Relay Service 新版本发布!*"$'\n'$'\n' + MESSAGE+="📦 版本号: \`${VERSION}\`"$'\n'$'\n' + MESSAGE+="📝 *更新内容:*"$'\n' + MESSAGE+="${CHANGELOG_TRUNCATED}"$'\n'$'\n' + MESSAGE+="🐳 *Docker 部署:*"$'\n' + MESSAGE+="\`\`\`bash"$'\n' + MESSAGE+="docker pull ${DOCKER_IMAGE}:${TAG}"$'\n' + MESSAGE+="docker pull ${DOCKER_IMAGE}:latest"$'\n' + MESSAGE+="docker pull ${GHCR_IMAGE}:${TAG}"$'\n' + MESSAGE+="docker pull ${GHCR_IMAGE}:latest"$'\n' + MESSAGE+="\`\`\`"$'\n'$'\n' + MESSAGE+="🔗 *相关链接:*"$'\n' + MESSAGE+="• [GitHub Release](https://github.com/${REPO}/releases/tag/${TAG})"$'\n' + MESSAGE+="• [完整更新日志](https://github.com/${REPO}/releases)"$'\n' + MESSAGE+="• [Docker Hub](https://hub.docker.com/r/${DOCKER_IMAGE%/*}/claude-relay-service)"$'\n' + MESSAGE+="• [GHCR](https://ghcr.io/${GHCR_IMAGE#ghcr.io/})"$'\n'$'\n' + MESSAGE+="#ClaudeRelay #Update #v${VERSION//./_}" + + # 使用 jq 构建 JSON 并发送 + jq -n \ + --arg chat_id "${TELEGRAM_CHAT_ID}" \ + --arg text "${MESSAGE}" \ + '{ + chat_id: $chat_id, + text: $text, + parse_mode: "Markdown", + disable_web_page_preview: false + }' | \ + curl -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ + -H "Content-Type: application/json" \ + -d @- diff --git a/VERSION b/VERSION index 5de35b89..1b2d909c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.277 +1.1.274 diff --git a/config/models.js b/config/models.js index aaff30ea..4b2d2da7 100644 --- a/config/models.js +++ b/config/models.js @@ -32,7 +32,6 @@ const OPENAI_MODELS = [ { value: 'gpt-5.2', label: 'GPT-5.2' }, { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' }, { value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex' }, - { value: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark' }, { value: 'codex-mini', label: 'Codex Mini' } ] diff --git a/src/services/modelService.js b/src/services/modelService.js index 3e305272..5a6275a0 100644 --- a/src/services/modelService.js +++ b/src/services/modelService.js @@ -52,9 +52,7 @@ class ModelService { 'gpt-5.1-codex', 'gpt-5.1-codex-max', 'gpt-5-2025-08-07', - 'gpt-5-codex', - 'gpt-5.3-codex', - 'gpt-5.3-codex-spark' + 'gpt-5-codex' ] }, gemini: { diff --git a/src/services/relay/claudeConsoleRelayService.js b/src/services/relay/claudeConsoleRelayService.js index 1cd55329..d7dcabc1 100644 --- a/src/services/relay/claudeConsoleRelayService.js +++ b/src/services/relay/claudeConsoleRelayService.js @@ -19,68 +19,6 @@ class ClaudeConsoleRelayService { this.defaultUserAgent = 'claude-cli/2.0.52 (external, cli)' } - /** - * 🔄 转换 messages 数组中的 system role 消息 - * Console API 不支持 role="system",需要将 system 内容合并到第一条 user 消息 - * @param {Object} requestBody - 原始请求体 - * @returns {Object} 转换后的请求体 - */ - _transformSystemMessages(requestBody) { - if (!requestBody || !Array.isArray(requestBody.messages)) { - return requestBody - } - - // 收集所有 system messages 的内容 - const systemContents = [] - const nonSystemMessages = [] - - for (const msg of requestBody.messages) { - if (msg && msg.role === 'system') { - systemContents.push(msg.content) - } else { - nonSystemMessages.push(msg) - } - } - - // 如果没有 system messages,直接返回原请求 - if (systemContents.length === 0) { - return requestBody - } - - // 合并 system 内容到第一条 user 消息 - const systemText = systemContents.join('\n\n') - let transformedMessages = nonSystemMessages - - // 查找第一条 user 消息 - const firstUserIndex = nonSystemMessages.findIndex((m) => m && m.role === 'user') - - if (firstUserIndex !== -1) { - // 将 system 内容前置到第一条 user 消息 - const firstUserMsg = nonSystemMessages[firstUserIndex] - const mergedContent = `${systemText}\n\n${firstUserMsg.content}` - transformedMessages = [...nonSystemMessages] - transformedMessages[firstUserIndex] = { - ...firstUserMsg, - content: mergedContent - } - } else { - // 如果没有 user 消息,创建一个包含 system 内容的 user 消息 - logger.warn( - `⚠️ Console API: No user message found to merge system prompt, creating new user message with system content` - ) - transformedMessages = [{ role: 'user', content: systemText }, ...nonSystemMessages] - } - - logger.debug( - `🔄 Console API: Transformed ${systemContents.length} system message(s) into user message context` - ) - - return { - ...requestBody, - messages: transformedMessages - } - } - // 🚀 转发请求到Claude Console API async relayRequest( requestBody, @@ -225,9 +163,6 @@ class ClaudeConsoleRelayService { model: mappedModel } - // 🔄 转换 system messages (Console API 不支持 role="system") - const transformedRequestBody = this._transformSystemMessages(modifiedRequestBody) - // 模型兼容性检查已经在调度器中完成,这里不需要再检查 // 创建代理agent @@ -284,7 +219,7 @@ class ClaudeConsoleRelayService { const requestConfig = { method: 'POST', url: apiEndpoint, - data: transformedRequestBody, + data: modifiedRequestBody, headers: { 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01', @@ -714,9 +649,6 @@ class ClaudeConsoleRelayService { model: mappedModel } - // 🔄 转换 system messages (Console API 不支持 role="system") - const transformedRequestBody = this._transformSystemMessages(modifiedRequestBody) - // 模型兼容性检查已经在调度器中完成,这里不需要再检查 // 创建代理agent @@ -724,7 +656,7 @@ class ClaudeConsoleRelayService { // 发送流式请求 await this._makeClaudeConsoleStreamRequest( - transformedRequestBody, + modifiedRequestBody, account, proxyAgent, clientHeaders,