diff --git a/.github/ISSUE_TEMPLATE/documentation-request.md b/.github/ISSUE_TEMPLATE/documentation-request.md new file mode 100644 index 000000000..2f2b44f12 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation-request.md @@ -0,0 +1,17 @@ +--- +name: Documentation request +about: Documentation requests +title: 'docs: TITLE' +labels: 'type: documentation' +assignees: '' + +--- + +**Pages** +- Page(s) that need to be done + +**Success Criteria** +Content that should be covered + +**Additional context** +Examples, reference pages, resources diff --git a/.github/workflows/jan-docs.yml b/.github/workflows/jan-docs.yml index afb8ac463..2993d1525 100644 --- a/.github/workflows/jan-docs.yml +++ b/.github/workflows/jan-docs.yml @@ -6,6 +6,7 @@ on: - main paths: - 'docs/**' + tags: ["v[0-9]+.[0-9]+.[0-9]+-docs"] pull_request: branches: - main @@ -18,7 +19,14 @@ on: jobs: deploy: name: Deploy to GitHub Pages + env: + CLOUDFLARE_ACCOUNT_ID: 9707100ef42a1a25bd70e3ee2137bd0e + CLOUDFLARE_PROJECT_NAME: jan runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + pull-requests: write steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 @@ -50,15 +58,33 @@ jobs: - name: Build website run: sed -i '/process.env.DEBUG = namespaces;/c\// process.env.DEBUG = namespaces;' ./node_modules/debug/src/node.js && yarn build working-directory: docs - + + - name: Publish to Cloudflare Pages PR Preview and Staging + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ env.CLOUDFLARE_ACCOUNT_ID }} + projectName: ${{ env.CLOUDFLARE_PROJECT_NAME }} + directory: ./docs/build + # Optional: Enable this if you want to have GitHub Deployments triggered + gitHubToken: ${{ secrets.GITHUB_TOKEN }} + id: deployCloudflarePages + + - uses: mshick/add-pr-comment@v2 + if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' + with: + message: | + Preview URL: ${{ steps.deployCloudflarePages.outputs.url }} + - name: Add Custome Domain file - if: github.event_name == 'push' && github.event.pull_request.head.repo.full_name != github.repository + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') run: echo "${{ vars.DOCUSAURUS_DOMAIN }}" > ./docs/build/CNAME # Popular action to deploy to GitHub Pages: # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus - name: Deploy to GitHub Pages - if: github.event_name == 'push' && github.event.pull_request.head.repo.full_name != github.repository + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/jan-electron-build.yml b/.github/workflows/jan-electron-build.yml index 34005e068..db585e3c1 100644 --- a/.github/workflows/jan-electron-build.yml +++ b/.github/workflows/jan-electron-build.yml @@ -2,7 +2,7 @@ name: Jan Build Electron App on: push: - tags: ["v*.*.*"] + tags: ["v[0-9]+.[0-9]+.[0-9]+"] jobs: build-macos: diff --git a/docs/README.md b/docs/README.md index 1bd3933d6..9baac2b29 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,6 +41,12 @@ $ GIT_USER= yarn deploy If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. +### Preview URL, Pre-release and Publishing Documentation + +When a PR is created, the preview URL will be automatically commented on the PR. For staging or pre-release documentation, use the following domains [https://pre-release.jan.ai/](https://pre-release.jan.ai/) + +To officially publish documentation, create a tag in the format `vx.y.z-docs` (e.g., `v0.1.1-docs`) on the `main` branch. The documentation will then be published to [https://jan.ai/](https://jan.ai/) + ### Additional Plugins - @docusaurus/theme-live-codeblock - [Redocusaurus](https://redocusaurus.vercel.app/): manually upload swagger files at `/openapi/OpenAPISpec.json` \ No newline at end of file diff --git a/docs/docs/handbook/handbook.md b/docs/docs/handbook/handbook.md index c4e635458..a8222702a 100644 --- a/docs/docs/handbook/handbook.md +++ b/docs/docs/handbook/handbook.md @@ -1,5 +1,72 @@ --- -title: Company Handbook +title: Onboarding Checklist slug: /handbook --- + +# Welcome + +Welcome to Jan! We’re really excited to bring you onboard. + +## Expectations + + +**Take Initiative** Take ownership of an area. If you see a problem, take it and own it to completion. Your work will often not be defined, or poorly defined. Take the initiative to figure out what needs to be done, seek others out for clarification, and then communicate what you will be doing to the team. + + **Bias to Action** There are many problem-filled areas. There is no need to ask for permission or try to build consensus: just take action. + +**Speak Up** We require clear, effective and timely communication, which enables others to coordinate with you to be effective. We are a fully distributed, remote team of people from different cultures and languages. If conflicts do arise, first assume Hanlon’s Razor: “Never attribute to malice that which is adequately explained by ~~stupidity~~ lack of communication or too much ambiguity”. Don’t take things personally, be a professional. + +**Mastery** We are working in a frontier industry, where there are no playbooks, and expertise is developed by doing. Own your area, and build mastery. + + +## Code of conduct + +- We expected you to be available and communicative during scheduled meetings or work hours. +- We operate on the basis of trust. +- Employees should seek a quiet and distraction-free working space, to the extent possible. +- Turning on video during meetings is encouraged. +- Casual dress during meetings is acceptable; however, use discretion (No naked top, pajamas, etc.) +- While it’s natural for people to disagree at times, disagreement is no excuse for poor behavior and poor manners. We cannot allow that frustration to turn into a personal attack. +- Respect other people's cultures. Especially since we are working in a diverse working culture. +- Sexual harassment is a specific type of prohibited conduct. Sexual harassment is any unwelcome conduct of a sexual nature that might reasonably be expected or be perceived to cause offense or humiliation. Sexual harassment may involve any conduct of a verbal, nonverbal, or physical nature, including written and electronic communications, and may occur between persons of the same or different genders. + +## Onboarding Checklist + +### HR + +- [ ] Service Agreement +- [ ] Equipment Loan Agreement +- [ ] Calendar events + - [ ] Add to Google Team + - [ ] Add to Standup & TGIF +- [ ] `#hr-*` channel +- [ ] BambooHr Log-in +- [ ] Add Emergency Contact in BambooHR + +### Apps you will need + + + +- Company-wide + - [ ] Google:`[first_name]@jan.ai` + - Recommended: setup on Mobile too (i.e. Calendar, Mail) + - We use Google Calendar for tracking meetings, etc. + - [ ] Discord: + - [Invite link](https://discord.gg/sZb6qxfgyx) to Jan’s Discord + - We use Discord for day-to-day Comms in the company (ala Slack) + - Recommended: setup on Mobile with Notifications + - Download the desktop app + - [ ] 1Password + - [ ] [Jan](https://jan.ai/) - Desktop App +- Engineering + - [ ] Code Editor (such as VSCode, Vim, ect) + - [ ] Github +- Communications + - [ ] Fill in your contact details [here](https://docs.google.com/spreadsheets/d/1KAxya29_wb1bEESiFJeCrOec4pCG3uA2D4_VPgAn89U/edit#gid=0) + - [ ] To make sure everyone in the remote working environment understand more about each other, we encourage you to share your `How to work with me` in the [Drive Tab](https://docs.google.com/spreadsheets/d/1KAxya29_wb1bEESiFJeCrOec4pCG3uA2D4_VPgAn89U/edit#gid=0) under your name and the Discord `Internal` channel. + +:::info UPDATING +::: diff --git a/docs/docs/specs/models.md b/docs/docs/specs/models.md index c214f7557..851626431 100644 --- a/docs/docs/specs/models.md +++ b/docs/docs/specs/models.md @@ -2,344 +2,105 @@ title: Models --- -import ApiSchema from '@theme/ApiSchema'; +:::caution -:::warning - -Draft Specification: functionality has not been implemented yet. - -Feedback: [HackMD: Models Spec](https://hackmd.io/ulO3uB1AQCqLa5SAAMFOQw) +Draft Specification: functionality has not been implemented yet. ::: ## Overview -Jan's Model API aims to be as similar as possible to [OpenAI's Models API](https://platform.openai.com/docs/api-reference/models), with additional methods for managing and running models locally. +In Jan, models are primary entities with the following capabilities: -### Objectives +- Users can import, configure, and run models locally. +- An [OpenAI Model API](https://platform.openai.com/docs/api-reference/models) compatible endpoint at `localhost:3000/v1/models`. +- Supported model formats: `ggufv3`, and more. -- Users can download, import and delete models -- Users can use remote models (e.g. OpenAI, OpenRouter) -- Users can start/stop models and use them in a thread (or via Chat Completions API) -- User can configure default model parameters at the model level (to be overridden later at message or thread level) +## Folder Structure -## Models Folder +- Models are stored in the `/models` folder. +- 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. -Models in Jan are stored in the `/models` folder. - -Models are stored and organized by folders, which are atomic representations of a model for easy packaging and version control. - -A model's folder name is its `model.id` and contains: - -- `.json`, i.e. the [Model Object](#model-object) -- Binaries (may be downloaded later) - -```shell -/jan # Jan root folder - /models - # GGUF model - /llama2-70b - llama2-70b.json - llama2-70b-q4_k_m.gguf - - # Recommended Model (yet to be downloaded) - /mistral-7b - mistral-7b.json # Contains download instructions - # Note: mistral-7b-*.gguf binaries not downloaded yet - - # Remote model - /azure-openai-gpt3-5 - azure-openai-gpt3-5.json - # Note: No binaries - - # Multiple Binaries - # COMING SOON - - # Multiple Quantizations - # COMING SOON - - # Imported model (autogenerated .json) - random-model-q4_k_m.bin - # Note: will be moved into a autogenerated folder - # /random-model-q4_k_m - # random-model-q4_k_m.bin - # random-model-q4_k_m.json (autogenerated) +```bash +jan/ # Jan root folder + models/ + llama2-70b-q4_k_m/ # Example: standard GGUF model + model.json + model-binary-1.gguf + mistral-7b-gguf-q3_k_l/ # Example: quantizations are separate folders + model.json + mistral-7b-q3-K-L.gguf + mistral-7b-gguf-q8_k_m/ # Example: quantizations are separate folders + model.json + mistral-7b-q8_k_k.gguf + llava-ggml-Q5/ # Example: model with many partitions + model.json + mmprj.bin + model_q5.ggml ``` -### Importing Models +## `model.json` -:::warning +- Each `model` folder contains a `model.json` file, which is a representation of a model. +- `model.json` contains metadata and default parameters used to run a model. +- The only required field is `source_url`. -- This has not been confirmed -- Dan's view: Jan should auto-detect and create folders automatically -- Jan's UI will allow users to rename folders and add metadata +### GGUF Example -::: +Here's a standard example `model.json` for a GGUF model. -You can import a model by just dragging it into the `/models` folder, similar to Oobabooga. - -- Jan will detect and generate a corresponding `model-filename.json` file based on filename -- Jan will move it into its own `/model-id` folder once you define a `model-id` via the UI -- Jan will populate the model's `model-id.json` as you add metadata through the UI - -## Model Object - -:::warning - -- This is currently not finalized -- Dan's view: I think the current JSON is extremely clunky - - We should move `init` to top-level (e.g. "settings"?) - - We should move `runtime` to top-level (e.g. "parameters"?) - - `metadata` is extremely overloaded and should be refactored -- Dan's view: we should make a model object very extensible - - A `GGUF` model would "extend" a common model object with extra fields (at top level) -- Dan's view: State is extremely badly named - - Recommended: `downloaded`, `started`, `stopped`, null (for yet-to-download) - - We should also note that this is only for local models (not remote) - -::: - -Jan represents models as `json`-based Model Object files, known colloquially as `model.jsons`. Jan aims for rough equivalence with [OpenAI's Model Object](https://platform.openai.com/docs/api-reference/models/object) with additional properties to support local models. - -Jan's models follow a `model_id.json` naming convention, and are built to be extremely lightweight, with the only mandatory field being a `source_url` to download the model binaries. - - - -### Types of Models - -:::warning - -- This is currently not in the Model Object, and requires further discussion. -- Dan's view: we should have a field to differentiate between `local` and `remote` models - -::: - -There are 3 types of models. - -- Local model -- Local model, yet-to-be downloaded (we have the URL) -- Remote model (i.e. OpenAI API) - -#### Local Models - -:::warning - -- This is currently not finalized -- Dan's view: we should have `download_url` and `local_url` for local models (and possibly more) - -::: - -A `model.json` for a local model should always reference the following fields: - -- `download_url`: the original download source of the model -- `local_url`: the current location of the model binaries (may be array of multiple binaries) +- `source_url`: https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/. ```json -// ./models/llama2/llama2-7bn-gguf.json -"local_url": "~/Downloads/llama-2-7bn-q5-k-l.gguf", -``` - -#### Remote Models - -:::warning - -- This is currently not finalized -- Dan's view: each cloud model should be provided via a syste module, or define its own params field on the `model` or `model.init` object - -::: - -A `model.json` for a remote model should always reference the following fields: - -- `api_url`: the API endpoint of the model -- Any authentication parameters - -```json -// Dan's view: This needs to be refactored pretty significantly -"source_url": "https://docs-test-001.openai.azure.com/openai.azure.com/docs-test-001/gpt4-turbo", -"parameters": { - "init" { - "API-KEY": "", - "DEPLOYMENT-NAME": "", - "api-version": "2023-05-15" - }, - "runtime": { - "temperature": "0.7", - "max_tokens": "2048", - "presence_penalty": "0", - "top_p": "1", - "stream": "true" - } -} -"metadata": { - "engine": "api", // Dan's view: this should be a `type` field -} -``` - -### Importers - -:::caution - -- This is only an idea, has not been confirmed as part of spec - -::: - -Jan builds "importers" for users to seamlessly import models from a single URL. - -We currently only provide this for [TheBloke models on Huggingface](https://huggingface.co/TheBloke) (i.e. one of the patron saints of llama.cpp), but we plan to add more in the future. - -Currently, pasting a TheBloke Huggingface link in the Explore Models page will fire an importer, resulting in an: - -- Nicely-formatted model card -- Fully-annotated `model.json` file - -### Multiple Binaries - -:::warning - -- This is currently not finalized -- Dan's view: having these fields under `model.metadata` is not maintainable -- We should explore some sort of `local_url` structure - -::: - -- Model has multiple binaries `model-llava-1.5-ggml.json` -- See [source](https://huggingface.co/mys/ggml_llava-v1.5-13b) - -```json -"source_url": "https://huggingface.co/mys/ggml_llava-v1.5-13b", -"parameters": {"init": {}, "runtime": {}} -"metadata": { - "mmproj_binary": "https://huggingface.co/mys/ggml_llava-v1.5-13b/blob/main/mmproj-model-f16.gguf", - "ggml_binary": "https://huggingface.co/mys/ggml_llava-v1.5-13b/blob/main/ggml-model-q5_k.gguf", - "engine": "llamacpp", - "quantization": "Q5_K" -} -``` - -## Models API - -:::warning - -- We should use the OpenAPI spec to discuss APIs -- Dan's view: This needs @louis and App Pod to review as they are more familiar with this -- Dan's view: Start/Stop model should have some UI indicator (show state, block input) - -::: - -See http://localhost:3001/api-reference#tag/Models. - -| Method | API Call | OpenAI-equivalent | -| -------------- | ------------------------------- | ----------------- | -| List Models | GET /v1/models | true | -| Get Model | GET /v1/models/{model_id} | true | -| Delete Model | DELETE /v1/models/{model_id} | true | -| Start Model | PUT /v1/models/{model_id}/start | | -| Stop Model | PUT /v1/models/{model_id}/start | | -| Download Model | POST /v1/models/ | | - -## Examples - -### Local Model - -- Model has 1 binary `model-zephyr-7B.json` -- See [source](https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/) - -```json -// ./models/zephr/zephyr-7b-beta-Q4_K_M.json -// Note: Default fields omitted for brevity "source_url": "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/blob/main/zephyr-7b-beta.Q4_K_M.gguf", -"parameters": { - "init": { +"type": "model", // Defaults to "model" +"version": "1", // Defaults to 1 +"id": "zephyr-7b" // Defaults to foldername +"name": "Zephyr 7B" // Defaults to foldername +"owned_by": "you" // Defaults to you +"created": 1231231 // Defaults to file creation time +"description": "" +"state": enum[null, "downloading", "ready", "starting", "stopping", ...] +"format": "ggufv3", // Defaults to "ggufv3" +"settings": { // Models are initialized with these settings "ctx_len": "2048", "ngl": "100", "embedding": "true", "n_parallel": "4", - "pre_prompt": "A chat between a curious user and an artificial intelligence", - "user_prompt": "USER: ", - "ai_prompt": "ASSISTANT: " - }, - "runtime": { + // 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 "temperature": "0.7", "token_limit": "2048", "top_k": "0", "top_p": "1", "stream": "true" - } }, -"metadata": { - "engine": "llamacpp", - "quantization": "Q3_K_L", - "size": "7B", -} +"metadata": {} // Defaults to {} +"assets": [ // Filepaths to model binaries; Defaults to current dir + "file://.../zephyr-7b-q4_k_m.bin", +] ``` -### Remote Model +## API Reference -- Using a remote API to access model `model-azure-openai-gpt4-turbo.json` -- See [source](https://learn.microsoft.com/en-us/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython&pivots=rest-api) +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. -```json -"source_url": "https://docs-test-001.openai.azure.com/openai.azure.com/docs-test-001/gpt4-turbo", -"parameters": { - "init" { - "API-KEY": "", - "DEPLOYMENT-NAME": "", - "api-version": "2023-05-15" - }, - "runtime": { - "temperature": "0.7", - "max_tokens": "2048", - "presence_penalty": "0", - "top_p": "1", - "stream": "true" - } -} -"metadata": { - "engine": "api", -} -``` +See [Jan Models API](https://jan.ai/api-reference#tag/Models) -### Deferred Download +## Importing Models -- Jan ships with a default model folders containing recommended models -- Only the Model Object `json` files are included -- Users must later explicitly download the model binaries -- -```sh -models/ - mistral-7b/ - mistral-7b.json - hermes-7b/ - hermes-7b.json -``` +:::caution -### Multiple quantizations +This is current under development. -- Each quantization has its own `Jan Model Object` file -- TODO: `model.json`? +::: -```sh -llama2-7b-gguf/ - llama2-7b-gguf-Q2.json - llama2-7b-gguf-Q3_K_L.json - .bin -``` +You can import a model by dragging the model binary or gguf file into the `/models` folder. -### Multiple model partitions - -- A Model that is partitioned into several binaries use just 1 file - -```sh -llava-ggml/ - llava-ggml-Q5.json - .proj - ggml -``` - -### Locally fine-tuned model - -```sh -llama-70b-finetune/ - llama-70b-finetune-q5.json - .bin -``` \ No newline at end of file +- Jan automatically generates a corresponding `model.json` file based on the binary filename. +- Jan automatically organizes it into its own `/models/model-id` folder. +- Jan automatically populates the `model.json` properties, which you can subsequently modify. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 09757c67a..ad02d83c9 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -34,6 +34,10 @@ const config = { locales: ["en"], }, + markdown: { + mermaid: true, + }, + // Plugins we added plugins: [ "docusaurus-plugin-sass", @@ -58,8 +62,6 @@ const config = { ], ], - themes: ["@docusaurus/theme-live-codeblock"], - // The classic preset will relay each option entry to the respective sub plugin/theme. presets: [ [ @@ -104,7 +106,7 @@ const config = { specs: [ { spec: "openapi/jan.yaml", // can be local file, url, or parsed json object - route: "/api-reference", // path where to render docs + route: "/api-reference/", // path where to render docs }, ], theme: { @@ -173,6 +175,7 @@ const config = { respectPrefersColorScheme: false, }, }, + themes: ["@docusaurus/theme-live-codeblock", "@docusaurus/theme-mermaid"], }; module.exports = config; diff --git a/docs/package.json b/docs/package.json index c5b9ba06f..84e238d71 100644 --- a/docs/package.json +++ b/docs/package.json @@ -21,9 +21,11 @@ "@headlessui/react": "^1.7.17", "@heroicons/react": "^2.0.18", "@mdx-js/react": "^1.6.22", + "@redocly/cli": "^1.4.1", "autoprefixer": "^10.4.16", "axios": "^1.5.1", "clsx": "^1.2.1", + "@docusaurus/plugin-content-docs": "2.4.3", "docusaurus-plugin-redoc": "^2.0.0", "docusaurus-plugin-sass": "^0.2.5", "docusaurus-theme-redoc": "^2.0.0", @@ -31,8 +33,8 @@ "postcss": "^8.4.30", "posthog-docusaurus": "^2.0.0", "prism-react-renderer": "^1.3.5", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-icons": "^4.11.0", "redocusaurus": "^2.0.0", "sass": "^1.69.3", diff --git a/docs/redocly.yaml b/docs/redocly.yaml new file mode 100644 index 000000000..3f07f9b99 --- /dev/null +++ b/docs/redocly.yaml @@ -0,0 +1,18 @@ +# NOTE: Only supports options marked as "Supported in Redoc CE" +# See https://redocly.com/docs/cli/configuration/ for more information. + +extends: + - recommended + +rules: + no-unused-components: error + +theme: + openapi: + schemaExpansionLevel: 2 + generateCodeSamples: + languages: + - lang: curl + - lang: Python + - lang: JavaScript + - lang: Node.js \ No newline at end of file diff --git a/docs/src/components/Footer/index.js b/docs/src/components/Footer/index.js index d6bfca608..e5c09fe8e 100644 --- a/docs/src/components/Footer/index.js +++ b/docs/src/components/Footer/index.js @@ -1,37 +1,20 @@ import React from "react"; const menus = [ - { - name: "Resources", - child: [ - { - menu: "Home", - path: "/", - }, - { - menu: "Platform", - path: "/platform", - }, - { - menu: "Solutions", - path: "/solutions", - }, - ], - }, { name: "For Developers", child: [ { menu: "Documentation (WIP)", - path: "/docs", + path: "/intro", }, { menu: "Hardware (WIP)", path: "/hardware", }, { - menu: "API (WIP)", - path: "/api", + menu: "API Reference (WIP)", + path: "/api-reference", }, { menu: "Changelog", @@ -67,6 +50,10 @@ const menus = [ menu: "About", path: "/about", }, + { + menu: "Blog", + path: "/blog", + }, { menu: "Careers", path: "https://janai.bamboohr.com/careers", @@ -82,13 +69,15 @@ export default function Footer() { return (