diff --git a/.github/workflows/jan-electron-build-beta.yml b/.github/workflows/jan-electron-build-beta.yml index 67496b3553..b29038b558 100644 --- a/.github/workflows/jan-electron-build-beta.yml +++ b/.github/workflows/jan-electron-build-beta.yml @@ -34,18 +34,8 @@ jobs: prerelease: false generate_release_notes: true - build-macos-x64: - uses: ./.github/workflows/template-build-macos-x64.yml - secrets: inherit - needs: [get-update-version] - with: - ref: ${{ github.ref }} - public_provider: github - new_version: ${{ needs.get-update-version.outputs.new_version }} - beta: true - - build-macos-arm64: - uses: ./.github/workflows/template-build-macos-arm64.yml + build-macos: + uses: ./.github/workflows/template-build-macos.yml secrets: inherit needs: [get-update-version] with: @@ -74,53 +64,14 @@ jobs: new_version: ${{ needs.get-update-version.outputs.new_version }} beta: true - combine-beta-mac-yml: - needs: [build-macos-x64, build-macos-arm64, create-draft-release, build-windows-x64, build-linux-x64] + sync-temp-to-latest: + needs: [build-macos, create-draft-release, build-windows-x64, build-linux-x64] runs-on: ubuntu-latest permissions: contents: write steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Download mac-x64 artifacts - uses: actions/download-artifact@v4 - with: - name: beta-mac-x64 - path: ./beta-mac-x64 - - name: Download mac-arm artifacts - uses: actions/download-artifact@v4 - with: - name: beta-mac-arm64 - path: ./beta-mac-arm64 - - - name: 'Merge beta-mac.yml' - # unfortunately electron-builder doesn't understand that we have two different releases for mac-x64 and mac-arm, so we need to manually merge the latest files - # see https://github.com/electron-userland/electron-builder/issues/5592 - run: | - ls -la . - ls -la ./beta-mac-x64 - ls -la ./beta-mac-arm64 - ls -la ./electron - cp ./electron/merge-latest-ymls.js /tmp/merge-beta-ymls.js - npm install js-yaml --prefix /tmp - node /tmp/merge-beta-ymls.js ./beta-mac-x64/beta-mac.yml ./beta-mac-arm64/beta-mac.yml ./beta-mac.yml - cat ./beta-mac.yml - - - name: Yet Another Upload Release Asset Action - uses: shogo82148/actions-upload-release-asset@v1.7.2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-draft-release.outputs.upload_url }} - asset_path: ./beta-mac.yml - asset_name: beta-mac.yml - asset_content_type: text/yaml - overwrite: true - - - name: Upload beta-mac.yml + - name: Sync temp to latest run: | - aws s3 cp ./beta-mac.yml "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-beta/beta-mac.yml" # sync temp-beta to beta by copy files that are different or new aws s3 sync "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-beta/" "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/beta/" env: @@ -136,7 +87,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} noti-discord-and-update-url-readme: - needs: [build-macos-x64, build-macos-arm64, create-draft-release, build-windows-x64, build-linux-x64, combine-beta-mac-yml] + needs: [build-macos, create-draft-release, build-windows-x64, build-linux-x64, sync-temp-to-latest] runs-on: ubuntu-latest steps: - name: Set version to environment variable @@ -149,8 +100,7 @@ jobs: args: | Jan-beta App version {{ VERSION }}, has been released, use the following links to download the app with faster speed or visit the Github release page for more information: - Windows: https://delta.jan.ai/beta/jan-beta-win-x64-{{ VERSION }}.exe - - macOS Intel: https://delta.jan.ai/beta/jan-beta-mac-x64-{{ VERSION }}.dmg - - macOS Apple Silicon: https://delta.jan.ai/beta/jan-beta-mac-arm64-{{ VERSION }}.dmg + - macOS Universal: https://delta.jan.ai/beta/jan-beta-mac-universal-{{ VERSION }}.dmg - Linux Deb: https://delta.jan.ai/beta/jan-beta-linux-amd64-{{ VERSION }}.deb - Linux AppImage: https://delta.jan.ai/beta/jan-beta-linux-x86_64-{{ VERSION }}.AppImage - Github Release URL: https://github.com/janhq/jan/releases/tag/v{{ VERSION }} diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index 73dc6524b0..60720052c8 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -42,17 +42,8 @@ jobs: get-update-version: uses: ./.github/workflows/template-get-update-version.yml - build-macos-x64: - uses: ./.github/workflows/template-build-macos-x64.yml - needs: [get-update-version, set-public-provider] - secrets: inherit - with: - ref: ${{ needs.set-public-provider.outputs.ref }} - public_provider: ${{ needs.set-public-provider.outputs.public_provider }} - new_version: ${{ needs.get-update-version.outputs.new_version }} - - build-macos-arm64: - uses: ./.github/workflows/template-build-macos-arm64.yml + build-macos: + uses: ./.github/workflows/template-build-macos.yml needs: [get-update-version, set-public-provider] secrets: inherit with: @@ -79,42 +70,13 @@ jobs: public_provider: ${{ needs.set-public-provider.outputs.public_provider }} new_version: ${{ needs.get-update-version.outputs.new_version }} - combine-latest-mac-yml: - needs: [set-public-provider, build-macos-x64, build-macos-arm64, build-windows-x64, build-linux-x64] + sync-temp-to-latest: + needs: [set-public-provider, build-windows-x64, build-linux-x64, build-macos] runs-on: ubuntu-latest steps: - - name: Getting the repo - uses: actions/checkout@v3 - with: - ref: ${{ needs.set-public-provider.outputs.ref }} - - name: Download mac-x64 artifacts - uses: actions/download-artifact@v4 - with: - name: latest-mac-x64 - path: ./latest-mac-x64 - - name: Download mac-arm artifacts - uses: actions/download-artifact@v4 - with: - name: latest-mac-arm64 - path: ./latest-mac-arm64 - - - name: 'Merge latest-mac.yml' - # unfortunately electron-builder doesn't understand that we have two different releases for mac-x64 and mac-arm, so we need to manually merge the latest files - # see https://github.com/electron-userland/electron-builder/issues/5592 - run: | - ls -la . - ls -la ./latest-mac-x64 - ls -la ./latest-mac-arm64 - ls -la ./electron - cp ./electron/merge-latest-ymls.js /tmp/merge-latest-ymls.js - npm install js-yaml --prefix /tmp - node /tmp/merge-latest-ymls.js ./latest-mac-x64/latest-mac.yml ./latest-mac-arm64/latest-mac.yml ./latest-mac.yml - cat ./latest-mac.yml - - - name: Upload latest-mac.yml + - name: Sync temp to latest if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }} run: | - aws s3 cp ./latest-mac.yml "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/latest-mac.yml" aws s3 sync s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/ s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/nightly/ env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} @@ -123,7 +85,7 @@ jobs: AWS_EC2_METADATA_DISABLED: "true" noti-discord-nightly-and-update-url-readme: - needs: [build-macos-x64, build-macos-arm64, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, combine-latest-mac-yml] + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] secrets: inherit if: github.event_name == 'schedule' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -134,7 +96,7 @@ jobs: new_version: ${{ needs.get-update-version.outputs.new_version }} noti-discord-pre-release-and-update-url-readme: - needs: [build-macos-x64, build-macos-arm64, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, combine-latest-mac-yml] + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] secrets: inherit if: github.event_name == 'push' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -145,7 +107,7 @@ jobs: new_version: ${{ needs.get-update-version.outputs.new_version }} noti-discord-manual-and-update-url-readme: - needs: [build-macos-x64, build-macos-arm64, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, combine-latest-mac-yml] + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] secrets: inherit if: github.event_name == 'workflow_dispatch' && github.event.inputs.public_provider == 'aws-s3' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml diff --git a/.github/workflows/jan-electron-build.yml b/.github/workflows/jan-electron-build.yml index 095c0ed200..3ca4a1fe28 100644 --- a/.github/workflows/jan-electron-build.yml +++ b/.github/workflows/jan-electron-build.yml @@ -33,17 +33,8 @@ jobs: draft: true prerelease: false - build-macos-x64: - uses: ./.github/workflows/template-build-macos-x64.yml - secrets: inherit - needs: [get-update-version] - with: - ref: ${{ github.ref }} - public_provider: github - new_version: ${{ needs.get-update-version.outputs.new_version }} - - build-macos-arm64: - uses: ./.github/workflows/template-build-macos-arm64.yml + build-macos: + uses: ./.github/workflows/template-build-macos.yml secrets: inherit needs: [get-update-version] with: @@ -69,52 +60,8 @@ jobs: public_provider: github new_version: ${{ needs.get-update-version.outputs.new_version }} - combine-latest-mac-yml: - needs: [build-macos-x64, build-macos-arm64, create-draft-release] - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Download mac-x64 artifacts - uses: actions/download-artifact@v4 - with: - name: latest-mac-x64 - path: ./latest-mac-x64 - - name: Download mac-arm artifacts - uses: actions/download-artifact@v4 - with: - name: latest-mac-arm64 - path: ./latest-mac-arm64 - - - name: 'Merge latest-mac.yml' - # unfortunately electron-builder doesn't understand that we have two different releases for mac-x64 and mac-arm, so we need to manually merge the latest files - # see https://github.com/electron-userland/electron-builder/issues/5592 - run: | - ls -la . - ls -la ./latest-mac-x64 - ls -la ./latest-mac-arm64 - ls -la ./electron - cp ./electron/merge-latest-ymls.js /tmp/merge-latest-ymls.js - npm install js-yaml --prefix /tmp - node /tmp/merge-latest-ymls.js ./latest-mac-x64/latest-mac.yml ./latest-mac-arm64/latest-mac.yml ./latest-mac.yml - cat ./latest-mac.yml - - - name: Yet Another Upload Release Asset Action - uses: shogo82148/actions-upload-release-asset@v1.7.2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-draft-release.outputs.upload_url }} - asset_path: ./latest-mac.yml - asset_name: latest-mac.yml - asset_content_type: text/yaml - overwrite: true - update_release_draft: - needs: [build-macos-x64, build-macos-arm64, build-windows-x64, build-linux-x64, combine-latest-mac-yml] + needs: [build-macos, build-windows-x64, build-linux-x64] permissions: # write permission is required to create a github release contents: write diff --git a/.github/workflows/template-build-macos-x64.yml b/.github/workflows/template-build-macos-x64.yml deleted file mode 100644 index 7781eb6301..0000000000 --- a/.github/workflows/template-build-macos-x64.yml +++ /dev/null @@ -1,210 +0,0 @@ -name: build-macos -on: - workflow_call: - inputs: - ref: - required: true - type: string - default: 'refs/heads/main' - public_provider: - required: true - type: string - default: none - description: 'none: build only, github: build and publish to github, aws s3: build and publish to aws s3' - new_version: - required: true - type: string - default: '' - aws_s3_prefix: - required: false - type: string - default: '/latest/' - beta: - required: false - type: boolean - default: false - secrets: - DELTA_AWS_S3_BUCKET_NAME: - required: false - DELTA_AWS_ACCESS_KEY_ID: - required: false - DELTA_AWS_SECRET_ACCESS_KEY: - required: false - CODE_SIGN_P12_BASE64: - required: false - CODE_SIGN_P12_PASSWORD: - required: false - APPLE_ID: - required: false - APPLE_APP_SPECIFIC_PASSWORD: - required: false - DEVELOPER_ID: - required: false - -jobs: - build-macos: - runs-on: macos-13 - environment: production - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - with: - ref: ${{ inputs.ref }} - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Update app version based on latest release tag with build number - if: inputs.public_provider != 'github' - run: | - echo "Version: ${{ inputs.new_version }}" - # Update the version in electron/package.json - jq --arg version "${{ inputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - - jq '.build.publish = [{"provider": "generic", "url": "https://delta.jan.ai/nightly", "channel": "latest"}, {"provider": "s3", "acl": null, "bucket": "${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}", "region": "${{ secrets.DELTA_AWS_REGION}}", "path": "temp-nightly", "channel": "latest"}]' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - cat electron/package.json - chmod +x .github/scripts/rename-app.sh - .github/scripts/rename-app.sh ./electron/package.json nightly - chmod +x .github/scripts/rename-workspace.sh - .github/scripts/rename-workspace.sh ./package.json nightly - echo "------------------------" - cat ./electron/package.json - echo "------------------------" - - - name: Change App Name for beta version - if: inputs.beta == true - shell: bash - run: | - chmod +x .github/scripts/rename-app.sh - .github/scripts/rename-app.sh ./electron/package.json beta - chmod +x .github/scripts/rename-workspace.sh - .github/scripts/rename-workspace.sh ./package.json beta - echo "------------------------" - cat ./electron/package.json - echo "------------------------" - cat ./package.json - jq '.build.publish = [{"provider": "generic", "url": "https://delta.jan.ai/beta", "channel": "beta"}, {"provider": "github", "owner": "janhq", "repo": "jan", "channel": "beta"}, {"provider": "s3", "acl": null, "bucket": "${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}", "region": "${{ secrets.DELTA_AWS_REGION}}", "path": "temp-beta", "channel": "beta"}]' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - cat electron/package.json - - - name: Update app version base on tag - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' - run: | - jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - cat electron/package.json - env: - VERSION_TAG: ${{ inputs.new_version }} - - - name: Get Cer for code signing - run: base64 -d <<< "$CODE_SIGN_P12_BASE64" > /tmp/codesign.p12 - shell: bash - env: - CODE_SIGN_P12_BASE64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - - - uses: apple-actions/import-codesign-certs@v2 - continue-on-error: true - with: - p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - - - name: Build and publish app to aws s3 r2 or github artifactory - if: inputs.public_provider != 'github' - run: | - # check public_provider is true or not - echo "public_provider is ${{ inputs.public_provider }}" - if [ "${{ inputs.public_provider }}" == "none" ]; then - make build - else - make build-and-publish - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: "/tmp/codesign.p12" - CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - CSC_IDENTITY_AUTO_DISCOVERY: "true" - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} - APP_PATH: "." - DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} - AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" - AWS_MAX_ATTEMPTS: "5" - - - name: Build and publish app to github - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' && inputs.beta == false - run: | - make build-and-publish - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: "/tmp/codesign.p12" - CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - CSC_IDENTITY_AUTO_DISCOVERY: "true" - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} - APP_PATH: "." - DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} - ANALYTICS_ID: ${{ secrets.JAN_APP_UMAMI_PROJECT_API_KEY }} - ANALYTICS_HOST: ${{ secrets.JAN_APP_UMAMI_URL }} - - - name: Build and publish app to github - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' && inputs.beta == true - run: | - make build-and-publish - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: "/tmp/codesign.p12" - CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - CSC_IDENTITY_AUTO_DISCOVERY: "true" - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} - APP_PATH: "." - DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} - AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" - AWS_MAX_ATTEMPTS: "5" - - - name: Upload Artifact - if: inputs.public_provider != 'github' - uses: actions/upload-artifact@v4 - with: - name: jan-mac-x64-${{ inputs.new_version }} - path: ./electron/dist/*.dmg - - - name: Upload Artifact - if: inputs.beta == false - uses: actions/upload-artifact@v4 - with: - name: latest-mac-x64 - path: ./electron/dist/latest-mac.yml - - - name: Upload Artifact - if: inputs.beta == true - uses: actions/upload-artifact@v4 - with: - name: beta-mac-x64 - path: ./electron/dist/beta-mac.yml \ No newline at end of file diff --git a/.github/workflows/template-build-macos-arm64.yml b/.github/workflows/template-build-macos.yml similarity index 94% rename from .github/workflows/template-build-macos-arm64.yml rename to .github/workflows/template-build-macos.yml index e618afb533..256bd8c5a6 100644 --- a/.github/workflows/template-build-macos-arm64.yml +++ b/.github/workflows/template-build-macos.yml @@ -192,19 +192,5 @@ jobs: if: inputs.public_provider != 'github' uses: actions/upload-artifact@v4 with: - name: jan-mac-arm64-${{ inputs.new_version }} + name: jan-mac-universal-${{ inputs.new_version }} path: ./electron/dist/*.dmg - - - name: Upload Artifact - if: inputs.beta == false - uses: actions/upload-artifact@v4 - with: - name: latest-mac-arm64 - path: ./electron/dist/latest-mac.yml - - - name: Upload Artifact - if: inputs.beta == true - uses: actions/upload-artifact@v4 - with: - name: beta-mac-arm64 - path: ./electron/dist/beta-mac.yml \ No newline at end of file diff --git a/.github/workflows/template-noti-discord-and-update-url-readme.yml b/.github/workflows/template-noti-discord-and-update-url-readme.yml index d799dacfac..59ad3c7be4 100644 --- a/.github/workflows/template-noti-discord-and-update-url-readme.yml +++ b/.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -48,8 +48,7 @@ jobs: args: | Jan App ${{ inputs.build_reason }} build artifact version {{ VERSION }}: - Windows: https://delta.jan.ai/nightly/jan-nightly-win-x64-{{ VERSION }}.exe - - macOS Intel: https://delta.jan.ai/nightly/jan-nightly-mac-x64-{{ VERSION }}.dmg - - macOS Apple Silicon: https://delta.jan.ai/nightly/jan-nightly-mac-arm64-{{ VERSION }}.dmg + - macOS Universal: https://delta.jan.ai/nightly/jan-nightly-mac-universal-{{ VERSION }}.dmg - Linux Deb: https://delta.jan.ai/nightly/jan-nightly-linux-amd64-{{ VERSION }}.deb - Linux AppImage: https://delta.jan.ai/nightly/jan-nightly-linux-x86_64-{{ VERSION }}.AppImage - Github action run: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }} diff --git a/Makefile b/Makefile index 0228c52d7b..e0750f3064 100644 --- a/Makefile +++ b/Makefile @@ -133,6 +133,7 @@ else ifeq ($(shell uname -s),Linux) find . -name ".turbo" -type d -exec rm -rf '{}' + find . -name "packake-lock.json" -type f -exec rm -rf '{}' + find . -name "yarn.lock" -type f -exec rm -rf '{}' + + find . -name "package-lock.json" -type f -exec rm -rf '{}' + rm -rf ./pre-install/*.tgz rm -rf ./extensions/*/*.tgz rm -rf ./electron/pre-install/*.tgz @@ -145,7 +146,7 @@ else find . -name "build" -type d -exec rm -rf '{}' + find . -name "out" -type d -exec rm -rf '{}' + find . -name ".turbo" -type d -exec rm -rf '{}' + - find . -name "packake-lock.json" -type f -exec rm -rf '{}' + + find . -name "package-lock.json" -type f -exec rm -rf '{}' + find . -name "yarn.lock" -type f -exec rm -rf '{}' + rm -rf ./pre-install/*.tgz rm -rf ./extensions/*/*.tgz diff --git a/core/src/browser/extensions/engines/OAIEngine.ts b/core/src/browser/extensions/engines/OAIEngine.ts index 694a872648..df51d37bb0 100644 --- a/core/src/browser/extensions/engines/OAIEngine.ts +++ b/core/src/browser/extensions/engines/OAIEngine.ts @@ -132,9 +132,6 @@ export abstract class OAIEngine extends AIEngine { events.emit(MessageEvent.OnMessageUpdate, message) }, error: async (err: any) => { - console.debug('inference url: ', this.inferenceUrl) - console.debug('header: ', header) - console.error(`Inference error:`, JSON.stringify(err)) if (this.isCancelled || message.content.length) { message.status = MessageStatus.Stopped events.emit(MessageEvent.OnMessageUpdate, message) diff --git a/core/src/browser/extensions/engines/helpers/sse.ts b/core/src/browser/extensions/engines/helpers/sse.ts index 0842675825..153d741da9 100644 --- a/core/src/browser/extensions/engines/helpers/sse.ts +++ b/core/src/browser/extensions/engines/helpers/sse.ts @@ -77,6 +77,11 @@ export function requestInference( const toParse = cachedLines + line if (!line.includes('data: [DONE]')) { const data = JSON.parse(toParse.replace('data: ', '')) + if ('error' in data) { + subscriber.error(data.error) + subscriber.complete() + return + } content += data.choices[0]?.delta?.content ?? '' if (content.startsWith('assistant: ')) { content = content.replace('assistant: ', '') diff --git a/docs/src/pages/docs/error-codes.mdx b/docs/src/pages/docs/error-codes.mdx index 65890c739b..7a3bde5806 100644 --- a/docs/src/pages/docs/error-codes.mdx +++ b/docs/src/pages/docs/error-codes.mdx @@ -81,7 +81,7 @@ These errors relate to the local API server's functionality. #### Error Types | Error Code | Cause | Solution | |------------|----------------------------------------|--------------------------------------------------------------| -| API-1 | Port 3928 is currently unavailable. | [Local API Server Guide](/docs/local-api#step-1-set-the-local-server) | +| API-1 | Port 39291 is currently unavailable. | [Local API Server Guide](/docs/local-api#step-1-set-the-local-server) | ### 8. Extensions and Integration Errors diff --git a/docs/src/pages/docs/troubleshooting.mdx b/docs/src/pages/docs/troubleshooting.mdx index d6725b2881..88cc39cbc3 100644 --- a/docs/src/pages/docs/troubleshooting.mdx +++ b/docs/src/pages/docs/troubleshooting.mdx @@ -368,23 +368,23 @@ When you start a chat with a model and encounter a Something's Amiss error, here 4. Confirm your V/RAM accessibility, mainly if using virtual RAM. 5. Nvidia GPU users should download [CUDA](https://developer.nvidia.com/cuda-downloads). 6. Linux users, ensure your system meets the requirements of gcc 11, g++ 11, cpp 11, or higher. Refer to this [link](#troubleshooting-nvidia-gpu) for details. -7. You might use the wrong port when you [check the app logs](#how-to-get-error-logs) and encounter the Bind address failed at 127.0.0.1:3928 error. To check the port status, try using the `netstat` command, like the following: +7. You might use the wrong port when you [check the app logs](#how-to-get-error-logs) and encounter the Bind address failed at 127.0.0.1:39291 error. To check the port status, try using the `netstat` command, like the following: ```bash - netstat -an | grep 3928 + netstat -an | grep 39291 ``` ```bash - netstat -ano | find "3928" - tasklist /fi "PID eq 3928" + netstat -ano | find "39291" + tasklist /fi "PID eq 39291" ``` ```bash - netstat -anpe | grep "3928" + netstat -anpe | grep "39291" ``` diff --git a/electron/package.json b/electron/package.json index 662a912f03..c4609e7af1 100644 --- a/electron/package.json +++ b/electron/package.json @@ -89,11 +89,11 @@ "build:test:darwin": "tsc -p . && electron-builder -p never -m --dir", "build:test:win32": "tsc -p . && electron-builder -p never -w --dir", "build:test:linux": "tsc -p . && electron-builder -p never -l --dir", - "build:darwin": "tsc -p . && electron-builder -p never -m", + "build:darwin": "tsc -p . && electron-builder -p never -m --universal", "build:win32": "tsc -p . && electron-builder -p never -w", "build:linux": "tsc -p . && electron-builder -p never -l deb -l AppImage", "build:publish": "yarn copy:assets && run-script-os", - "build:publish:darwin": "tsc -p . && electron-builder -p always -m", + "build:publish:darwin": "tsc -p . && electron-builder -p always -m --universal", "build:publish:win32": "tsc -p . && electron-builder -p always -w", "build:publish:linux": "tsc -p . && electron-builder -p always -l deb -l AppImage" }, diff --git a/extensions/assistant-extension/package.json b/extensions/assistant-extension/package.json index aa5dba6922..ff757cccec 100644 --- a/extensions/assistant-extension/package.json +++ b/extensions/assistant-extension/package.json @@ -9,9 +9,10 @@ "license": "AGPL-3.0", "scripts": { "clean:modules": "rimraf node_modules/pdf-parse/test && cd node_modules/pdf-parse/lib/pdf.js && rimraf v1.9.426 v1.10.88 v2.0.550", + "build-universal-hnswlib": "cd node_modules/hnswlib-node && arch -x86_64 npx node-gyp rebuild --arch=x64 && mv build/Release/addon.node ./addon-amd64.node && node-gyp rebuild --arch=arm64 && mv build/Release/addon.node ./addon-arm64.node && lipo -create -output build/Release/addon.node ./addon-arm64.node ./addon-amd64.node && rm ./addon-arm64.node && rm ./addon-amd64.node", "build": "yarn clean:modules && tsc --module commonjs && rollup -c rollup.config.ts", "build:publish:linux": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install", - "build:publish:darwin": "rimraf *.tgz --glob && yarn build && ../../.github/scripts/auto-sign.sh && npm pack && cpx *.tgz ../../pre-install", + "build:publish:darwin": "rimraf *.tgz --glob && yarn build-universal-hnswlib && yarn build && ../../.github/scripts/auto-sign.sh && npm pack && cpx *.tgz ../../pre-install", "build:publish:win32": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install", "build:publish": "run-script-os" }, diff --git a/extensions/inference-cortex-extension/package.json b/extensions/inference-cortex-extension/package.json index b0f20bae6a..507ab4ebc8 100644 --- a/extensions/inference-cortex-extension/package.json +++ b/extensions/inference-cortex-extension/package.json @@ -1,7 +1,7 @@ { "name": "@janhq/inference-cortex-extension", "productName": "Cortex Inference Engine", - "version": "1.0.23", + "version": "1.0.24", "description": "This extension embeds cortex.cpp, a lightweight inference engine written in C++. See https://jan.ai.\nAdditional dependencies could be installed to run without Cuda Toolkit installation.", "main": "dist/index.js", "node": "dist/node/index.cjs.js", diff --git a/extensions/inference-cortex-extension/resources/models/bakllava-1/model.json b/extensions/inference-cortex-extension/resources/models/bakllava-1/model.json index 391c939905..ccc8f693f5 100644 --- a/extensions/inference-cortex-extension/resources/models/bakllava-1/model.json +++ b/extensions/inference-cortex-extension/resources/models/bakllava-1/model.json @@ -21,7 +21,8 @@ "ctx_len": 4096, "prompt_template": "\n### Instruction:\n{prompt}\n### Response:\n", "llama_model_path": "ggml-model-q5_k.gguf", - "mmproj": "mmproj-model-f16.gguf" + "mmproj": "mmproj-model-f16.gguf", + "ngl": 33 }, "parameters": { "max_tokens": 4096 diff --git a/extensions/inference-cortex-extension/resources/models/llava-13b/model.json b/extensions/inference-cortex-extension/resources/models/llava-13b/model.json index 791c98749d..fe058e259a 100644 --- a/extensions/inference-cortex-extension/resources/models/llava-13b/model.json +++ b/extensions/inference-cortex-extension/resources/models/llava-13b/model.json @@ -21,7 +21,8 @@ "ctx_len": 4096, "prompt_template": "\n### Instruction:\n{prompt}\n### Response:\n", "llama_model_path": "llava-v1.6-vicuna-13b.Q4_K_M.gguf", - "mmproj": "mmproj-model-f16.gguf" + "mmproj": "mmproj-model-f16.gguf", + "ngl": 33 }, "parameters": { "max_tokens": 4096, diff --git a/extensions/inference-cortex-extension/resources/models/llava-7b/model.json b/extensions/inference-cortex-extension/resources/models/llava-7b/model.json index b22899c96e..8e5cdf09f1 100644 --- a/extensions/inference-cortex-extension/resources/models/llava-7b/model.json +++ b/extensions/inference-cortex-extension/resources/models/llava-7b/model.json @@ -21,7 +21,8 @@ "ctx_len": 4096, "prompt_template": "\n### Instruction:\n{prompt}\n### Response:\n", "llama_model_path": "llava-v1.6-mistral-7b.Q4_K_M.gguf", - "mmproj": "mmproj-model-f16.gguf" + "mmproj": "mmproj-model-f16.gguf", + "ngl": 33 }, "parameters": { "max_tokens": 4096, diff --git a/extensions/inference-cortex-extension/src/index.ts b/extensions/inference-cortex-extension/src/index.ts index 4e9ffd55a9..4cc322436d 100644 --- a/extensions/inference-cortex-extension/src/index.ts +++ b/extensions/inference-cortex-extension/src/index.ts @@ -334,13 +334,22 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { } }) + /** + * This is to handle the server segfault issue + */ this.socket.onclose = (event) => { console.log('WebSocket closed:', event) + // Notify app to update model running state events.emit(ModelEvent.OnModelStopped, {}) + + // Reconnect to the /events websocket if (this.shouldReconnect) { console.log(`Attempting to reconnect...`) setTimeout(() => this.subscribeToEvents(), 1000) } + + // Queue up health check + this.queue.add(() => this.healthz()) } resolve() diff --git a/web/containers/ErrorMessage/index.tsx b/web/containers/ErrorMessage/index.tsx index 4c97da14be..b2f6bc23af 100644 --- a/web/containers/ErrorMessage/index.tsx +++ b/web/containers/ErrorMessage/index.tsx @@ -52,7 +52,10 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => { ) default: return ( -

+

{message.content[0]?.text?.value && ( )} diff --git a/web/containers/ModelDropdown/index.tsx b/web/containers/ModelDropdown/index.tsx index 66a20a8542..dd6caa795c 100644 --- a/web/containers/ModelDropdown/index.tsx +++ b/web/containers/ModelDropdown/index.tsx @@ -187,15 +187,19 @@ const ModelDropdown = ({ ], }) - const overriddenSettings = - model?.settings.ctx_len && model.settings.ctx_len > 4096 - ? { ctx_len: 4096 } - : {} + const defaultContextLength = Math.min( + 8192, + model?.settings.ctx_len ?? 8192 + ) + const overriddenParameters = { + ctx_len: Math.min(8192, model?.settings.ctx_len ?? 8192), + max_tokens: defaultContextLength, + } const modelParams = { ...model?.parameters, ...model?.settings, - ...overriddenSettings, + ...overriddenParameters, } // Update model parameter to the thread state diff --git a/web/containers/Providers/ModelHandler.tsx b/web/containers/Providers/ModelHandler.tsx index b36f413b9b..373c0aebd6 100644 --- a/web/containers/Providers/ModelHandler.tsx +++ b/web/containers/Providers/ModelHandler.tsx @@ -134,7 +134,7 @@ export default function ModelHandler() { // Remove non-alphanumeric characters const cleanedMessageContent = messageContent - .replace(/[^a-z0-9\s]/gi, '') + .replace(/[^\p{L}\s]+/gu, '') .trim() // Split the message into words @@ -147,6 +147,9 @@ export default function ModelHandler() { return } + // Do not persist empty message + if (!cleanedMessageContent.trim().length) return + const updatedThread: Thread = { ...thread, diff --git a/web/hooks/useCreateNewThread.ts b/web/hooks/useCreateNewThread.ts index 75aa99c27c..999c887cbc 100644 --- a/web/hooks/useCreateNewThread.ts +++ b/web/hooks/useCreateNewThread.ts @@ -105,14 +105,21 @@ export const useCreateNewThread = () => { enabled: true, settings: assistant.tools && assistant.tools[0].settings, } - const overriddenSettings = - defaultModel?.settings.ctx_len && defaultModel.settings.ctx_len > 2048 - ? { ctx_len: 4096 } - : {} - - const overriddenParameters = defaultModel?.parameters.max_tokens - ? { max_tokens: 4096 } - : {} + + // Default context length is 8192 + const defaultContextLength = Math.min( + 8192, + defaultModel?.settings.ctx_len ?? 8192 + ) + + const overriddenSettings = { + ctx_len: defaultContextLength, + } + + // Use ctx length by default + const overriddenParameters = { + max_tokens: defaultContextLength, + } const createdAt = Date.now() let instructions: string | undefined = assistant.instructions diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index 815bdf116a..dc9a52f1be 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -10,7 +10,6 @@ import { ConversationalExtension, EngineManager, ToolManager, - ChatCompletionMessage, } from '@janhq/core' import { extractInferenceParams, extractModelLoadParams } from '@janhq/core' import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -21,7 +20,6 @@ import { fileUploadAtom, } from '@/containers/Providers/Jotai' -import { Stack } from '@/utils/Stack' import { compressImage, getBase64 } from '@/utils/base64' import { MessageRequestBuilder } from '@/utils/messageRequestBuilder' @@ -86,33 +84,6 @@ export default function useSendChatMessage() { selectedModelRef.current = selectedModel }, [selectedModel]) - const normalizeMessages = ( - messages: ChatCompletionMessage[] - ): ChatCompletionMessage[] => { - const stack = new Stack() - for (const message of messages) { - if (stack.isEmpty()) { - stack.push(message) - continue - } - const topMessage = stack.peek() - - if (message.role === topMessage.role) { - // add an empty message - stack.push({ - role: - topMessage.role === ChatCompletionRole.User - ? ChatCompletionRole.Assistant - : ChatCompletionRole.User, - content: '.', // some model requires not empty message - }) - } - stack.push(message) - } - - return stack.reverseOutput() - } - const resendChatMessage = async (currentMessage: ThreadMessage) => { // Delete last response before regenerating const newConvoData = currentMessages @@ -247,7 +218,6 @@ export default function useSendChatMessage() { (assistant) => assistant.tools ?? [] ) ?? [] ) - request.messages = normalizeMessages(request.messages ?? []) // Request for inference EngineManager.instance() diff --git a/web/package.json b/web/package.json index 6954a23bbc..e0f8558826 100644 --- a/web/package.json +++ b/web/package.json @@ -38,7 +38,7 @@ "react-icons": "^4.12.0", "react-markdown": "^9.0.1", "react-toastify": "^9.1.3", - "rehype-highlight": "^6.0.0", + "rehype-highlight": "^7.0.1", "rehype-highlight-code-lines": "^1.0.4", "rehype-katex": "^7.0.1", "rehype-raw": "^7.0.0", diff --git a/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx index ec5875bcb9..9077a351ac 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx @@ -14,9 +14,11 @@ import LoadModelError from '../LoadModelError' import EmptyThread from './EmptyThread' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' +import { activeThreadAtom } from '@/helpers/atoms/Thread.atom' const ChatConfigurator = memo(() => { const messages = useAtomValue(getCurrentChatMessagesAtom) + const currentThread = useAtomValue(activeThreadAtom) const [current, setCurrent] = useState([]) const loadModelError = useAtomValue(loadModelErrorAtom) @@ -31,12 +33,12 @@ const ChatConfigurator = memo(() => { useEffect(() => { if ( - messages?.length !== current?.length || - !isMessagesIdentificial(messages, current) + !isMessagesIdentificial(messages, current) || + messages.some((e) => e.thread_id !== currentThread?.id) ) { setCurrent(messages) } - }, [messages, current, loadModelError]) + }, [messages, current, loadModelError, currentThread]) if (!messages.length) return return ( @@ -119,7 +121,7 @@ const ChatBody = memo( > {items.map((virtualRow) => (

diff --git a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx index 10d4082113..1fa3ef1155 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx @@ -54,7 +54,12 @@ const ChatItem = forwardRef((message, ref) => { <> {status !== MessageStatus.Error && content?.length > 0 && (
- +
)} {errorMessage && !message.loadModelError && ( diff --git a/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx b/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx index 569e93d62b..d6fed48043 100644 --- a/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx @@ -49,7 +49,9 @@ const LoadModelError = () => { } else { return (
- {loadModelError &&

{loadModelError}

} + {loadModelError && ( +

{loadModelError}

+ )}

{`Something's wrong.`} Access  = (props) => { +const MessageContainer: React.FC< + ThreadMessage & { isCurrentMessage: boolean } +> = (props) => { const isUser = props.role === ChatCompletionRole.User const isSystem = props.role === ChatCompletionRole.System const editMessage = useAtomValue(editMessageAtom) const activeThread = useAtomValue(activeThreadAtom) - const tokenSpeed = useAtomValue(tokenSpeedAtom) - const messages = useAtomValue(getCurrentChatMessagesAtom) const text = useMemo( () => props.content[0]?.text?.value ?? '', @@ -81,16 +80,6 @@ const MessageContainer: React.FC = (props) => {

{displayDate(props.created)}

-
- -
{tokenSpeed && tokenSpeed.message === props.id && tokenSpeed.tokenSpeed > 0 && ( @@ -100,39 +89,52 @@ const MessageContainer: React.FC = (props) => { )}
-
- <> - {messageType === ContentType.Image && ( - +
+
+ > + +
+
+ <> + {messageType === ContentType.Image && ( + + )} + {messageType === ContentType.Pdf && ( + + )} - {editMessage === props.id ? ( -
- -
- ) : ( -
- -
- )} - + {editMessage === props.id ? ( +
+ +
+ ) : ( +
+ +
+ )} + +
) diff --git a/web/utils/messageRequestBuilder.ts b/web/utils/messageRequestBuilder.ts index 949b4405ca..3153a7e3eb 100644 --- a/web/utils/messageRequestBuilder.ts +++ b/web/utils/messageRequestBuilder.ts @@ -15,6 +15,8 @@ import { ulid } from 'ulidx' import { FileType } from '@/containers/Providers/Jotai' +import { Stack } from '@/utils/Stack' + export class MessageRequestBuilder { msgId: string type: MessageRequestType @@ -36,7 +38,7 @@ export class MessageRequestBuilder { .filter((e) => e.status !== MessageStatus.Error) .map((msg) => ({ role: msg.role, - content: msg.content[0]?.text.value ?? '', + content: msg.content[0]?.text.value ?? '.', })) } @@ -130,12 +132,39 @@ export class MessageRequestBuilder { return this } + normalizeMessages = ( + messages: ChatCompletionMessage[] + ): ChatCompletionMessage[] => { + const stack = new Stack() + for (const message of messages) { + if (stack.isEmpty()) { + stack.push(message) + continue + } + const topMessage = stack.peek() + + if (message.role === topMessage.role) { + // add an empty message + stack.push({ + role: + topMessage.role === ChatCompletionRole.User + ? ChatCompletionRole.Assistant + : ChatCompletionRole.User, + content: '.', // some model requires not empty message + }) + } + stack.push(message) + } + + return stack.reverseOutput() + } + build(): MessageRequest { return { id: this.msgId, type: this.type, threadId: this.thread.id, - messages: this.messages, + messages: this.normalizeMessages(this.messages), model: this.model, thread: this.thread, }