Merge branch 'dev' into docs-add-integration-lmstudio
This commit is contained in:
commit
db9ec320a3
40
.github/workflows/jan-server-build-nightly.yml
vendored
Normal file
40
.github/workflows/jan-server-build-nightly.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
name: Jan Build Docker Nightly or Manual
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- feature/helmchart-and-ci-jan-server
|
||||||
|
paths-ignore:
|
||||||
|
- 'README.md'
|
||||||
|
- 'docs/**'
|
||||||
|
schedule:
|
||||||
|
- cron: '0 20 * * 1,2,3' # At 8 PM UTC on Monday, Tuesday, and Wednesday which is 3 AM UTC+7 Tuesday, Wednesday, and Thursday
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Job create Update app version based on latest release tag with build number and save to output
|
||||||
|
get-update-version:
|
||||||
|
uses: ./.github/workflows/template-get-update-version.yml
|
||||||
|
|
||||||
|
build-cpu:
|
||||||
|
uses: ./.github/workflows/template-build-jan-server.yml
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
secrets: inherit
|
||||||
|
needs: [get-update-version]
|
||||||
|
with:
|
||||||
|
dockerfile_path: ./Dockerfile
|
||||||
|
docker_image_tag: "ghcr.io/janhq/jan-server:dev-cpu-latest,ghcr.io/janhq/jan-server:dev-cpu-${{ needs.get-update-version.outputs.new_version }}"
|
||||||
|
|
||||||
|
build-gpu:
|
||||||
|
uses: ./.github/workflows/template-build-jan-server.yml
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
secrets: inherit
|
||||||
|
needs: [get-update-version]
|
||||||
|
with:
|
||||||
|
dockerfile_path: ./Dockerfile.gpu
|
||||||
|
docker_image_tag: "ghcr.io/janhq/jan-server:dev-cuda-12.2-latest,ghcr.io/janhq/jan-server:dev-cuda-12.2-${{ needs.get-update-version.outputs.new_version }}"
|
||||||
|
|
||||||
|
|
||||||
30
.github/workflows/jan-server-build.yml
vendored
Normal file
30
.github/workflows/jan-server-build.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: Jan Build Docker
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Job create Update app version based on latest release tag with build number and save to output
|
||||||
|
get-update-version:
|
||||||
|
uses: ./.github/workflows/template-get-update-version.yml
|
||||||
|
|
||||||
|
build-cpu:
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
uses: ./.github/workflows/template-build-jan-server.yml
|
||||||
|
secrets: inherit
|
||||||
|
needs: [get-update-version]
|
||||||
|
with:
|
||||||
|
dockerfile_path: ./Dockerfile
|
||||||
|
docker_image_tag: "ghcr.io/janhq/jan-server:cpu-latest,ghcr.io/janhq/jan-server:cpu-${{ needs.get-update-version.outputs.new_version }}"
|
||||||
|
|
||||||
|
build-gpu:
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
uses: ./.github/workflows/template-build-jan-server.yml
|
||||||
|
secrets: inherit
|
||||||
|
needs: [get-update-version]
|
||||||
|
with:
|
||||||
|
dockerfile_path: ./Dockerfile.gpu
|
||||||
|
docker_image_tag: "ghcr.io/janhq/jan-server:cuda-12.2-latest,ghcr.io/janhq/jan-server:cuda-12.2-${{ needs.get-update-version.outputs.new_version }}"
|
||||||
39
.github/workflows/template-build-jan-server.yml
vendored
Normal file
39
.github/workflows/template-build-jan-server.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: build-jan-server
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
dockerfile_path:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: './Dockerfile'
|
||||||
|
docker_image_tag:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'ghcr.io/janhq/jan-server:dev-latest'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: janhq/jan-server
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ${{ inputs.dockerfile_path }}
|
||||||
|
push: true
|
||||||
|
tags: ${{ inputs.docker_image_tag }}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@
|
|||||||
error.log
|
error.log
|
||||||
node_modules
|
node_modules
|
||||||
*.tgz
|
*.tgz
|
||||||
|
!charts/server/charts/*.tgz
|
||||||
yarn.lock
|
yarn.lock
|
||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
|
|||||||
10
README.md
10
README.md
@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
|
|||||||
<tr style="text-align:center">
|
<tr style="text-align:center">
|
||||||
<td style="text-align:center"><b>Experimental (Nightly Build)</b></td>
|
<td style="text-align:center"><b>Experimental (Nightly Build)</b></td>
|
||||||
<td style="text-align:center">
|
<td style="text-align:center">
|
||||||
<a href='https://delta.jan.ai/latest/jan-win-x64-0.4.6-276.exe'>
|
<a href='https://delta.jan.ai/latest/jan-win-x64-0.4.6-279.exe'>
|
||||||
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
|
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
|
||||||
<b>jan.exe</b>
|
<b>jan.exe</b>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align:center">
|
<td style="text-align:center">
|
||||||
<a href='https://delta.jan.ai/latest/jan-mac-x64-0.4.6-276.dmg'>
|
<a href='https://delta.jan.ai/latest/jan-mac-x64-0.4.6-279.dmg'>
|
||||||
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
|
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
|
||||||
<b>Intel</b>
|
<b>Intel</b>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align:center">
|
<td style="text-align:center">
|
||||||
<a href='https://delta.jan.ai/latest/jan-mac-arm64-0.4.6-276.dmg'>
|
<a href='https://delta.jan.ai/latest/jan-mac-arm64-0.4.6-279.dmg'>
|
||||||
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
|
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
|
||||||
<b>M1/M2</b>
|
<b>M1/M2</b>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align:center">
|
<td style="text-align:center">
|
||||||
<a href='https://delta.jan.ai/latest/jan-linux-amd64-0.4.6-276.deb'>
|
<a href='https://delta.jan.ai/latest/jan-linux-amd64-0.4.6-279.deb'>
|
||||||
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
|
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
|
||||||
<b>jan.deb</b>
|
<b>jan.deb</b>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align:center">
|
<td style="text-align:center">
|
||||||
<a href='https://delta.jan.ai/latest/jan-linux-x86_64-0.4.6-276.AppImage'>
|
<a href='https://delta.jan.ai/latest/jan-linux-x86_64-0.4.6-279.AppImage'>
|
||||||
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
|
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
|
||||||
<b>jan.AppImage</b>
|
<b>jan.AppImage</b>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
6
charts/server/Chart.lock
Normal file
6
charts/server/Chart.lock
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
dependencies:
|
||||||
|
- name: common
|
||||||
|
repository: oci://ghcr.io/janhq/charts
|
||||||
|
version: 0.1.2
|
||||||
|
digest: sha256:35e98bde174130787755b0f8ea2359b7b6790d965a7157c2f7cabf1bc8c04471
|
||||||
|
generated: "2024-02-20T16:20:37.6530108+07:00"
|
||||||
10
charts/server/Chart.yaml
Normal file
10
charts/server/Chart.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: jan-server
|
||||||
|
description: A Helm chart for Kubernetes
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: '1.0.0'
|
||||||
|
dependencies:
|
||||||
|
- name: common
|
||||||
|
version: 0.1.2 # common-chart-version
|
||||||
|
repository: oci://ghcr.io/janhq/charts
|
||||||
BIN
charts/server/charts/common-0.1.2.tgz
Normal file
BIN
charts/server/charts/common-0.1.2.tgz
Normal file
Binary file not shown.
4
charts/server/config.json
Normal file
4
charts/server/config.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"image-list": "server=ghcr.io/janhq/jan-server",
|
||||||
|
"platforms": "linux/amd64"
|
||||||
|
}
|
||||||
256
charts/server/values.yaml
Normal file
256
charts/server/values.yaml
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
common:
|
||||||
|
imageTag: v0.4.6-cpu
|
||||||
|
# DO NOT CHANGE THE LINE ABOVE. MAKE ALL CHANGES BELOW
|
||||||
|
|
||||||
|
# Global pvc for all workload
|
||||||
|
pvc:
|
||||||
|
enabled: false
|
||||||
|
name: 'janroot'
|
||||||
|
accessModes: 'ReadWriteOnce'
|
||||||
|
storageClassName: ''
|
||||||
|
capacity: '50Gi'
|
||||||
|
|
||||||
|
# Global image pull secret
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
externalSecret:
|
||||||
|
create: false
|
||||||
|
name: ''
|
||||||
|
annotations: {}
|
||||||
|
|
||||||
|
nameOverride: 'jan-server'
|
||||||
|
fullnameOverride: 'jan-server'
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: 'jan-server-service-account'
|
||||||
|
|
||||||
|
podDisruptionBudget:
|
||||||
|
create: false
|
||||||
|
minAvailable: 1
|
||||||
|
|
||||||
|
workloads:
|
||||||
|
- name: server
|
||||||
|
image:
|
||||||
|
repository: ghcr.io/janhq/jan-server
|
||||||
|
pullPolicy: Always
|
||||||
|
|
||||||
|
command: ['/bin/sh', '-c']
|
||||||
|
args: ['cd server && node build/main.js']
|
||||||
|
|
||||||
|
replicaCount: 1
|
||||||
|
ports:
|
||||||
|
containerPort: 1337
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
canary:
|
||||||
|
steps:
|
||||||
|
- setWeight: 50
|
||||||
|
- pause: { duration: 1m }
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: 'nginx'
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: '100m'
|
||||||
|
nginx.ingress.kubernetes.io/proxy-read-timeout: '1800'
|
||||||
|
nginx.ingress.kubernetes.io/proxy-send-timeout: '1800'
|
||||||
|
# cert-manager.io/cluster-issuer: 'jan-ai-dns01-cluster-issuer'
|
||||||
|
# nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: HTTP
|
||||||
|
hosts:
|
||||||
|
- host: server.local
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
[]
|
||||||
|
# - hosts:
|
||||||
|
# - server-dev.jan.ai
|
||||||
|
# secretName: jan-server-prod-tls-v2
|
||||||
|
|
||||||
|
instrumentation:
|
||||||
|
enabled: false
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
|
||||||
|
securityContext: {}
|
||||||
|
|
||||||
|
service:
|
||||||
|
extenalLabel: {}
|
||||||
|
type: ClusterIP
|
||||||
|
port: 1337
|
||||||
|
targetPort: 1337
|
||||||
|
|
||||||
|
# If you want to use GPU, please uncomment the following lines and change imageTag to the one with GPU support
|
||||||
|
resources:
|
||||||
|
# limits:
|
||||||
|
# nvidia.com/gpu: 1
|
||||||
|
requests:
|
||||||
|
cpu: 2000m
|
||||||
|
memory: 8192M
|
||||||
|
|
||||||
|
# If you want to use pv, please uncomment the following lines and enable pvc.enabled
|
||||||
|
volumes:
|
||||||
|
[]
|
||||||
|
# - name: janroot
|
||||||
|
# persistentVolumeClaim:
|
||||||
|
# claimName: janroot
|
||||||
|
|
||||||
|
volumeMounts:
|
||||||
|
[]
|
||||||
|
# - name: janroot
|
||||||
|
# mountPath: /app/server/build/jan
|
||||||
|
|
||||||
|
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_BUCKET_NAME, AWS_ENDPOINT, AWS_REGION should mount as a secret env instead of plain text here
|
||||||
|
# Change API_BASE_URL to your server's public domain
|
||||||
|
env:
|
||||||
|
- name: API_BASE_URL
|
||||||
|
value: 'http://server.local'
|
||||||
|
|
||||||
|
lifecycle: {}
|
||||||
|
autoscaling:
|
||||||
|
enabled: false
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 3
|
||||||
|
targetCPUUtilizationPercentage: 95
|
||||||
|
targetMemoryUtilizationPercentage: 95
|
||||||
|
|
||||||
|
kedaScaling:
|
||||||
|
enabled: false # ignore if autoscaling.enable = true
|
||||||
|
cooldownPeriod: 30
|
||||||
|
pollingInterval: 2
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 5
|
||||||
|
metricName: celery_queue_length
|
||||||
|
query: celery_queue_length{queue_name="myqueue"} # change queue_name here
|
||||||
|
serverAddress: http://prometheus-prod-kube-prome-prometheus.monitoring.svc:9090
|
||||||
|
threshold: '3'
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
podSecurityGroup:
|
||||||
|
enabled: false
|
||||||
|
securitygroupid: []
|
||||||
|
|
||||||
|
# Reloader Option
|
||||||
|
reloader: 'false'
|
||||||
|
vpa:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
- name: web
|
||||||
|
image:
|
||||||
|
repository: ghcr.io/janhq/jan-server
|
||||||
|
pullPolicy: Always
|
||||||
|
|
||||||
|
command: ['/bin/sh', '-c']
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
'export NODE_ENV=production && yarn workspace jan-web build && cd web && npx serve out',
|
||||||
|
]
|
||||||
|
|
||||||
|
replicaCount: 1
|
||||||
|
ports:
|
||||||
|
containerPort: 3000
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
canary:
|
||||||
|
steps:
|
||||||
|
- setWeight: 50
|
||||||
|
- pause: { duration: 1m }
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: 'nginx'
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: '100m'
|
||||||
|
nginx.ingress.kubernetes.io/proxy-read-timeout: '1800'
|
||||||
|
nginx.ingress.kubernetes.io/proxy-send-timeout: '1800'
|
||||||
|
# cert-manager.io/cluster-issuer: 'jan-ai-dns01-cluster-issuer'
|
||||||
|
# nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: HTTP
|
||||||
|
hosts:
|
||||||
|
- host: web.local
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
[]
|
||||||
|
# - hosts:
|
||||||
|
# - server-dev.jan.ai
|
||||||
|
# secretName: jan-server-prod-tls-v2
|
||||||
|
|
||||||
|
instrumentation:
|
||||||
|
enabled: false
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
|
||||||
|
securityContext: {}
|
||||||
|
|
||||||
|
service:
|
||||||
|
extenalLabel: {}
|
||||||
|
type: ClusterIP
|
||||||
|
port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 2048M
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 500M
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
[]
|
||||||
|
# - name: janroot
|
||||||
|
# persistentVolumeClaim:
|
||||||
|
# claimName: janroot
|
||||||
|
|
||||||
|
volumeMounts:
|
||||||
|
[]
|
||||||
|
# - name: janroot
|
||||||
|
# mountPath: /app/server/build/jan
|
||||||
|
|
||||||
|
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_BUCKET_NAME, AWS_ENDPOINT, AWS_REGION should mount as a secret env instead of plain text here
|
||||||
|
# Change API_BASE_URL to your server's public domain
|
||||||
|
env:
|
||||||
|
- name: API_BASE_URL
|
||||||
|
value: 'http://server.local'
|
||||||
|
|
||||||
|
lifecycle: {}
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 3
|
||||||
|
targetCPUUtilizationPercentage: 95
|
||||||
|
targetMemoryUtilizationPercentage: 95
|
||||||
|
|
||||||
|
kedaScaling:
|
||||||
|
enabled: false # ignore if autoscaling.enable = true
|
||||||
|
cooldownPeriod: 30
|
||||||
|
pollingInterval: 2
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 5
|
||||||
|
metricName: celery_queue_length
|
||||||
|
query: celery_queue_length{queue_name="myqueue"} # change queue_name here
|
||||||
|
serverAddress: http://prometheus-prod-kube-prome-prometheus.monitoring.svc:9090
|
||||||
|
threshold: '3'
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
podSecurityGroup:
|
||||||
|
enabled: false
|
||||||
|
securitygroupid: []
|
||||||
|
|
||||||
|
# Reloader Option
|
||||||
|
reloader: 'false'
|
||||||
|
vpa:
|
||||||
|
enabled: false
|
||||||
@ -154,7 +154,10 @@ export default class JanInferenceNitroExtension extends InferenceExtension {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (nitroInitResult?.error) {
|
if (nitroInitResult?.error) {
|
||||||
events.emit(ModelEvent.OnModelFail, model)
|
events.emit(ModelEvent.OnModelFail, {
|
||||||
|
...model,
|
||||||
|
error: nitroInitResult.error,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -310,9 +310,15 @@ async function killSubprocess(): Promise<void> {
|
|||||||
subprocess?.kill()
|
subprocess?.kill()
|
||||||
subprocess = undefined
|
subprocess = undefined
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {}) // Do nothing with this attempt
|
||||||
.then(() => tcpPortUsed.waitUntilFree(PORT, 300, 5000))
|
.then(() => tcpPortUsed.waitUntilFree(PORT, 300, 5000))
|
||||||
.then(() => log(`[NITRO]::Debug: Nitro process is terminated`))
|
.then(() => log(`[NITRO]::Debug: Nitro process is terminated`))
|
||||||
|
.catch((err) => {
|
||||||
|
log(
|
||||||
|
`[NITRO]::Debug: Could not kill running process on port ${PORT}. Might be another process running on the same port? ${err}`
|
||||||
|
)
|
||||||
|
throw 'PORT_NOT_AVAILABLE'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -195,7 +195,12 @@ const DropdownListSidebar = ({
|
|||||||
</SelectValue>
|
</SelectValue>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectPortal>
|
<SelectPortal>
|
||||||
<SelectContent className="right-2 block w-full min-w-[450px] pr-0">
|
<SelectContent
|
||||||
|
className={twMerge(
|
||||||
|
'right-2 block w-full min-w-[450px] pr-0',
|
||||||
|
isTabActive === 1 && '[&_.select-scroll-down-button]:hidden'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="relative px-2 py-2 dark:bg-secondary/50">
|
<div className="relative px-2 py-2 dark:bg-secondary/50">
|
||||||
<ul className="inline-flex w-full space-x-2 rounded-lg bg-zinc-100 px-1 dark:bg-secondary">
|
<ul className="inline-flex w-full space-x-2 rounded-lg bg-zinc-100 px-1 dark:bg-secondary">
|
||||||
{engineOptions.map((name, i) => {
|
{engineOptions.map((name, i) => {
|
||||||
|
|||||||
@ -152,7 +152,7 @@ const BottomBar = () => {
|
|||||||
{gpus.length > 0 && (
|
{gpus.length > 0 && (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
<div className="flex cursor-pointer items-center">
|
<div className="flex items-center">
|
||||||
<SystemItem
|
<SystemItem
|
||||||
name={`${gpus.length} GPU `}
|
name={`${gpus.length} GPU `}
|
||||||
value={`${calculateUtilization()}% `}
|
value={`${calculateUtilization()}% `}
|
||||||
|
|||||||
@ -114,8 +114,8 @@ export default function EventHandler({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
const onModelInitFailed = useCallback(
|
const onModelInitFailed = useCallback(
|
||||||
(res: any) => {
|
(res: any) => {
|
||||||
const errorMessage = `${res.error}`
|
const errorMessage = res?.error ?? res
|
||||||
console.error('Failed to load model: ' + errorMessage)
|
console.error('Failed to load model: ', errorMessage)
|
||||||
setStateModel(() => ({
|
setStateModel(() => ({
|
||||||
state: 'start',
|
state: 'start',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import ModalTroubleShooting, {
|
|||||||
modalTroubleShootingAtom,
|
modalTroubleShootingAtom,
|
||||||
} from '@/containers/ModalTroubleShoot'
|
} from '@/containers/ModalTroubleShoot'
|
||||||
|
|
||||||
|
import { loadModelErrorAtom } from '@/hooks/useActiveModel'
|
||||||
import useSendChatMessage from '@/hooks/useSendChatMessage'
|
import useSendChatMessage from '@/hooks/useSendChatMessage'
|
||||||
|
|
||||||
import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
||||||
@ -15,6 +16,8 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => {
|
|||||||
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
const { resendChatMessage } = useSendChatMessage()
|
const { resendChatMessage } = useSendChatMessage()
|
||||||
const setModalTroubleShooting = useSetAtom(modalTroubleShootingAtom)
|
const setModalTroubleShooting = useSetAtom(modalTroubleShootingAtom)
|
||||||
|
const loadModelError = useAtomValue(loadModelErrorAtom)
|
||||||
|
const PORT_NOT_AVAILABLE = 'PORT_NOT_AVAILABLE'
|
||||||
|
|
||||||
const regenerateMessage = async () => {
|
const regenerateMessage = async () => {
|
||||||
const lastMessageIndex = messages.length - 1
|
const lastMessageIndex = messages.length - 1
|
||||||
@ -23,9 +26,9 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="mt-10">
|
||||||
{message.status === MessageStatus.Stopped && (
|
{message.status === MessageStatus.Stopped && (
|
||||||
<div key={message.id} className="mt-10 flex flex-col items-center">
|
<div key={message.id} className="flex flex-col items-center">
|
||||||
<span className="mb-3 text-center text-sm font-medium text-gray-500">
|
<span className="mb-3 text-center text-sm font-medium text-gray-500">
|
||||||
Oops! The generation was interrupted. Let's give it another go!
|
Oops! The generation was interrupted. Let's give it another go!
|
||||||
</span>
|
</span>
|
||||||
@ -41,6 +44,26 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{message.status === MessageStatus.Error && (
|
{message.status === MessageStatus.Error && (
|
||||||
|
<>
|
||||||
|
{loadModelError === PORT_NOT_AVAILABLE ? (
|
||||||
|
<div
|
||||||
|
key={message.id}
|
||||||
|
className="flex flex-col items-center text-center text-sm font-medium text-gray-500 w-full"
|
||||||
|
>
|
||||||
|
<p className="w-[90%]">
|
||||||
|
Port 3928 is currently unavailable. Check for conflicting apps,
|
||||||
|
or access
|
||||||
|
<span
|
||||||
|
className="cursor-pointer text-primary dark:text-blue-400"
|
||||||
|
onClick={() => setModalTroubleShooting(true)}
|
||||||
|
>
|
||||||
|
troubleshooting assistance
|
||||||
|
</span>
|
||||||
|
for further support.
|
||||||
|
</p>
|
||||||
|
<ModalTroubleShooting />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div
|
<div
|
||||||
key={message.id}
|
key={message.id}
|
||||||
className="flex flex-col items-center text-center text-sm font-medium text-gray-500"
|
className="flex flex-col items-center text-center text-sm font-medium text-gray-500"
|
||||||
@ -60,6 +83,8 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default ErrorMessage
|
export default ErrorMessage
|
||||||
|
|||||||
@ -197,7 +197,7 @@ const Sidebar: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
{activeThread?.assistants[0]?.tools &&
|
{activeThread?.assistants[0]?.tools &&
|
||||||
componentDataAssistantSetting.length > 0 && (
|
componentDataAssistantSetting.length > 0 && (
|
||||||
<CardSidebar title="Tools">
|
<CardSidebar title="Tools" isShow={true}>
|
||||||
<div className="px-2 pt-4">
|
<div className="px-2 pt-4">
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user