Merge branch 'main' into fix/spec_assistants_v1

This commit is contained in:
0xSage 2023-11-24 16:57:04 +08:00 committed by GitHub
commit 51f9fcc2b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1533 additions and 9999 deletions

View File

@ -5,8 +5,34 @@ on:
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
jobs:
create-draft-release:
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
version: ${{ steps.get_version.outputs.version }}
permissions:
contents: write
steps:
- name: Extract tag name without v prefix
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
env:
GITHUB_REF: ${{ github.ref }}
- name: Create Draft Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: "${{ env.VERSION }}"
draft: true
prerelease: false
build-macos:
runs-on: macos-latest
needs: create-draft-release
environment: production
permissions:
contents: write
@ -28,7 +54,12 @@ jobs:
- name: Update app version base on tag
run: |
make update-app-version
if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Tag is not valid!"
exit 1
fi
jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json
mv /tmp/package.json electron/package.json
env:
VERSION_TAG: ${{ steps.tag.outputs.tag }}
@ -59,6 +90,7 @@ jobs:
build-windows-x64:
runs-on: windows-latest
needs: create-draft-release
permissions:
contents: write
steps:
@ -80,18 +112,71 @@ jobs:
- name: Update app version base on tag
shell: bash
run: |
make update-app-version
if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Tag is not valid!"
exit 1
fi
jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json
mv /tmp/package.json electron/package.json
env:
VERSION_TAG: ${{ steps.tag.outputs.tag }}
- name: Build and publish app
- name: Build uikit
run: |
make build-and-publish
cd uikit
yarn config set network-timeout 300000
yarn install
yarn build
- name: Install yarn dependencies
shell: powershell
run: |
yarn config set network-timeout 300000
yarn build:core
yarn install
$env:NITRO_VERSION = Get-Content .\plugins\inference-plugin\nitro\version.txt; echo $env:NITRO_VERSION
yarn build:plugins
yarn build
- name: Windows Code Sign with AzureSignTool
run: |
dotnet tool install --global AzureSignTool
cd ./electron/dist
azuresigntool.exe sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v "jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe"
- uses: actions/upload-release-asset@v1.0.1
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-draft-release.outputs.upload_url }}
asset_path: ./electron/dist/jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe
asset_name: jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe
asset_content_type: application/octet-stream
- uses: actions/upload-release-asset@v1.0.1
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-draft-release.outputs.upload_url }}
asset_path: ./electron/dist/jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe.blockmap
asset_name: jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe.blockmap
asset_content_type: text/xml
- uses: actions/upload-release-asset@v1.0.1
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-draft-release.outputs.upload_url }}
asset_path: ./electron/dist/latest.yml
asset_name: latest.yml
asset_content_type: text/yaml
build-linux-x64:
runs-on: ubuntu-latest
needs: create-draft-release
environment: production
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
@ -118,7 +203,12 @@ jobs:
- name: Update app version base on tag
run: |
make update-app-version
if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Tag is not valid!"
exit 1
fi
jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json
mv /tmp/package.json electron/package.json
env:
VERSION_TAG: ${{ steps.tag.outputs.tag }}
@ -129,7 +219,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update_release_draft:
needs: [build-macos, build-windows-x64, build-linux-x64]
needs: [build-macos, build-windows-x64, build-linux-x64, create-draft-release]
permissions:
# write permission is required to create a github release
contents: write

View File

@ -11,14 +11,6 @@ ifeq ($(OS),Windows_NT)
else
cd uikit && yarn install && yarn build
endif
# Updates the app version based on the tag
update-app-version:
if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then \
echo "Error: Tag is not valid!"; \
exit 1; \
fi
jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json
mv /tmp/package.json electron/package.json
# Installs yarn dependencies and builds core and plugins
install-and-build: build-uikit

View File

@ -0,0 +1,5 @@
---
title: Community
---
- [ ] Social media links

View File

@ -2,15 +2,29 @@
title: Linux
---
# Jan on Linux
# Installing Jan on Linux
## Installation
1. To download the lastest version of Jan on Linux, please visit the [Jan's homepage](https://jan.ai/).
2. For Debian/Ubuntu-based distributions, the recommended installation method is through the `.deb` package (64-bit). This can be done either through the graphical software center, if available, or via the command line using the following:
Jan is available for download via our homepage, [https://jan.ai](https://jan.ai/).
For Linux, the download should be available as a `.deb` file in the following format.
```bash
sudo apt install ./jan-linux-amd64-<version>.deb
# sudo apt install ./jan-linux-arm64-0.3.1.deb
jan-linux-amd64-{version}.deb
```
The typical installation process takes around a minute.
### GitHub Releases
Jan is also available from [Jan's GitHub Releases](https://github.com/janhq/jan/releases) page, with a recommended [latest stable release](https://github.com/janhq/jan/releases/latest).
Within the Releases' assets, you will find the following files for Linux:
```bash
# Debian Linux distribution
jan-linux-amd64-{version}.deb
```
## Uninstall Jan

View File

@ -2,13 +2,37 @@
title: Mac
---
# Jan on MacOS
# Installing Jan on MacOS
## Installation
1. To download the lastest version of Jan on MacOS, please visit the [Jan's homepage](https://jan.ai/).
2. On the homepage, please choose the appropriate release version for your system architecture as follows:
- Intel Mac: `jan-mac-x64-<version>.dmg`
- Apple Silicon Mac: `jan-mac-arm64-<version>.dmg`
Jan is available for download via our homepage, [https://jan.ai/](https://jan.ai/).
For MacOS, the download should be available as a `.dmg` file in the following format.
```bash
# Intel Mac
jan-mac-x64-{version}.dmg
# Apple Silicon Mac
jan-mac-arm64-{version}.dmg
```
The typical installation process taks around a minute.
## GitHub Releases
Jan is also available from [Jan's GitHub Releases](https://github.com/janhq/jan/releases) page, with a recommended [latest stable release](https://github.com/janhq/jan/releases/latest).
Within the Releases' assets, you will find the following files for MacOS:
```bash
# Intel Mac (dmg file and zip file)
jan-mac-x64-{version}.dmg
jan-mac-x64-{version}.zip
# Apple Silicon Mac (dmg file and zip file)
jan-mac-arm64-{version}.dmg
jan-mac-arm64-{version}.zip
```
## Uninstall Jan
As Jan is development mode, you might get stuck on a broken build

View File

@ -16,9 +16,9 @@ jan-win-x64-{version}.exe
The typical installation process takes around a minute.
### Github Releases
### GitHub Releases
Jan is also available from [Jan's Github Releases](https://github.com/janhq/jan/releases) page, with a recommended [latest stable release](https://github.com/janhq/jan/releases/latest).
Jan is also available from [Jan's GitHub Releases](https://github.com/janhq/jan/releases) page, with a recommended [latest stable release](https://github.com/janhq/jan/releases/latest).
Within the Releases' assets, you will find the following files for Windows:

View File

@ -1,6 +1,6 @@
---
title: Introduction
slug: /intro
slug: /docs
---
Jan is a ChatGPT-alternative that runs on your own computer, with a [local API server](/api).

View File

@ -2,15 +2,29 @@
title: Chats
---
:::warning
:::caution
This page is still under construction, and should be read as a scratchpad
This is currently under development.
:::
Chats are essentially inference requests to a model
## Overview
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/chat
In Jan, `chats` are LLM responses in the form of OpenAI compatible `chat completion objects`.
- This should reference Nitro ChatCompletion API page to reduce duplication.
- We are fine with adding Jan API for this but it makes sense to use Nitro as reference as Nitro is default inference engine for Jan in this release
- Models take a list of messages and return a model-generated response as output.
- An [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) compatible endpoint at `localhost:3000/v1/chats`.
## Folder Structure
Chats are stateless, thus are not saved in `janroot`. Any content and relevant metadata from calling this endpoint is extracted and persisted through [Messages](/specs/messages).
## API Reference
Jan's Chat API is compatible with [OpenAI's Chat API](https://platform.openai.com/docs/api-reference/chat).
See [Jan Chat API](https://jan.ai/api-reference/#tag/Chat-Completion)
## Implementation
Under the hood, the `/chat` endpoint simply reroutes an existing endpoint from [Nitro server](https://nitro.jan.ai). Nitro is a lightweight & local inference server, written in C++ and embedded into the Jan app. See [Nitro documentation](https://nitro.jan.ai/docs).

View File

@ -8,66 +8,36 @@ This page is still under construction, and should be read as a scratchpad
:::
```sh
janroot/
assistants/
assistant-a/
assistant.json
src/
index.ts
threads/
thread-a/
thread-b
models/
model-a/
model.json
```
Jan use the local filesystem for data persistence, similar to VSCode. This allows for composability and tinkerability.
```sh=
/janroot # Jan's root folder (e.g. ~/jan)
/models # For raw AI models
/threads # For conversation history
/assistants # For AI assistants' configs, knowledge, etc.
```yaml
janroot/ # Jan's root folder (e.g. ~/jan)
models/ # For raw AI models
threads/ # For conversation history
assistants/ # For AI assistants' configs, knowledge, etc.
```
```sh=
```yaml
/models
/modelA
model.json # Default model settings
llama-7b-q4.gguf # Model binaries
llama-7b-q5.gguf # Include different quantizations
/threads
/jan-unixstamp-salt
model.json # Overrides assistant/model-level model settings
/jan-unixstamp
thread.json # thread metadata (e.g. subject)
messages.json # messages
content.json # What is this?
files/ # Future for RAG
messages.jsonl # messages
files/ # RAG
/assistants
/jan
/jan # A default assistant that can use all models
assistant.json # Assistant configs (see below)
# For any custom code
package.json # Import npm modules
# e.g. Langchain, Llamaindex
/src # Supporting files (needs better name)
package.json # Import npm modules, e.g. Langchain, Llamaindex
/src # For custom code
index.js # Entrypoint
process.js # For electron IPC processes (needs better name)
# `/threads` at root level
# `/models` at root level
/shakespeare
# `/threads` at root level
# `/models` at root level
/shakespeare # Example of a custom assistant
assistant.json
model.json # Creator chooses model and settings
package.json
/src
index.js
process.js
/threads # Assistants remember conversations in the future
/models # Users can upload custom models
/finetuned-model
```

View File

@ -4,7 +4,7 @@ title: "Files"
:::warning
Draft Specification: functionality has not been implemented yet.
Draft Specification: functionality has not been implemented yet.
:::
@ -18,7 +18,7 @@ Files can be used by `threads`, `assistants` and `fine-tuning`
- Note: OAI's struct doesn't seem very well designed
- `files.json`
```json
```js
{
// Public properties (OpenAI Compatible: https://platform.openai.com/docs/api-reference/files/object)
"id": "file-BK7bzQj3FfZFXr7DbL6xJwfo",
@ -31,19 +31,25 @@ Files can be used by `threads`, `assistants` and `fine-tuning`
```
## File API
### List Files
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/files/list
### Upload file
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/files/create
### Delete file
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/files/delete
### Retrieve file
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/files/retrieve
### Retrieve file content
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/files/retrieve-contents
## Files Filesystem

3
docs/docs/specs/home.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Home
---

3
docs/docs/specs/hub.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Hub
---

View File

@ -13,28 +13,25 @@ This is currently under development.
`Messages` capture a conversation's content. This can include the content from LLM responses and other metadata from [chat completions](/specs/chats).
- Users and assistants can send multimedia messages.
- An [OpenAI Message API](https://platform.openai.com/docs/api-reference/messages) compatible endpoint at `localhost:3000/v1/messages`.
- An [OpenAI Message API](https://platform.openai.com/docs/api-reference/messages) compatible endpoint at `localhost:1337/v1/messages`.
## Folder Structure
Messages are saved in the `/threads/{thread_id}` folder in `messages.jsonl` files
```sh
```yaml
jan/
threads/
assistant_name_unix_timestamp/
...
messages.jsonl
jan_2341243134/
...
messages.jsonl
thread.json # Thread metadata
messages.jsonl # Messages are stored in jsonl format
```
## `message.jsonl`
Individual messages are saved in `jsonl` format for indexing purposes.
```json
```js
{...message_2}
{...message_1}
{...message_0}
@ -44,13 +41,13 @@ Individual messages are saved in `jsonl` format for indexing purposes.
Here's a standard example `message` sent from a user.
```json
```js
"id": "0", // Sequential or UUID
"object": "thread.message", // Defaults to "thread.message"
"created_at": 1698983503,
"thread_id": "thread_asdf", // Defaults to parent thread
"assistant_id": "jan", // Defaults to parent thread
"role": "user", // From either "user" or "assistant"
"role": "user", // From either "user" or "assistant"
"content": [
{
"type": "text",
@ -61,13 +58,11 @@ Here's a standard example `message` sent from a user.
}
],
"metadata": {}, // Defaults to {}
// "run_id": "...", // Rather than `run` id abstraction
// "file_ids": [],
```
Here's an example `message` response from an assistant.
```json
```js
"id": "0", // Sequential or UUID
"object": "thread.message", // Defaults to "thread.message"
"created_at": 1698983503,
@ -84,175 +79,11 @@ Here's an example `message` response from an assistant.
}
],
"metadata": {}, // Defaults to {}
// "run_id": "...", // KIV
// "file_ids": [], // KIV
// "usage": {} // KIV: saving chat completion properties https://platform.openai.com/docs/api-reference/chat/object
"usage": {} // Save chat completion properties https://platform.openai.com/docs/api-reference/chat/object
```
## API Reference
Jan's `messages` API is compatible with [OpenAI's Messages API](https://platform.openai.com/docs/api-reference/messages), with additional methods for managing messages locally.
See [Jan Messages API](https://jan.ai/api-reference#tag/Messages)
<!-- TODO clean this part up into API -->
<!--
### Get list message
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/messages/getMessage
- Example request
```shell
curl {JAN_URL}/v1/threads/{thread_id}/messages/{message_id} \
-H "Content-Type: application/json"
```
- Example response
```json
{
"id": "msg_abc123",
"object": "thread.message",
"created_at": 1699017614,
"thread_id": "thread_abc123",
"role": "user",
"content": [
{
"type": "text",
"text": {
"value": "How does AI work? Explain it in simple terms.",
"annotations": []
}
}
],
"file_ids": [],
"assistant_id": null,
"run_id": null,
"metadata": {}
}
```
### Create message
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/messages/createMessage
- Example request
```shell
curl -X POST {JAN_URL}/v1/threads/{thread_id}/messages \
-H "Content-Type: application/json" \
-d '{
"role": "user",
"content": "How does AI work? Explain it in simple terms."
}'
```
- Example response
```json
{
"id": "msg_abc123",
"object": "thread.message",
"created_at": 1699017614,
"thread_id": "thread_abc123",
"role": "user",
"content": [
{
"type": "text",
"text": {
"value": "How does AI work? Explain it in simple terms.",
"annotations": []
}
}
],
"file_ids": [],
"assistant_id": null,
"run_id": null,
"metadata": {}
}
```
### Get message
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/assistants/listAssistants
- Example request
```shell
curl {JAN_URL}/v1/threads/{thread_id}/messages/{message_id} \
-H "Content-Type: application/json"
```
- Example response
```json
{
"id": "msg_abc123",
"object": "thread.message",
"created_at": 1699017614,
"thread_id": "thread_abc123",
"role": "user",
"content": [
{
"type": "text",
"text": {
"value": "How does AI work? Explain it in simple terms.",
"annotations": []
}
}
],
"file_ids": [],
"assistant_id": null,
"run_id": null,
"metadata": {}
}
```
### Modify message
> Jan: TODO: Do we need to modify message? Or let user create new message?
# Get message file
> OpenAI Equivalent: https://api.openai.com/v1/threads/{thread_id}/messages/{message_id}/files/{file_id}
- Example request
```shell
curl {JAN_URL}/v1/threads/{thread_id}/messages/{message_id}/files/{file_id} \
-H "Content-Type: application/json"
```
- Example response
```json
{
"id": "file-abc123",
"object": "thread.message.file",
"created_at": 1699061776,
"message_id": "msg_abc123"
}
```
# List message files
> OpenAI Equivalent: https://api.openai.com/v1/threads/{thread_id}/messages/{message_id}/files
````
- Example request
```shell
curl {JAN_URL}/v1/threads/{thread_id}/messages/{message_id}/files/{file_id} \
-H "Content-Type: application/json"
````
- Example response
```json
{
"id": "file-abc123",
"object": "thread.message.file",
"created_at": 1699061776,
"message_id": "msg_abc123"
}
``` -->
See [Jan Messages API](https://jan.ai/api-reference#tag/Messages).

View File

@ -22,7 +22,7 @@ In Jan, models are primary entities with the following capabilities:
- Models are organized by individual folders, each containing the binaries and configurations needed to run the model. This makes for easy packaging and sharing.
- Model folder names are unique and used as `model_id` default values.
```bash
```yaml
jan/ # Jan root folder
models/
llama2-70b-q4_k_m/ # Example: standard GGUF model
@ -52,9 +52,9 @@ Here's a standard example `model.json` for a GGUF model.
- `source_url`: https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/.
```json
```js
"id": "zephyr-7b" // Defaults to foldername
"object": "model", // Defaults to "model"
"object": "model", // Defaults to "model"
"source_url": "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/blob/main/zephyr-7b-beta.Q4_K_M.gguf",
"name": "Zephyr 7B" // Defaults to foldername
"owned_by": "you" // Defaults to you
@ -63,24 +63,21 @@ Here's a standard example `model.json` for a GGUF model.
"description": ""
"state": enum[null, "downloading", "ready", "starting", "stopping", ...]
"format": "ggufv3", // Defaults to "ggufv3"
"settings": { // Models are initialized with these settings
"settings": { // Models are initialized with settings
"ctx_len": "2048",
"ngl": "100",
"embedding": "true",
"n_parallel": "4",
// KIV: "pre_prompt": "A chat between a curious user and an artificial intelligence",
// KIV:"user_prompt": "USER: ",
// KIV: "ai_prompt": "ASSISTANT: "
}
"parameters": { // Models are called with these parameters
"parameters": { // Models are called parameters
"temperature": "0.7",
"token_limit": "2048",
"top_k": "0",
"top_p": "1",
"stream": "true"
},
"metadata": {} // Defaults to {}
"assets": [ // Filepaths to model binaries; Defaults to current dir
"metadata": {} // Defaults to {}
"assets": [ // Defaults to current dir
"file://.../zephyr-7b-q4_k_m.bin",
]
```
@ -89,7 +86,7 @@ Here's a standard example `model.json` for a GGUF model.
Jan's Model API is compatible with [OpenAI's Models API](https://platform.openai.com/docs/api-reference/models), with additional methods for managing and running models locally.
See [Jan Models API](https://jan.ai/api-reference#tag/Models)
See [Jan Models API](https://jan.ai/api-reference#tag/Models).
## Importing Models

View File

@ -0,0 +1,3 @@
---
title: System Monitor
---

View File

@ -14,7 +14,7 @@ This is currently under development.
- Users can tweak `model` params and `assistant` behavior within each thread.
- Users can import and export threads.
- An [OpenAI Thread API](https://platform.openai.com/docs/api-reference/threads) compatible endpoint at `localhost:3000/v1/threads`.
- An [OpenAI Thread API](https://platform.openai.com/docs/api-reference/threads) compatible endpoint at `localhost:1337/v1/threads`.
## Folder Structure
@ -23,13 +23,10 @@ This is currently under development.
- Thread folders follow the naming: `assistant_id` + `thread_created_at`.
- Thread folders also contain `messages.jsonl` files. See [messages](/specs/messages).
```sh
jan/
```yaml
janroot/
threads/
assistant_name_unix_timestamp/
thread.json
messages.jsonl
jan_2341243134/
assistant_name_unix_timestamp/ # Thread `ID`
thread.json
```
@ -43,14 +40,15 @@ jan/
Here's a standard example `thread.json` for a conversation between the user and the default Jan assistant.
```json
```js
"id": "thread_....", // Defaults to foldername
"object": "thread", // Defaults to "thread"
"title": "funny physics joke", // Defaults to ""
"assistants": [
{
"assistant_id": "jan", // Defaults to "jan"
"model": { // Defaults to 1 currently active model (can be changed before thread is begun)
"model": { // Defaults to the currently active model (can be changed before thread is begun)
"id": "...",
"settings": {}, // Defaults to and overrides assistant.json's "settings" (and if none, then model.json "settings")
"parameters": {}, // Defaults to and overrides assistant.json's "parameters" (and if none, then model.json "parameters")
}
@ -64,164 +62,4 @@ Here's a standard example `thread.json` for a conversation between the user and
Jan's Threads API is compatible with [OpenAI's Threads API](https://platform.openai.com/docs/api-reference/threads), with additional methods for managing threads locally.
See [Jan Threads API](https://jan.ai/api-reference#tag/Threads)
<!-- TODO clean this part up into API -->
<!--
### Get thread
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/threads/getThread
- Example request
```shell
curl {JAN_URL}/v1/threads/{thread_id}
```
- Example response
```json
{
"id": "thread_abc123",
"object": "thread",
"created_at": 1699014083,
"assistants": ["assistant-001"],
"metadata": {},
"messages": []
}
```
### Create Thread
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/threads/createThread
- Example request
```shell
curl -X POST {JAN_URL}/v1/threads \
-H "Content-Type: application/json" \
-d '{
"messages": [{
"role": "user",
"content": "Hello, what is AI?",
"file_ids": ["file-abc123"]
}, {
"role": "user",
"content": "How does AI work? Explain it in simple terms."
}]
}'
```
- Example response
```json
{
"id": "thread_abc123",
"object": "thread",
"created_at": 1699014083,
"metadata": {}
}
```
### Modify Thread
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/threads/modifyThread
- Example request
```shell
curl -X POST {JAN_URL}/v1/threads/{thread_id} \
-H "Content-Type: application/json" \
-d '{
"messages": [{
"role": "user",
"content": "Hello, what is AI?",
"file_ids": ["file-abc123"]
}, {
"role": "user",
"content": "How does AI work? Explain it in simple terms."
}]
}'
```
- Example response
```json
{
"id": "thread_abc123",
"object": "thread",
"created_at": 1699014083,
"metadata": {}
}
```
- https://platform.openai.com/docs/api-reference/threads/modifyThread
### Delete Thread
> OpenAI Equivalent: https://platform.openai.com/docs/api-reference/threads/deleteThread
- Example request
```shell
curl -X DELETE {JAN_URL}/v1/threads/{thread_id}
```
- Example response
```json
{
"id": "thread_abc123",
"object": "thread.deleted",
"deleted": true
}
```
### List Threads
> This is a Jan-only endpoint, not supported by OAI yet.
- Example request
```shell
curl {JAN_URL}/v1/threads \
-H "Content-Type: application/json" \
```
- Example response
```json
[
{
"id": "thread_abc123",
"object": "thread",
"created_at": 1699014083,
"assistants": ["assistant-001"],
"metadata": {},
"messages": []
},
{
"id": "thread_abc456",
"object": "thread",
"created_at": 1699014083,
"assistants": ["assistant-002", "assistant-002"],
"metadata": {}
}
]
```
### Get & Modify `Thread.Assistants`
-> Can achieve this goal by calling `Modify Thread` API
#### `GET v1/threads/{thread_id}/assistants`
-> Can achieve this goal by calling `Get Thread` API
#### `POST v1/threads/{thread_id}/assistants/{assistant_id}`
-> Can achieve this goal by calling `Modify Assistant` API with `thread.assistant[]`
### List `Thread.Messages`
-> Can achieve this goal by calling `Get Thread` API -->
See [Jan Threads API](https://jan.ai/api-reference#tag/Threads).

View File

@ -25,7 +25,7 @@ const config = {
onBrokenLinks: "warn",
onBrokenMarkdownLinks: "warn",
trailingSlash: true,
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
@ -112,6 +112,11 @@ const config = {
theme: {
primaryColor: "#1a73e8",
primaryColorDark: "#1a73e8",
options: {
disableSearch: true,
requiredPropsFirst: true,
noAutoAuth: true
},
// redocOptions: { hideDownloadButton: false },
},
},
@ -141,16 +146,34 @@ const config = {
// Navbar Left
{
type: "docSidebar",
sidebarId: "docsSidebar",
sidebarId: "guidesSidebar",
position: "left",
label: "Documentation",
label: "Guides",
},
{
type: "docSidebar",
sidebarId: "developerSidebar",
position: "left",
label: "Developer",
},
{
position: "left",
to: "/api-reference",
label: "API Reference",
},
{
type: "docSidebar",
position: "left",
sidebarId: "specsSidebar",
label: "Specs",
},
// Navbar right
{
type: "docSidebar",
position: "right",
sidebarId: "communitySidebar",
label: "Community",
},
{
to: "blog",
label: "Blog",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,304 @@
components:
schemas:
MessageObject:
type: object
properties:
id:
type: string
description: "Sequential or UUID identifier of the message."
example: 0
object:
type: string
description: "Type of the object, defaults to 'thread.message'."
example: thread.message
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the message."
thread_id:
type: string
description: "Identifier of the thread to which this message belongs. Defaults to parent thread."
example: "thread_asdf"
assistant_id:
type: string
description: "Identifier of the assistant involved in the message. Defaults to parent thread."
example: jan
role:
type: string
enum: ["user", "assistant"]
description: "Role of the sender, either 'user' or 'assistant'."
content:
type: array
items:
type: object
properties:
type:
type: string
description: "Type of content, e.g., 'text'."
text:
type: object
properties:
value:
type: string
description: "Text content of the message."
example: "Hi!?"
annotations:
type: array
items:
type: string
description: "Annotations for the text content, if any."
example: []
metadata:
type: object
description: "Metadata associated with the message, defaults to an empty object."
example: {}
GetMessageResponse:
type: object
properties:
id:
type: string
description: "The identifier of the message."
example: msg_abc123
object:
type: string
description: "Type of the object, indicating it's a thread message."
default: thread.message
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the message."
example: 1699017614
thread_id:
type: string
description: "Identifier of the thread to which this message belongs."
example: thread_abc123
role:
type: string
description: "Role of the sender, either 'user' or 'assistant'."
example: user
content:
type: array
items:
type: object
properties:
type:
type: string
description: "Type of content, e.g., 'text'."
example: text
text:
type: object
properties:
value:
type: string
description: "Text content of the message."
example: "How does AI work? Explain it in simple terms."
annotations:
type: array
items:
type: string
description: "Annotations for the text content, if any."
example: []
file_ids:
type: array
items:
type: string
description: "Array of file IDs associated with the message, if any."
example: []
assistant_id:
type: string
description: "Identifier of the assistant involved in the message, if applicable."
example: null
run_id:
type: string
description: "Run ID associated with the message, if applicable."
example: null
metadata:
type: object
description: "Metadata associated with the message."
example: {}
CreateMessageResponse:
type: object
properties:
id:
type: string
description: "The identifier of the created message."
example: msg_abc123
object:
type: string
description: "Type of the object, indicating it's a thread message."
example: thread.message
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the message."
example: 1699017614
thread_id:
type: string
description: "Identifier of the thread to which this message belongs."
example: thread_abc123
role:
type: string
description: "Role of the sender, either 'user' or 'assistant'."
example: user
content:
type: array
items:
type: object
properties:
type:
type: string
description: "Type of content, e.g., 'text'."
example: text
text:
type: object
properties:
value:
type: string
description: "Text content of the message."
example: "How does AI work? Explain it in simple terms."
annotations:
type: array
items:
type: string
description: "Annotations for the text content, if any."
example: []
file_ids:
type: array
items:
type: string
description: "Array of file IDs associated with the message, if any."
example: []
assistant_id:
type: string
description: "Identifier of the assistant involved in the message, if applicable."
example: null
run_id:
type: string
description: "Run ID associated with the message, if applicable."
example: null
metadata:
type: object
description: "Metadata associated with the message."
example: {}
ListMessagesResponse:
type: object
properties:
object:
type: string
description: "Type of the object, indicating it's a list."
default: "list"
data:
type: array
items:
$ref: '#/components/schemas/ListMessageObject'
first_id:
type: string
description: "Identifier of the first message in the list."
example: "msg_abc123"
last_id:
type: string
description: "Identifier of the last message in the list."
example: "msg_abc456"
has_more:
type: boolean
description: "Indicates whether there are more messages to retrieve."
example: false
ListMessageObject:
type: object
properties:
id:
type: string
description: "The identifier of the message."
example: msg_abc123
object:
type: string
description: "Type of the object, indicating it's a thread message."
example: thread.message
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the message."
example: 1699017614
thread_id:
type: string
description: "Identifier of the thread to which this message belongs."
example: thread_abc123
role:
type: string
description: "Role of the sender, either 'user' or 'assistant'."
example: user
content:
type: array
items:
type: object
properties:
type:
type: string
description: "Type of content, e.g., 'text'."
text:
type: object
properties:
value:
type: string
description: "Text content of the message."
example: "How does AI work? Explain it in simple terms."
annotations:
type: array
items:
type: string
description: "Annotations for the text content, if any."
file_ids:
type: array
items:
type: string
description: "Array of file IDs associated with the message, if any."
example: []
assistant_id:
type: string
description: "Identifier of the assistant involved in the message, if applicable."
example: null
run_id:
type: string
description: "Run ID associated with the message, if applicable."
example: null
metadata:
type: object
description: "Metadata associated with the message."
example: {}
MessageFileObject:
type: object
properties:
id:
type: string
description: "The identifier of the file."
example: file-abc123
object:
type: string
description: "Type of the object, indicating it's a thread message file."
example: thread.message.file
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the file."
example: 1699061776
message_id:
type: string
description: "Identifier of the message to which this file is associated."
example: msg_abc123
ListMessageFilesResponse:
type: object
properties:
object:
type: string
description: "Type of the object, indicating it's a list."
default: "list"
data:
type: array
items:
$ref: '#/components/schemas/MessageFileObject'

View File

@ -0,0 +1,320 @@
components:
schemas:
ListModelsResponse:
type: object
properties:
object:
type: string
enum: [list]
data:
type: array
items:
$ref: "#/components/schemas/Model"
required:
- object
- data
Model:
type: object
properties:
type:
type: string
default: "model"
description: "The type of the object."
version:
type: string
default: "1"
description: "The version number of the model."
id:
type: string
description: "Unique identifier used in chat-completions model_name, matches folder name."
example: "zephyr-7b"
name:
type: string
description: "Name of the model."
example: "Zephyr 7B"
owned_by:
type: string
description: "Compatibility field for OpenAI."
default: ""
created:
type: integer
format: int64
description: "Unix timestamp representing the creation time."
description:
type: string
description: "Description of the model."
state:
type: string
enum: [null, "downloading", "ready", "starting", "stopping"]
description: "Current state of the model."
format:
type: string
description: "State format of the model, distinct from the engine."
example: "ggufv3"
source_url:
type: string
format: uri
description: "URL to the source of the model."
example: "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/blob/main/zephyr-7b-beta.Q4_K_M.gguf"
settings:
type: object
properties:
ctx_len:
type: string
description: "Context length."
example: "2048"
ngl:
type: string
description: "Number of layers."
example: "100"
embedding:
type: string
description: "Indicates if embedding is enabled."
example: "true"
n_parallel:
type: string
description: "Number of parallel processes."
example: "4"
additionalProperties: false
parameters:
type: object
properties:
temperature:
type: string
description: "Temperature setting for the model."
example: "0.7"
token_limit:
type: string
description: "Token limit for the model."
example: "2048"
top_k:
type: string
description: "Top-k setting for the model."
example: "0"
top_p:
type: string
description: "Top-p setting for the model."
example: "1"
stream:
type: string
description: "Indicates if streaming is enabled."
example: "true"
additionalProperties: false
metadata:
type: object
description: "Additional metadata."
assets:
type: array
items:
type: string
description: "List of assets related to the model."
required:
- source_url
ModelObject:
type: object
properties:
id:
type: string
description: "The identifier of the model."
example: "zephyr-7b"
object:
type: string
description: "The type of the object, indicating it's a model."
default: "model"
created:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the model."
example: "1253935178"
owned_by:
type: string
description: "The entity that owns the model."
example: "_"
required:
- id
- object
- created
- owned_by
GetModelResponse:
type: object
properties:
id:
type: string
description: "The identifier of the model."
example: "zephyr-7b"
object:
type: string
description: "Type of the object, indicating it's a model."
default: "model"
created:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the model."
owned_by:
type: string
description: "The entity that owns the model."
example: "_"
state:
type: string
enum: [not_downloaded, downloaded, running, stopped]
description: "The current state of the model."
source_url:
type: string
format: uri
description: "URL to the source of the model."
example: "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/blob/main/zephyr-7b-beta.Q4_K_M.gguf"
parameters:
type: object
properties:
ctx_len:
type: integer
description: "Context length."
example: 2048
ngl:
type: integer
description: "Number of layers."
example: 100
embedding:
type: boolean
description: "Indicates if embedding is enabled."
example: true
n_parallel:
type: integer
description: "Number of parallel processes."
example: 4
# pre_prompt:
# type: string
# description: "Predefined prompt for initiating the chat."
# example: "A chat between a curious user and an artificial intelligence"
# user_prompt:
# type: string
# description: "Format of user's prompt."
# example: "USER: "
# ai_prompt:
# type: string
# description: "Format of AI's response."
# example: "ASSISTANT: "
temperature:
type: string
description: "Temperature setting for the model."
example: "0.7"
token_limit:
type: string
description: "Token limit for the model."
example: "2048"
top_k:
type: string
description: "Top-k setting for the model."
example: "0"
top_p:
type: string
description: "Top-p setting for the model."
example: "1"
metadata:
type: object
properties:
engine:
type: string
description: "The engine used by the model."
example: "llamacpp"
quantization:
type: string
description: "Quantization parameter of the model."
example: "Q3_K_L"
size:
type: string
description: "Size of the model."
example: "7B"
required:
- id
- object
- created
- owned_by
- state
- source_url
- parameters
- metadata
DeleteModelResponse:
type: object
properties:
id:
type: string
description: "The identifier of the model that was deleted."
example: "model-zephyr-7B"
object:
type: string
description: "Type of the object, indicating it's a model."
default: "model"
deleted:
type: boolean
description: "Indicates whether the model was successfully deleted."
example: true
required:
- id
- object
- deleted
StartModelResponse:
type: object
properties:
id:
type: string
description: "The identifier of the model that was started."
example: "model-zephyr-7B"
object:
type: string
description: "Type of the object, indicating it's a model."
default: "model"
state:
type: string
description: "The current state of the model after the start operation."
example: "running"
required:
- id
- object
- state
StopModelResponse:
type: object
properties:
id:
type: string
description: "The identifier of the model that was started."
example: "model-zephyr-7B"
object:
type: string
description: "Type of the object, indicating it's a model."
default: "model"
state:
type: string
description: "The current state of the model after the start operation."
example: "stopped"
required:
- id
- object
- state
DownloadModelResponse:
type: object
properties:
id:
type: string
description: "The identifier of the model that was started."
example: "model-zephyr-7B"
object:
type: string
description: "Type of the object, indicating it's a model."
default: "model"
state:
type: string
description: "The current state of the model after the start operation."
example: "downloaded"
required:
- id
- object
- state

View File

@ -0,0 +1,155 @@
components:
schemas:
ThreadObject:
type: object
properties:
id:
type: string
description: "The identifier of the thread, defaults to foldername."
example: thread_....
object:
type: string
description: "Type of the object, defaults to thread."
example: thread
summary:
type: string
description: "A brief summary or description of the thread, defaults to an empty string."
example: "funny physics joke"
assistants:
type: array
items:
type: string
description: "List of assistants involved in the thread, defaults to [\"jan\"]."
example: ["jan"]
created:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the thread, defaults to file creation time."
example: 1231231
metadata:
type: object
description: "Metadata associated with the thread, defaults to an empty object."
example: {}
messages:
type: array
description: "List of messages within the thread."
items:
type: string
example: []
model_id:
type: string
description: "Model identifier associated with the thread, defaults to assistant.model."
example: "..."
settings:
type: object
description: "Settings for the thread, defaults to and overrides assistant.settings."
parameters:
type: object
description: "Parameters for the thread, defaults to and overrides assistant.settings."
GetThreadResponse:
type: object
properties:
id:
type: string
description: "The identifier of the thread."
example: thread_abc123
object:
type: string
description: "Type of the object"
example: thread
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the thread."
example: 1699014083
assistants:
type: array
items:
type: string
description: "List of assistants involved in the thread."
example: ["assistant-001"]
metadata:
type: object
description: "Metadata associated with the thread."
example: {}
messages:
type: array
items:
type: string
description: "List of messages within the thread."
example: []
CreateThreadResponse:
type: object
properties:
id:
type: string
description: "The identifier of the newly created thread."
example: thread_abc123
object:
type: string
description: "Type of the object, indicating it's a thread."
example: thread
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the thread."
example: 1699014083
metadata:
type: object
description: "Metadata associated with the newly created thread."
example: {}
ThreadMessageObject:
type: object
properties:
role:
type: string
description: "Role of the sender, either 'user' or 'assistant'."
enum: ["user", "assistant"]
content:
type: string
description: "Text content of the message."
file_ids:
type: array
items:
type: string
description: "Array of file IDs associated with the message, if any."
ModifyThreadResponse:
type: object
properties:
id:
type: string
description: "The identifier of the modified thread."
example: thread_abc123
object:
type: string
description: "Type of the object, indicating it's a thread."
example: thread
created_at:
type: integer
format: int64
description: "Unix timestamp representing the creation time of the thread."
example: 1699014083
metadata:
type: object
description: "Metadata associated with the modified thread."
example: {}
DeleteThreadResponse:
type: object
properties:
id:
type: string
description: "The identifier of the deleted thread."
example: thread_abc123
object:
type: string
description: "Type of the object, indicating the thread has been deleted."
example: thread.deleted
deleted:
type: boolean
description: "Indicates whether the thread was successfully deleted."
example: true

View File

@ -21,7 +21,7 @@
"@docusaurus/theme-mermaid": "^3.0.0",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
"@mdx-js/react": "^1.6.22",
"@mdx-js/react": "^3.0.0",
"@redocly/cli": "^1.4.1",
"autoprefixer": "^10.4.16",
"axios": "^1.5.1",

View File

@ -13,7 +13,7 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
docsSidebar: [
guidesSidebar: [
{
type: "category",
label: "Introduction",
@ -42,43 +42,14 @@ const sidebars = {
collapsed: true,
items: ["docs/models", "docs/server"],
},
{
type: "category",
label: "Extending Jan",
link: { type: "doc", id: "docs/extensions" },
collapsible: true,
collapsed: true,
items: ["docs/assistants", "docs/themes", "docs/tools", "docs/modules"],
},
{
type: "category",
label: "Building Jan",
collapsible: true,
collapsed: true,
items: [
"specs/architecture",
"specs/data-structures",
"specs/user-interface",
{
type: "category",
label: "Specifications",
collapsible: true,
collapsed: false,
items: [
"specs/chats",
"specs/models",
"specs/threads",
"specs/messages",
"specs/assistants",
// "specs/files",
// "specs/jan",
// "specs/fine-tuning",
// "specs/settings",
// "specs/prompts",
],
},
],
},
],
developerSidebar: [
"docs/extensions",
"docs/assistants",
"docs/themes",
"docs/tools",
"docs/modules",
],
apiSidebar: [
@ -97,17 +68,53 @@ const sidebars = {
},
],
aboutSidebar: [
specsSidebar: [
{
type: "doc",
label: "About Jan",
id: "about/about",
type: "category",
label: "Overview",
collapsible: true,
collapsed: false,
items: [
"specs/architecture",
"specs/data-structures",
"specs/user-interface",
],
},
{
type: "link",
label: "Careers",
href: "https://janai.bamboohr.com/careers",
type: "category",
label: "Product",
collapsible: true,
collapsed: false,
items: [
"specs/home",
"specs/hub",
"specs/system-monitor",
"specs/settings",
],
},
{
type: "category",
label: "Engineering",
collapsible: true,
collapsed: false,
items: [
"specs/chats",
"specs/models",
"specs/threads",
"specs/messages",
// "specs/assistants",
// "specs/files",
// "specs/jan",
// "specs/fine-tuning",
// "specs/settings",
// "specs/prompts",
],
},
],
communitySidebar: [
"community/community",
{
type: "category",
label: "Events",
@ -122,6 +129,19 @@ const sidebars = {
},
],
},
],
aboutSidebar: [
{
type: "doc",
label: "About Jan",
id: "about/about",
},
{
type: "link",
label: "Careers",
href: "https://janai.bamboohr.com/careers",
},
{
type: "category",
label: "Company Handbook",

View File

@ -1807,11 +1807,6 @@
unist-util-visit "^5.0.0"
vfile "^6.0.0"
"@mdx-js/react@^1.6.22":
version "1.6.22"
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573"
integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==
"@mdx-js/react@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.0.tgz#eaccaa8d6a7736b19080aff5a70448a7ba692271"
@ -2337,9 +2332,9 @@
"@types/node" "*"
"@types/node@*":
version "20.9.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.3.tgz#e089e1634436f676ff299596c9531bd2b59fffc6"
integrity sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==
version "20.9.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.4.tgz#cc8f970e869c26834bdb7ed480b30ede622d74c7"
integrity sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA==
dependencies:
undici-types "~5.26.4"
@ -2426,9 +2421,9 @@
"@types/node" "*"
"@types/scheduler@*":
version "0.16.7"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.7.tgz#d62f1bd54724c84089f51f9218393930ba4abcf4"
integrity sha512-8g25Nl3AuB1KulTlSUsUhUo/oBgBU6XIXQ+XURpeioEbEJvkO7qI4vDfREv3vJYHHzqXjcAHvoJy4pTtSQNZtA==
version "0.16.8"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
"@types/send@*":
version "0.17.4"
@ -2462,9 +2457,9 @@
"@types/node" "*"
"@types/stylis@^4.0.2":
version "4.2.3"
resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.3.tgz#0dff504fc23487a02a29209b162249070e83a0da"
integrity sha512-86XLCVEmWagiUEbr2AjSbeY4qHN9jMm3pgM3PuBYfLIbT0MpDSnA3GA/4W7KoH/C/eeK77kNaeIxZzjhKYIBgw==
version "4.2.4"
resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.4.tgz#14b61f022e832d87d442ae1795e0f0f0b7daa879"
integrity sha512-36ZrGJ8fgtBr6nwNnuJ9jXIj+bn/pF6UoqmrQT7+Y99+tFFeHHsoR54+194dHdyhPjgbeoNz3Qru0oRt0l6ASQ==
"@types/unist@*", "@types/unist@^3.0.0":
version "3.0.2"
@ -3133,9 +3128,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541:
version "1.0.30001563"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz#aa68a64188903e98f36eb9c56e48fba0c1fe2a32"
integrity sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==
version "1.0.30001564"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz#eaa8bbc58c0cbccdcb7b41186df39dd2ba591889"
integrity sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==
ccount@^2.0.0:
version "2.0.1"
@ -4406,9 +4401,9 @@ ee-first@1.1.1:
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
electron-to-chromium@^1.4.535:
version "1.4.589"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.589.tgz#3fc83c284ed8f1f58e0cb3c664c8ebcb4d0b42fb"
integrity sha512-zF6y5v/YfoFIgwf2dDfAqVlPPsyQeWNpEWXbAlDUS8Ax4Z2VoiiZpAPC0Jm9hXEkJm2vIZpwB6rc4KnLTQffbQ==
version "1.4.592"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.592.tgz#1ffd49ba3da3da3077ea20014b066c910d50c913"
integrity sha512-D3NOkROIlF+d5ixnz7pAf3Lu/AuWpd6AYgI9O67GQXMXTcCP1gJQRotOq35eQy5Sb4hez33XH1YdTtILA7Udww==
elkjs@^0.8.2:
version "0.8.2"
@ -8282,9 +8277,9 @@ react-fast-compare@^3.2.0, react-fast-compare@^3.2.2:
integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==
react-helmet-async@*:
version "2.0.0"
resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-2.0.0.tgz#730c07280fb1f2392768a780fa56058057137803"
integrity sha512-pYYyVtyNkPuCENuHZkIy8CWmlINWO3oeh8HCBAw80CY4+rOc/pJwGgay5EUMSGBy5ii123Q8rncKvi+Jpt1scw==
version "2.0.1"
resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-2.0.1.tgz#c97e53d03bfe578011e4abbd61113321b0362471"
integrity sha512-SFvEqfhFpLr5xqU6fWFb8wjVPjOR4A5skkNVNN5gAr/QeHutfDe4m1Cdo521umTiFRAY8hDOcl4xJO8sXN1n2Q==
dependencies:
invariant "^2.2.4"
react-fast-compare "^3.2.2"

View File

@ -31,7 +31,7 @@ const BottomBar = () => {
<div className="fixed bottom-0 left-16 z-20 flex h-12 w-[calc(100%-64px)] items-center justify-between border-t border-border bg-background/50 px-3">
<div className="flex flex-shrink-0 items-center gap-x-2">
<div className="flex items-center space-x-2">
{!progress && progress === 0 ? (
{progress && progress > 0 ? (
<ProgressBar total={100} used={progress} />
) : null}
</div>