diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml new file mode 100644 index 00000000..f9938ebf --- /dev/null +++ b/.github/workflows/deploy-dev.yaml @@ -0,0 +1,52 @@ +name: Deploy to dev machine + +on: + workflow_call: + inputs: + stack-name: + required: false + type: string + default: dev + image-tag: + required: false + type: string + default: latest + backend-port: + required: false + type: string + default: 8080 + website-port: + required: false + type: string + default: 3000 + +jobs: + deploy: + runs-on: ubuntu-latest + env: + WEB_ADMIN_USERS: ${{ secrets.DEV_WEB_ADMIN_USERS }} + WEB_DISCORD_CLIENT_ID: ${{ secrets.DEV_WEB_DISCORD_CLIENT_ID }} + WEB_DISCORD_CLIENT_SECRET: ${{ secrets.DEV_WEB_DISCORD_CLIENT_SECRET }} + WEB_EMAIL_SERVER_HOST: ${{ secrets.DEV_WEB_EMAIL_SERVER_HOST }} + WEB_EMAIL_SERVER_PASSWORD: ${{ secrets.DEV_WEB_EMAIL_SERVER_PASSWORD }} + WEB_EMAIL_SERVER_PORT: ${{ secrets.DEV_WEB_EMAIL_SERVER_PORT }} + WEB_EMAIL_SERVER_USER: ${{ secrets.DEV_WEB_EMAIL_SERVER_USER }} + WEB_NEXTAUTH_SECRET: ${{ secrets.DEV_WEB_NEXTAUTH_SECRET }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Run playbook + uses: dawidd6/action-ansible-playbook@v2 + with: + # Required, playbook filepath + playbook: deploy-dev.yaml + # Optional, directory where playbooks live + directory: ansible + # Optional, SSH private key + key: ${{secrets.DEV_NODE_PRIVATE_KEY}} + # Optional, literal inventory file contents + inventory: | + [dev] + dev01 ansible_host=${{secrets.DEV_NODE_IP}} ansible_connection=ssh ansible_user=web-team + options: | + --extra-vars "stack_name=${{inputs.stack-name}} image_tag=${{inputs.image-tag}} backend_port=${{inputs.backend-port}} website_port=${{inputs.website-port}}" diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 2a8c2ff9..ac2b8f81 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -46,8 +46,9 @@ jobs: with: images: ${{ env.REGISTRY }}/${{ inputs.image-name }} tags: | - type=sha,prefix=${{ env.TAG_PREFIX }},format=short - type=ref,event=tag + type=raw,value=latest,enable=${{ github.ref_name == 'main' }} + type=sha,prefix=${{ env.TAG_PREFIX }},format=short,enable=${{ github.ref_name != 'main' }} + type=ref,event=tag,enable=${{ github.ref_name != 'main' }} - name: Build and push Docker image uses: docker/build-push-action@v3.2.0 with: diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 47f21feb..3f587f28 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -1,9 +1,7 @@ name: pre-commit on: - push: - branches: - - main + workflow_call: pull_request_target: jobs: @@ -18,7 +16,7 @@ jobs: # in case of push, check out the main branch - uses: actions/checkout@v3 - if: github.event_name == 'push' + if: github.event_name != 'pull_request_target' - uses: actions/setup-python@v4 with: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1bf0ac6a..ea239492 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,12 +1,19 @@ name: Release on: + push: + branches: + - main release: - types: [released] + types: + - released jobs: + pre-commit: + uses: ./.github/workflows/pre-commit.yaml build-backend: uses: ./.github/workflows/docker-build.yaml + needs: pre-commit with: image-name: oasst-backend context: . @@ -14,6 +21,7 @@ jobs: build-args: "" build-web: uses: ./.github/workflows/docker-build.yaml + needs: pre-commit with: image-name: oasst-web context: . @@ -21,6 +29,7 @@ jobs: build-args: "" build-bot: uses: ./.github/workflows/docker-build.yaml + needs: pre-commit with: image-name: oasst-discord-bot context: . @@ -28,29 +37,12 @@ jobs: build-args: "" deploy-dev: needs: [build-backend, build-web, build-bot] - runs-on: ubuntu-latest - env: - WEB_ADMIN_USERS: ${{ secrets.DEV_WEB_ADMIN_USERS }} - WEB_DISCORD_CLIENT_ID: ${{ secrets.DEV_WEB_DISCORD_CLIENT_ID }} - WEB_DISCORD_CLIENT_SECRET: ${{ secrets.DEV_WEB_DISCORD_CLIENT_SECRET }} - WEB_EMAIL_SERVER_HOST: ${{ secrets.DEV_WEB_EMAIL_SERVER_HOST }} - WEB_EMAIL_SERVER_PASSWORD: ${{ secrets.DEV_WEB_EMAIL_SERVER_PASSWORD }} - WEB_EMAIL_SERVER_PORT: ${{ secrets.DEV_WEB_EMAIL_SERVER_PORT }} - WEB_EMAIL_SERVER_USER: ${{ secrets.DEV_WEB_EMAIL_SERVER_USER }} - WEB_NEXTAUTH_SECRET: ${{ secrets.DEV_WEB_NEXTAUTH_SECRET }} - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Run playbook - uses: dawidd6/action-ansible-playbook@v2 - with: - # Required, playbook filepath - playbook: dev.yaml - # Optional, directory where playbooks live - directory: ansible - # Optional, SSH private key - key: ${{secrets.DEV_NODE_PRIVATE_KEY}} - # Optional, literal inventory file contents - inventory: | - [dev] - dev01 ansible_host=${{secrets.DEV_NODE_IP}} ansible_connection=ssh ansible_user=web-team + uses: ./.github/workflows/deploy-dev.yaml + secrets: inherit + with: + stack-name: ${{ github.event_name == 'release' && 'staging' || 'dev' }} + image-tag: + ${{ github.event_name == 'release' && github.event.release.tag_name || + 'latest' }} + backend-port: ${{ github.event_name == 'release' && '8180' || '8080' }} + website-port: ${{ github.event_name == 'release' && '3100' || '3000' }} diff --git a/.github/workflows/test-api-contract.yaml b/.github/workflows/test-api-contract.yaml index dac53306..bee2f357 100644 --- a/.github/workflows/test-api-contract.yaml +++ b/.github/workflows/test-api-contract.yaml @@ -44,3 +44,9 @@ jobs: run: ./scripts/frontend-development/run-contract-test.sh - run: ./scripts/backend-development/stop-mock-server.sh + + #- uses: stefanzweifel/git-auto-commit-action@v4 + # with: + # file_pattern: "docs/docs/api/openapi.json" + # commit_message: + # update docs/docs/api/openapi.json by run ${{ github.run_id }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0bb81e89..b31d1e8f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ # # /WARNING! -exclude: build|stubs|^bot/templates/$|openassistant/templates +exclude: build|stubs|^bot/templates/$|openassistant/templates|docs/docs/api/openapi.json repos: - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b290f5fe..56dfa22c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,20 +37,28 @@ contributions smoothly we recommend the following: 1. Before working on any changes, try to [sync the forked repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) to keep it up-to-date with the upstream repository. -1. Work on a small focused change that only touches on a few files. +1. On a + [new branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository) + in your fork (aka a "feature branch" and not `main`) work on a small focused + change that only touches on a few files. 1. Run `pre-commit` and make sure all files have formatting fixed. This simplifies life for reviewers. 1. Package up a small bit of work that solves part of the problem [into a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) and [send it out for review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review). + [Here](https://github.com/LAION-AI/Open-Assistant/pull/658) is an example PR + for this project to illustrate this flow. 1. If you're lucky, we can merge your change into `main` without any problems. If there's changes to files you're working on, resolve them by: 1. First try rebase as suggested [in these instructions](https://timwise.co.uk/2019/10/14/merge-vs-rebase/#should-you-rebase). 1. If rebase feels too painful, merge as suggested [in these instructions](https://timwise.co.uk/2019/10/14/merge-vs-rebase/#should-you-merge). -1. Once you've resolved any conflicts, finish the review and merge into `main`. +1. Once you've resolved any conflicts, finish the review and + [squash and merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) + your PR (when squashing try to clean up or update the individual commit + messages to be one sensible single one). 1. Merge in your change and move onto a new issue or the second step of your current issue. @@ -59,6 +67,24 @@ need help on it or would like suggestions on how to approach the issue. If so, share wildly. If they seem to have a good handle on it, let them work on their solution until a challenge comes up. +#### Tips + +- At any point you can compare your feature branch to the upstream/main of + `LAION-AI/Open-Assistant` but using a URL like this: + https://github.com/LAION-AI/Open-Assistant/compare/main...andrewm4894:Open-Assistant:my-example-feature-branch. + Obviously just replace `andrewm4894` with your own GitHub user name and + `my-example-feature-branch` with whatever you called the feature branch you + are working on, so something like + `https://github.com/LAION-AI/Open-Assistant/compare/main...:Open-Assistant:`. + This will show the changes that would appear in a PR, so you can check this to + make sure it just looks like only the files you have changed or added will be + part of the PR. +- Try not to work on the `main` branch in your fork - ideally you can keep this + as just a updated copy of `main` from `LAION-AI/Open-Assistant`. +- If your feature branch gets messed up, just update the `main` branch in your + fork and create a fresh new clean "feature branch" you can try again on by + adding your changes one by one in separate commits or all as a single commit. + ### When does a review finish A review finishes when all blocking comments are addressed and at least one diff --git a/ansible/dev.yaml b/ansible/deploy-dev.yaml similarity index 64% rename from ansible/dev.yaml rename to ansible/deploy-dev.yaml index 3cf061a5..112a1d69 100644 --- a/ansible/dev.yaml +++ b/ansible/deploy-dev.yaml @@ -1,29 +1,37 @@ # ansible playbook to set up some docker containers -- name: Set up a dev node +- name: Deploy to dev node hosts: dev gather_facts: true + vars: + stack_name: "dev" + image_tag: latest + backend_port: 8080 + website_port: 3000 tasks: - name: Create network community.docker.docker_network: - name: oasst + name: "oasst-{{ stack_name }}" state: present driver: bridge + - name: Create stack files directory + ansible.builtin.file: + path: "./{{ stack_name }}" + state: directory + - name: Copy redis.conf to managed node ansible.builtin.copy: src: ./redis.conf - dest: ./redis.conf + dest: "./{{ stack_name }}/redis.conf" - name: Set up Redis community.docker.docker_container: - name: oasst-redis + name: "oasst-{{ stack_name }}-redis" image: redis state: started restart_policy: always - network_mode: oasst - ports: - - 6379:6379 + network_mode: "oasst-{{ stack_name }}" healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] interval: 2s @@ -31,73 +39,64 @@ retries: 10 command: redis-server /usr/local/etc/redis/redis.conf volumes: - - "./redis.conf:/usr/local/etc/redis/redis.conf" - - - name: Set up Redis Insights - community.docker.docker_container: - name: oasst-redis-insights - image: redislabs/redisinsight:latest - state: started - restart_policy: always - network_mode: oasst - ports: - - 8001:8001 + - "./{{ stack_name }}/redis.conf:/usr/local/etc/redis/redis.conf" - name: Create postgres containers community.docker.docker_container: - name: "{{ item.name }}" + name: "oasst-{{ stack_name }}-postgres-{{ item.name }}" image: postgres:15 state: started restart_policy: always - network_mode: oasst + network_mode: "oasst-{{ stack_name }}" env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres - volumes: - - "{{ item.name }}:/var/lib/postgresql/data" healthcheck: test: ["CMD", "pg_isready", "-U", "postgres"] interval: 2s timeout: 2s retries: 10 loop: - - name: oasst-postgres - - name: oasst-postgres-web + - name: backend + - name: web - name: Run the oasst oasst-backend community.docker.docker_container: - name: oasst-backend - image: ghcr.io/laion-ai/open-assistant/oasst-backend + name: "oasst-{{ stack_name }}-backend" + image: "ghcr.io/laion-ai/open-assistant/oasst-backend:{{ image_tag }}" state: started recreate: true pull: true restart_policy: always - network_mode: oasst + network_mode: "oasst-{{ stack_name }}" env: - POSTGRES_HOST: oasst-postgres - REDIS_HOST: oasst-redis + POSTGRES_HOST: "oasst-{{ stack_name }}-postgres-backend" + REDIS_HOST: "oasst-{{ stack_name }}-redis" DEBUG_ALLOW_ANY_API_KEY: "true" DEBUG_USE_SEED_DATA: "true" DEBUG_ALLOW_SELF_LABELING: "true" MAX_WORKERS: "1" RATE_LIMIT: "false" DEBUG_SKIP_EMBEDDING_COMPUTATION: "true" + DEBUG_SKIP_TOXICITY_CALCULATION: "true" ports: - - 8080:8080 + - "{{ backend_port }}:8080" - name: Run the oasst oasst-web frontend community.docker.docker_container: - name: oasst-web - image: ghcr.io/laion-ai/open-assistant/oasst-web + name: "oasst-{{ stack_name }}-web" + image: "ghcr.io/laion-ai/open-assistant/oasst-web:{{ image_tag }}" state: started recreate: true pull: true restart_policy: always - network_mode: oasst + network_mode: "oasst-{{ stack_name }}" env: ADMIN_USERS: "{{ lookup('ansible.builtin.env', 'WEB_ADMIN_USERS') }}" - DATABASE_URL: postgres://postgres:postgres@oasst-postgres-web/postgres + DATABASE_URL: + "postgres://postgres:postgres@oasst-{{ stack_name + }}-postgres-web/postgres" DEBUG_LOGIN: "true" DISCORD_CLIENT_ID: "{{ lookup('ansible.builtin.env', 'WEB_DISCORD_CLIENT_ID') }}" @@ -112,11 +111,11 @@ "{{ lookup('ansible.builtin.env', 'WEB_EMAIL_SERVER_PORT') }}" EMAIL_SERVER_USER: "{{ lookup('ansible.builtin.env', 'WEB_EMAIL_SERVER_USER') }}" - FASTAPI_URL: http://oasst-backend:8080 + FASTAPI_URL: "http://oasst-{{ stack_name }}-backend:8080" FASTAPI_KEY: "1234" NEXTAUTH_SECRET: "{{ lookup('ansible.builtin.env', 'WEB_NEXTAUTH_SECRET') }}" - NEXTAUTH_URL: http://web.dev.open-assistant.io/ + NEXTAUTH_URL: http://web.{{ stack_name }}.open-assistant.io/ ports: - - 3000:3000 + - "{{ website_port }}:3000" command: bash wait-for-postgres.sh node server.js diff --git a/backend/README.md b/backend/README.md index 056e0823..6fe10fe1 100644 --- a/backend/README.md +++ b/backend/README.md @@ -59,3 +59,6 @@ without having to actually set up and run a development backend. # save openapi.json to docs/docs/api wget localhost:8080/api/v1/openapi.json -O docs/docs/api/openapi.json ``` + +Note: The api docs should be automatically updated by the +`test-api-contract.yaml` workflow. diff --git a/backend/alembic/versions/2023_01_08_2200-bcc2fe18d214_messagetoxicity.py b/backend/alembic/versions/2023_01_08_2200-bcc2fe18d214_messagetoxicity.py new file mode 100644 index 00000000..1d17b9d2 --- /dev/null +++ b/backend/alembic/versions/2023_01_08_2200-bcc2fe18d214_messagetoxicity.py @@ -0,0 +1,40 @@ +"""MessageToxicity + +Revision ID: bcc2fe18d214 +Revises: 20cd871f4ec7 +Create Date: 2023-01-08 22:00:43.297719 + +""" +import sqlalchemy as sa +import sqlmodel +from alembic import op +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = "bcc2fe18d214" +down_revision = "846cc08ac79f" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "message_toxicity", + sa.Column("message_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.Column("toxicity", sa.Float(), nullable=True), + sa.Column("created_date", sa.DateTime(), server_default=sa.text("CURRENT_TIMESTAMP"), nullable=False), + sa.Column("model", sqlmodel.sql.sqltypes.AutoString(length=256), nullable=False), + sa.ForeignKeyConstraint( + ["message_id"], + ["message.id"], + ), + sa.PrimaryKeyConstraint("message_id", "model"), + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("message_toxicity") + # ### end Alembic commands ### diff --git a/backend/alembic/versions/2023_01_14_1509-619255ae9076_add_rank_to_message_table.py b/backend/alembic/versions/2023_01_14_1509-619255ae9076_add_rank_to_message_table.py new file mode 100644 index 00000000..ac8765f3 --- /dev/null +++ b/backend/alembic/versions/2023_01_14_1509-619255ae9076_add_rank_to_message_table.py @@ -0,0 +1,90 @@ +"""add rank to message table + +Revision ID: 619255ae9076 +Revises: bcc2fe18d214 +Create Date: 2023-01-14 15:09:03.462482 + +""" +import sqlalchemy as sa +import sqlmodel +from alembic import op +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = "619255ae9076" +down_revision = "bcc2fe18d214" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("message", sa.Column("rank", sa.Integer(), nullable=True)) + op.add_column("message_toxicity", sa.Column("score", sa.Float(), nullable=True)) + op.add_column("message_toxicity", sa.Column("label", sqlmodel.sql.sqltypes.AutoString(length=256), nullable=False)) + op.drop_column("message_toxicity", "toxicity") + op.add_column("user_stats", sa.Column("time_frame", sqlmodel.sql.sqltypes.AutoString(), nullable=False)) + op.add_column("user_stats", sa.Column("prompts", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("replies_assistant", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("replies_prompter", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("labels_simple", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("labels_full", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("rankings_total", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("rankings_good", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("accepted_prompts", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("accepted_replies_assistant", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("accepted_replies_prompter", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_assistant_ranked_1", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_assistant_ranked_2", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_assistant_ranked_3", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_prompter_ranked_1", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_prompter_ranked_2", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("reply_prompter_ranked_3", sa.Integer(), nullable=False)) + op.add_column("user_stats", sa.Column("streak_last_day_date", sa.DateTime(), nullable=True)) + op.add_column("user_stats", sa.Column("streak_days", sa.Integer(), nullable=True)) + op.drop_column("user_stats", "messages") + op.drop_column("user_stats", "upvotes") + op.drop_column("user_stats", "task_reward") + op.drop_column("user_stats", "compare_wins") + op.drop_column("user_stats", "compare_losses") + op.drop_column("user_stats", "downvotes") + op.drop_column("user_stats", "reactions") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("user_stats", sa.Column("reactions", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("downvotes", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("compare_losses", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("compare_wins", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("task_reward", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("upvotes", sa.INTEGER(), autoincrement=False, nullable=False)) + op.add_column("user_stats", sa.Column("messages", sa.INTEGER(), autoincrement=False, nullable=False)) + op.drop_column("user_stats", "streak_days") + op.drop_column("user_stats", "streak_last_day_date") + op.drop_column("user_stats", "reply_prompter_ranked_3") + op.drop_column("user_stats", "reply_prompter_ranked_2") + op.drop_column("user_stats", "reply_prompter_ranked_1") + op.drop_column("user_stats", "reply_assistant_ranked_3") + op.drop_column("user_stats", "reply_assistant_ranked_2") + op.drop_column("user_stats", "reply_assistant_ranked_1") + op.drop_column("user_stats", "accepted_replies_prompter") + op.drop_column("user_stats", "accepted_replies_assistant") + op.drop_column("user_stats", "accepted_prompts") + op.drop_column("user_stats", "rankings_good") + op.drop_column("user_stats", "rankings_total") + op.drop_column("user_stats", "labels_full") + op.drop_column("user_stats", "labels_simple") + op.drop_column("user_stats", "replies_prompter") + op.drop_column("user_stats", "replies_assistant") + op.drop_column("user_stats", "prompts") + op.drop_column("user_stats", "time_frame") + op.add_column( + "message_toxicity", + sa.Column("toxicity", postgresql.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True), + ) + op.drop_column("message_toxicity", "label") + op.drop_column("message_toxicity", "score") + op.drop_column("message", "rank") + # ### end Alembic commands ### diff --git a/backend/oasst_backend/api/v1/hugging_face.py b/backend/oasst_backend/api/v1/hugging_face.py index 62d2ea6b..a6715574 100644 --- a/backend/oasst_backend/api/v1/hugging_face.py +++ b/backend/oasst_backend/api/v1/hugging_face.py @@ -4,7 +4,7 @@ from fastapi import APIRouter, Depends from oasst_backend.api import deps from oasst_backend.models import ApiClient from oasst_backend.schemas.hugging_face import ToxicityClassification -from oasst_backend.utils.hugging_face import HfUrl, HuggingFaceAPI +from oasst_backend.utils.hugging_face import HfClassificationModel, HfUrl, HuggingFaceAPI router = APIRouter() @@ -25,7 +25,8 @@ async def get_text_toxicity( ToxicityClassification: the score of toxicity of the message. """ - api_url: str = HfUrl.HUGGINGFACE_TOXIC_ROBERTA.value + api_url: str = HfUrl.HUGGINGFACE_TOXIC_CLASSIFICATION.value + "/" + HfClassificationModel.TOXIC_ROBERTA.value + hugging_face_api = HuggingFaceAPI(api_url) response = await hugging_face_api.post(msg) diff --git a/backend/oasst_backend/api/v1/users.py b/backend/oasst_backend/api/v1/users.py index f09d58b5..565499a7 100644 --- a/backend/oasst_backend/api/v1/users.py +++ b/backend/oasst_backend/api/v1/users.py @@ -15,7 +15,7 @@ from starlette.status import HTTP_204_NO_CONTENT router = APIRouter() -@router.get("/users/{user_id}", response_model=protocol.User) +@router.get("/users/{user_id}", response_model=protocol.FrontEndUser) def get_user( user_id: UUID, api_client_id: UUID = None, diff --git a/backend/oasst_backend/config.py b/backend/oasst_backend/config.py index c18bd4c2..53277d2b 100644 --- a/backend/oasst_backend/config.py +++ b/backend/oasst_backend/config.py @@ -20,28 +20,28 @@ class TreeManagerConfiguration(BaseModel): """Maximum number of reply messages per tree node.""" goal_tree_size: int = 15 - """Total number of messages to gather per tree""" + """Total number of messages to gather per tree.""" num_reviews_initial_prompt: int = 3 """Number of peer review checks to collect in INITIAL_PROMPT_REVIEW state.""" num_reviews_reply: int = 3 - """Number of peer review checks to collect per reply (other than initial_prompt)""" + """Number of peer review checks to collect per reply (other than initial_prompt).""" p_full_labeling_review_prompt: float = 0.1 - """Probability of full text-labeling (instead of mandatory only) for initial prompts""" + """Probability of full text-labeling (instead of mandatory only) for initial prompts.""" p_full_labeling_review_reply_assistant: float = 0.1 - """Probability of full text-labeling (instead of mandatory only) for assistant replies""" + """Probability of full text-labeling (instead of mandatory only) for assistant replies.""" p_full_labeling_review_reply_prompter: float = 0.1 - """Probability of full text-labeling (instead of mandatory only) for prompter replies""" + """Probability of full text-labeling (instead of mandatory only) for prompter replies.""" acceptance_threshold_initial_prompt: float = 0.6 - """Threshold for accepting an initial prompt""" + """Threshold for accepting an initial prompt.""" acceptance_threshold_reply: float = 0.6 - """Threshold for accepting a reply""" + """Threshold for accepting a reply.""" num_required_rankings: int = 3 """Number of rankings in which the message participated.""" @@ -50,7 +50,7 @@ class TreeManagerConfiguration(BaseModel): """Mandatory labels in text-labeling tasks for initial prompts.""" mandatory_labels_assistant_reply: Optional[list[protocol_schema.TextLabel]] = [protocol_schema.TextLabel.spam] - """Mandatory labels in text-labeling tasks for assistant reylies.""" + """Mandatory labels in text-labeling tasks for assistant replies.""" mandatory_labels_prompter_reply: Optional[list[protocol_schema.TextLabel]] = [protocol_schema.TextLabel.spam] """Mandatory labels in text-labeling tasks for prompter replies.""" @@ -79,6 +79,7 @@ class Settings(BaseSettings): ) DEBUG_ALLOW_SELF_LABELING: bool = False # allow users to label their own messages DEBUG_SKIP_EMBEDDING_COMPUTATION: bool = False + DEBUG_SKIP_TOXICITY_CALCULATION: bool = False HUGGING_FACE_API_KEY: str = "" diff --git a/backend/oasst_backend/models/__init__.py b/backend/oasst_backend/models/__init__.py index 0873381c..9dc052d7 100644 --- a/backend/oasst_backend/models/__init__.py +++ b/backend/oasst_backend/models/__init__.py @@ -3,6 +3,7 @@ from .journal import Journal, JournalIntegration from .message import Message from .message_embedding import MessageEmbedding from .message_reaction import MessageReaction +from .message_toxicity import MessageToxicity from .message_tree_state import MessageTreeState from .task import Task from .text_labels import TextLabels @@ -17,6 +18,7 @@ __all__ = [ "MessageEmbedding", "MessageReaction", "MessageTreeState", + "MessageToxicity", "Task", "TextLabels", "Journal", diff --git a/backend/oasst_backend/models/message.py b/backend/oasst_backend/models/message.py index 488656a5..9583510f 100644 --- a/backend/oasst_backend/models/message.py +++ b/backend/oasst_backend/models/message.py @@ -45,6 +45,8 @@ class Message(SQLModel, table=True): review_result: bool = Field(sa_column=sa.Column(sa.Boolean, default=False, server_default=false(), nullable=False)) ranking_count: int = Field(sa_column=sa.Column(sa.Integer, default=0, server_default=sa.text("0"), nullable=False)) + rank: Optional[int] = Field(nullable=True) + def ensure_is_message(self) -> None: if not self.payload or not isinstance(self.payload.payload, MessagePayload): raise OasstError("Invalid message", OasstErrorCode.INVALID_MESSAGE, HTTPStatus.INTERNAL_SERVER_ERROR) diff --git a/backend/oasst_backend/models/message_toxicity.py b/backend/oasst_backend/models/message_toxicity.py new file mode 100644 index 00000000..8a78e2dc --- /dev/null +++ b/backend/oasst_backend/models/message_toxicity.py @@ -0,0 +1,24 @@ +from datetime import datetime +from typing import Optional +from uuid import UUID + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, Float, SQLModel + + +class MessageToxicity(SQLModel, table=True): + __tablename__ = "message_toxicity" + __table_args__ = (sa.PrimaryKeyConstraint("message_id", "model"),) + + message_id: UUID = Field(sa_column=sa.Column(pg.UUID(as_uuid=True), sa.ForeignKey("message.id"), nullable=False)) + model: str = Field(max_length=256, nullable=False) + + # Storing the score and the label of the message + score: float = Field(sa_column=sa.Column(Float), nullable=False) + label: str = Field(max_length=256, nullable=False) + + # In the case that the Message Embedding is created afterwards + created_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) + ) diff --git a/backend/oasst_backend/models/user_stats.py b/backend/oasst_backend/models/user_stats.py index b7b3231a..0bdaa3f4 100644 --- a/backend/oasst_backend/models/user_stats.py +++ b/backend/oasst_backend/models/user_stats.py @@ -1,4 +1,5 @@ from datetime import datetime +from enum import Enum from typing import Optional from uuid import UUID @@ -7,21 +8,46 @@ import sqlalchemy.dialects.postgresql as pg from sqlmodel import Field, SQLModel +class UserStatsTimeFrame(str, Enum): + day = "day" + week = "week" + month = "month" + total = "total" + + class UserStats(SQLModel, table=True): __tablename__ = "user_stats" user_id: Optional[UUID] = Field( sa_column=sa.Column(pg.UUID(as_uuid=True), sa.ForeignKey("user.id"), primary_key=True) ) + time_frame: Optional[str] = Field(nullable=False, primary_key=True) + leader_score: int = 0 modified_date: Optional[datetime] = Field( sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) ) - reactions: int = 0 # reactions sent by user - messages: int = 0 # messages sent by user - upvotes: int = 0 # received upvotes (form other users) - downvotes: int = 0 # received downvotes (from other users) - task_reward: int = 0 # reward for task completions - compare_wins: int = 0 # num times user's message won compare tasks - compare_losses: int = 0 # num times users's message lost compare tasks + prompts: int = 0 + replies_assistant: int = 0 + replies_prompter: int = 0 + labels_simple: int = 0 + labels_full: int = 0 + rankings_total: int = 0 + rankings_good: int = 0 + + accepted_prompts: int = 0 + accepted_replies_assistant: int = 0 + accepted_replies_prompter: int = 0 + + reply_assistant_ranked_1: int = 0 + reply_assistant_ranked_2: int = 0 + reply_assistant_ranked_3: int = 0 + + reply_prompter_ranked_1: int = 0 + reply_prompter_ranked_2: int = 0 + reply_prompter_ranked_3: int = 0 + + # only used for time span "total" + streak_last_day_date: Optional[datetime] = Field(nullable=True) + streak_days: Optional[int] = Field(nullable=True) diff --git a/backend/oasst_backend/prompt_repository.py b/backend/oasst_backend/prompt_repository.py index cb6e70f7..0c40daa0 100644 --- a/backend/oasst_backend/prompt_repository.py +++ b/backend/oasst_backend/prompt_repository.py @@ -14,6 +14,7 @@ from oasst_backend.models import ( Message, MessageEmbedding, MessageReaction, + MessageToxicity, MessageTreeState, Task, TextLabels, @@ -293,6 +294,25 @@ class PromptRepository: return reaction, task + def insert_toxicity(self, message_id: UUID, model: str, score: float, label: str) -> MessageToxicity: + """Save the toxicity score of a new message in the database. + Args: + message_id (UUID): the identifier of the message we want to save its toxicity score + model (str): the model used for creating the toxicity score + score (float): the toxicity score that we obtained from the model + label (str): the final classification in toxicity of the model + Raises: + OasstError: if misses some of the before params + Returns: + MessageToxicity: the instance in the database of the score saved for that message + """ + + message_toxicity = MessageToxicity(message_id=message_id, model=model, score=score, label=label) + self.db.add(message_toxicity) + self.db.commit() + self.db.refresh(message_toxicity) + return message_toxicity + def insert_message_embedding(self, message_id: UUID, model: str, embedding: List[float]) -> MessageEmbedding: """Insert the embedding of a new message in the database. @@ -308,9 +328,6 @@ class PromptRepository: MessageEmbedding: the instance in the database of the embedding saved for that message """ - if None in (message_id, model, embedding): - raise OasstError("Paramters missing to add embedding", OasstErrorCode.GENERIC_ERROR) - message_embedding = MessageEmbedding(message_id=message_id, model=model, embedding=embedding) self.db.add(message_embedding) self.db.commit() diff --git a/backend/oasst_backend/tree_manager.py b/backend/oasst_backend/tree_manager.py index d7abd9f8..fe45ca0e 100644 --- a/backend/oasst_backend/tree_manager.py +++ b/backend/oasst_backend/tree_manager.py @@ -1,7 +1,7 @@ import random from enum import Enum from http import HTTPStatus -from typing import Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple from uuid import UUID import numpy as np @@ -11,7 +11,7 @@ from oasst_backend.api.v1.utils import prepare_conversation, prepare_conversatio from oasst_backend.config import TreeManagerConfiguration, settings from oasst_backend.models import Message, MessageReaction, MessageTreeState, TextLabels, message_tree_state from oasst_backend.prompt_repository import PromptRepository -from oasst_backend.utils.hugging_face import HfEmbeddingModel, HfUrl, HuggingFaceAPI +from oasst_backend.utils.hugging_face import HfClassificationModel, HfEmbeddingModel, HfUrl, HuggingFaceAPI from oasst_shared.exceptions.oasst_api_error import OasstError, OasstErrorCode from oasst_shared.schemas import protocol as protocol_schema from sqlalchemy.sql import text @@ -363,6 +363,25 @@ class TreeManager: f"Could not fetch embbeddings for text reply to {interaction.message_id=} with {interaction.text=} by {interaction.user=}." ) + if not settings.DEBUG_SKIP_TOXICITY_CALCULATION: + try: + model_name: str = HfClassificationModel.TOXIC_ROBERTA.value + hugging_face_api: HuggingFaceAPI = HuggingFaceAPI( + f"{HfUrl.HUGGINGFACE_FEATURE_EXTRACTION.value}/{model_name}" + ) + + toxicity: List[List[Dict[str, Any]]] = await hugging_face_api.post(interaction.text) + toxicity = toxicity[0][0] + + pr.insert_toxicity( + message_id=message.id, model=model_name, score=toxicity["score"], label=toxicity["label"] + ) + + except OasstError: + logger.error( + f"Could not compute toxicity for text reply to {interaction.message_id=} with {interaction.text=} by {interaction.user=}." + ) + case protocol_schema.MessageRating: logger.info( f"Frontend reports rating of {interaction.message_id=} with {interaction.rating=} by {interaction.user=}." diff --git a/backend/oasst_backend/utils/hugging_face.py b/backend/oasst_backend/utils/hugging_face.py index 099bc51f..1aef23ce 100644 --- a/backend/oasst_backend/utils/hugging_face.py +++ b/backend/oasst_backend/utils/hugging_face.py @@ -8,10 +8,14 @@ from oasst_shared.exceptions import OasstError, OasstErrorCode class HfUrl(str, Enum): - HUGGINGFACE_TOXIC_ROBERTA = ("https://api-inference.huggingface.co/models/unitary/multilingual-toxic-xlm-roberta",) + HUGGINGFACE_TOXIC_CLASSIFICATION = "https://api-inference.huggingface.co/models" HUGGINGFACE_FEATURE_EXTRACTION = "https://api-inference.huggingface.co/pipeline/feature-extraction" +class HfClassificationModel(str, Enum): + TOXIC_ROBERTA = "unitary/multilingual-toxic-xlm-roberta" + + class HfEmbeddingModel(str, Enum): MINILM = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" diff --git a/discord-bot/requirements.txt b/discord-bot/requirements.txt index f6943cb0..ca294142 100644 --- a/discord-bot/requirements.txt +++ b/discord-bot/requirements.txt @@ -1,9 +1,8 @@ -aiosqlite # database -hikari # discord framework -hikari-lightbulb # command handler -hikari-miru # modals and buttons -hikari[speedups] -loguru -pydantic[dotenv] +aiosqlite == 0.18.0 # database +hikari-lightbulb == 2.3.1 # command handler +hikari-miru == 2.0.2 # modals and buttons +hikari[speedups] == 2.0.0.dev115 # discord framework +loguru == 0.6.0 +pydantic[dotenv] == 1.10.4 -uvloop; os_name != 'nt' # Faster drop-in replacement for asyncio event loop +uvloop == 0.17.0; os_name != 'nt' # Faster drop-in replacement for asyncio event loop diff --git a/docker-compose.yaml b/docker-compose.yaml index 858acb68..cde65166 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -101,6 +101,7 @@ services: - DEBUG_USE_SEED_DATA=True - DEBUG_ALLOW_SELF_LABELING=True - MAX_WORKERS=1 + - DEBUG_SKIP_TOXICITY_CALCULATION=True - DEBUG_SKIP_EMBEDDING_COMPUTATION=True depends_on: db: diff --git a/docs/docs/api/openapi.json b/docs/docs/api/openapi.json index c6a985b3..540cceae 100644 --- a/docs/docs/api/openapi.json +++ b/docs/docs/api/openapi.json @@ -1,17 +1,24 @@ { "openapi": "3.0.2", - "info": { "title": "open-assistant backend", "version": "0.1.0" }, + "info": { + "title": "open-assistant backend", + "version": "0.1.0" + }, "paths": { "/api/v1/tasks/": { "post": { - "tags": ["tasks"], + "tags": [ + "tasks" + ], "summary": "Request Task", "description": "Create new task.", "operationId": "request_task_api_v1_tasks__post", "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskRequest" } + "schema": { + "$ref": "#/components/schemas/TaskRequest" + } } }, "required": true @@ -24,25 +31,51 @@ "schema": { "title": "Response Request Task Api V1 Tasks Post", "anyOf": [ - { "$ref": "#/components/schemas/TaskDone" }, - { "$ref": "#/components/schemas/SummarizeStoryTask" }, - { "$ref": "#/components/schemas/RateSummaryTask" }, - { "$ref": "#/components/schemas/InitialPromptTask" }, - { "$ref": "#/components/schemas/ReplyToConversationTask" }, - { "$ref": "#/components/schemas/PrompterReplyTask" }, - { "$ref": "#/components/schemas/AssistantReplyTask" }, - { "$ref": "#/components/schemas/RankInitialPromptsTask" }, + { + "$ref": "#/components/schemas/TaskDone" + }, + { + "$ref": "#/components/schemas/SummarizeStoryTask" + }, + { + "$ref": "#/components/schemas/RateSummaryTask" + }, + { + "$ref": "#/components/schemas/InitialPromptTask" + }, + { + "$ref": "#/components/schemas/ReplyToConversationTask" + }, + { + "$ref": "#/components/schemas/PrompterReplyTask" + }, + { + "$ref": "#/components/schemas/AssistantReplyTask" + }, + { + "$ref": "#/components/schemas/RankInitialPromptsTask" + }, { "$ref": "#/components/schemas/RankConversationRepliesTask" }, - { "$ref": "#/components/schemas/RankPrompterRepliesTask" }, - { "$ref": "#/components/schemas/RankAssistantRepliesTask" }, - { "$ref": "#/components/schemas/LabelInitialPromptTask" }, + { + "$ref": "#/components/schemas/RankPrompterRepliesTask" + }, + { + "$ref": "#/components/schemas/RankAssistantRepliesTask" + }, + { + "$ref": "#/components/schemas/LabelInitialPromptTask" + }, { "$ref": "#/components/schemas/LabelConversationReplyTask" }, - { "$ref": "#/components/schemas/LabelPrompterReplyTask" }, - { "$ref": "#/components/schemas/LabelAssistantReplyTask" } + { + "$ref": "#/components/schemas/LabelPrompterReplyTask" + }, + { + "$ref": "#/components/schemas/LabelAssistantReplyTask" + } ] } } @@ -52,17 +85,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/tasks/{task_id}/ack": { "post": { - "tags": ["tasks"], + "tags": [ + "tasks" + ], "summary": "Tasks Acknowledge", "description": "The frontend acknowledges a task.", "operationId": "tasks_acknowledge_api_v1_tasks__task_id__ack_post", @@ -81,28 +125,43 @@ "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskAck" } + "schema": { + "$ref": "#/components/schemas/TaskAck" + } } }, "required": true }, "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/tasks/{task_id}/nack": { "post": { - "tags": ["tasks"], + "tags": [ + "tasks" + ], "summary": "Tasks Acknowledge Failure", "description": "The frontend reports failure to implement a task.", "operationId": "tasks_acknowledge_failure_api_v1_tasks__task_id__nack_post", @@ -121,28 +180,43 @@ "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskNAck" } + "schema": { + "$ref": "#/components/schemas/TaskNAck" + } } }, "required": true }, "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/tasks/interaction": { "post": { - "tags": ["tasks"], + "tags": [ + "tasks" + ], "summary": "Tasks Interaction", "description": "The frontend reports an interaction.", "operationId": "tasks_interaction_api_v1_tasks_interaction_post", @@ -152,10 +226,18 @@ "schema": { "title": "Interaction", "anyOf": [ - { "$ref": "#/components/schemas/TextReplyToMessage" }, - { "$ref": "#/components/schemas/MessageRating" }, - { "$ref": "#/components/schemas/MessageRanking" }, - { "$ref": "#/components/schemas/TextLabels" } + { + "$ref": "#/components/schemas/TextReplyToMessage" + }, + { + "$ref": "#/components/schemas/MessageRating" + }, + { + "$ref": "#/components/schemas/MessageRanking" + }, + { + "$ref": "#/components/schemas/TextLabels" + } ] } } @@ -167,7 +249,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskDone" } + "schema": { + "$ref": "#/components/schemas/TaskDone" + } } } }, @@ -175,23 +259,36 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/tasks/close": { "post": { - "tags": ["tasks"], + "tags": [ + "tasks" + ], "summary": "Close Collective Task", "operationId": "close_collective_task_api_v1_tasks_close_post", "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskClose" } + "schema": { + "$ref": "#/components/schemas/TaskClose" + } } }, "required": true @@ -201,7 +298,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TaskDone" } + "schema": { + "$ref": "#/components/schemas/TaskDone" + } } } }, @@ -209,71 +308,109 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/text_labels/": { "post": { - "tags": ["text_labels"], + "tags": [ + "text_labels" + ], "summary": "Label Text", "description": "Label a piece of text.", "operationId": "label_text_api_v1_text_labels__post", "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/TextLabels" } + "schema": { + "$ref": "#/components/schemas/TextLabels" + } } }, "required": true }, "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/text_labels/valid_labels": { "get": { - "tags": ["text_labels"], + "tags": [ + "text_labels" + ], "summary": "Get Valid Lables", "operationId": "get_valid_lables_api_v1_text_labels_valid_labels_get", "responses": { "200": { "description": "Successful Response", - "content": { "application/json": { "schema": {} } } + "content": { + "application/json": { + "schema": {} + } + } } } } }, "/api/v1/messages/": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Query Messages", "description": "Query messages.", "operationId": "query_messages_api_v1_messages__get", "parameters": [ { "required": false, - "schema": { "title": "Username", "type": "string" }, + "schema": { + "title": "Username", + "type": "string" + }, "name": "username", "in": "query" }, { "required": false, - "schema": { "title": "Api Client Id", "type": "string" }, + "schema": { + "title": "Api Client Id", + "type": "string" + }, "name": "api_client_id", "in": "query" }, @@ -281,8 +418,8 @@ "required": false, "schema": { "title": "Max Count", - "maximum": 1000.0, - "exclusiveMinimum": 0.0, + "maximum": 1000, + "exclusiveMinimum": 0, "type": "integer", "default": 10 }, @@ -321,7 +458,11 @@ }, { "required": false, - "schema": { "title": "Desc", "type": "boolean", "default": true }, + "schema": { + "title": "Desc", + "type": "boolean", + "default": true + }, "name": "desc", "in": "query" }, @@ -344,7 +485,9 @@ "schema": { "title": "Response Query Messages Api V1 Messages Get", "type": "array", - "items": { "$ref": "#/components/schemas/Message" } + "items": { + "$ref": "#/components/schemas/Message" + } } } } @@ -353,17 +496,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Message", "description": "Get a message by its internal ID.", "operationId": "get_message_api_v1_messages__message_id__get", @@ -384,7 +538,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Message" } + "schema": { + "$ref": "#/components/schemas/Message" + } } } }, @@ -392,15 +548,26 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] }, "delete": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Mark Message Deleted", "operationId": "mark_message_deleted_api_v1_messages__message_id__delete", "parameters": [ @@ -416,22 +583,35 @@ } ], "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/conversation": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Conv", "description": "Get a conversation from the tree root and up to the message with given internal ID.", "operationId": "get_conv_api_v1_messages__message_id__conversation_get", @@ -452,7 +632,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Conversation" } + "schema": { + "$ref": "#/components/schemas/Conversation" + } } } }, @@ -460,17 +642,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/tree": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Tree", "description": "Get all messages belonging to the same message tree.", "operationId": "get_tree_api_v1_messages__message_id__tree_get", @@ -491,7 +684,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -499,17 +694,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/children": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Children", "description": "Get all messages belonging to the same message tree.", "operationId": "get_children_api_v1_messages__message_id__children_get", @@ -533,7 +739,9 @@ "schema": { "title": "Response Get Children Api V1 Messages Message Id Children Get", "type": "array", - "items": { "$ref": "#/components/schemas/Message" } + "items": { + "$ref": "#/components/schemas/Message" + } } } } @@ -542,17 +750,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/descendants": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Descendants", "description": "Get a subtree which starts with this message.", "operationId": "get_descendants_api_v1_messages__message_id__descendants_get", @@ -573,7 +792,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -581,17 +802,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/longest_conversation_in_tree": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Longest Conv", "description": "Get the longest conversation from the tree of the message.", "operationId": "get_longest_conv_api_v1_messages__message_id__longest_conversation_in_tree_get", @@ -612,7 +844,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Conversation" } + "schema": { + "$ref": "#/components/schemas/Conversation" + } } } }, @@ -620,17 +854,28 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/messages/{message_id}/max_children_in_tree": { "get": { - "tags": ["messages"], + "tags": [ + "messages" + ], "summary": "Get Max Children", "description": "Get message with the most children from the tree of the provided message.", "operationId": "get_max_children_api_v1_messages__message_id__max_children_in_tree_get", @@ -651,7 +896,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -659,24 +906,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Message By Frontend Id", "description": "Get a message by its frontend ID.", "operationId": "get_message_by_frontend_id_api_v1_frontend_messages__message_id__get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -686,7 +947,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Message" } + "schema": { + "$ref": "#/components/schemas/Message" + } } } }, @@ -694,24 +957,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/conversation": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Conv By Frontend Id", "description": "Get a conversation from the tree root and up to the message with given frontend ID.", "operationId": "get_conv_by_frontend_id_api_v1_frontend_messages__message_id__conversation_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -721,7 +998,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Conversation" } + "schema": { + "$ref": "#/components/schemas/Conversation" + } } } }, @@ -729,24 +1008,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/tree": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Tree By Frontend Id", "description": "Get all messages belonging to the same message tree.\nMessage is identified by its frontend ID.", "operationId": "get_tree_by_frontend_id_api_v1_frontend_messages__message_id__tree_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -756,7 +1049,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -764,24 +1059,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/children": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Children By Frontend Id", "description": "Get all messages belonging to the same message tree.", "operationId": "get_children_by_frontend_id_api_v1_frontend_messages__message_id__children_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -794,7 +1103,9 @@ "schema": { "title": "Response Get Children By Frontend Id Api V1 Frontend Messages Message Id Children Get", "type": "array", - "items": { "$ref": "#/components/schemas/Message" } + "items": { + "$ref": "#/components/schemas/Message" + } } } } @@ -803,24 +1114,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/descendants": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Descendants By Frontend Id", "description": "Get a subtree which starts with this message.\nThe message is identified by its frontend ID.", "operationId": "get_descendants_by_frontend_id_api_v1_frontend_messages__message_id__descendants_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -830,7 +1155,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -838,24 +1165,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/longest_conversation_in_tree": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Longest Conv By Frontend Id", "description": "Get the longest conversation from the tree of the message.\nThe message is identified by its frontend ID.", "operationId": "get_longest_conv_by_frontend_id_api_v1_frontend_messages__message_id__longest_conversation_in_tree_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -865,7 +1206,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Conversation" } + "schema": { + "$ref": "#/components/schemas/Conversation" + } } } }, @@ -873,24 +1216,38 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_messages/{message_id}/max_children_in_tree": { "get": { - "tags": ["frontend_messages"], + "tags": [ + "frontend_messages" + ], "summary": "Get Max Children By Frontend Id", "description": "Get message with the most children from the tree of the provided message.\nThe message is identified by its frontend ID.", "operationId": "get_max_children_by_frontend_id_api_v1_frontend_messages__message_id__max_children_in_tree_get", "parameters": [ { "required": true, - "schema": { "title": "Message Id", "type": "string" }, + "schema": { + "title": "Message Id", + "type": "string" + }, "name": "message_id", "in": "path" } @@ -900,7 +1257,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/MessageTree" } + "schema": { + "$ref": "#/components/schemas/MessageTree" + } } } }, @@ -908,17 +1267,194 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] + } + }, + "/api/v1/users/users/{user_id}": { + "get": { + "tags": [ + "users" + ], + "summary": "Get User", + "description": "Get a user by global user ID. Only trusted clients can resolve users they did not register.", + "operationId": "get_user_api_v1_users_users__user_id__get", + "parameters": [ + { + "required": true, + "schema": { + "title": "User Id", + "type": "string", + "format": "uuid" + }, + "name": "user_id", + "in": "path" + }, + { + "required": false, + "schema": { + "title": "Api Client Id", + "type": "string", + "format": "uuid" + }, + "name": "api_client_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] + }, + "put": { + "tags": [ + "users" + ], + "summary": "Update User", + "description": "Update a user by global user ID. Only trusted clients can update users.", + "operationId": "update_user_api_v1_users_users__user_id__put", + "parameters": [ + { + "required": true, + "schema": { + "title": "User Id", + "type": "string", + "format": "uuid" + }, + "name": "user_id", + "in": "path" + }, + { + "required": false, + "schema": { + "title": "Enabled", + "type": "boolean" + }, + "name": "enabled", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Notes", + "type": "string" + }, + "name": "notes", + "in": "query" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] + }, + "delete": { + "tags": [ + "users" + ], + "summary": "Delete User", + "description": "Delete a user by global user ID. Only trusted clients can delete users.", + "operationId": "delete_user_api_v1_users_users__user_id__delete", + "parameters": [ + { + "required": true, + "schema": { + "title": "User Id", + "type": "string", + "format": "uuid" + }, + "name": "user_id", + "in": "path" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/users/{user_id}/messages": { "get": { - "tags": ["users"], + "tags": [ + "users" + ], "summary": "Query User Messages", "description": "Query user messages.", "operationId": "query_user_messages_api_v1_users__user_id__messages_get", @@ -947,8 +1483,8 @@ "required": false, "schema": { "title": "Max Count", - "maximum": 1000.0, - "exclusiveMinimum": 0.0, + "maximum": 1000, + "exclusiveMinimum": 0, "type": "integer", "default": 10 }, @@ -987,7 +1523,11 @@ }, { "required": false, - "schema": { "title": "Desc", "type": "boolean", "default": true }, + "schema": { + "title": "Desc", + "type": "boolean", + "default": true + }, "name": "desc", "in": "query" }, @@ -1010,7 +1550,9 @@ "schema": { "title": "Response Query User Messages Api V1 Users User Id Messages Get", "type": "array", - "items": { "$ref": "#/components/schemas/Message" } + "items": { + "$ref": "#/components/schemas/Message" + } } } } @@ -1019,15 +1561,26 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] }, "delete": { - "tags": ["users"], + "tags": [ + "users" + ], "summary": "Mark User Messages Deleted", "operationId": "mark_user_messages_deleted_api_v1_users__user_id__messages_delete", "parameters": [ @@ -1043,35 +1596,237 @@ } ], "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] + } + }, + "/api/v1/frontend_users/": { + "get": { + "tags": [ + "frontend_users" + ], + "summary": "Get Users", + "operationId": "get_users_api_v1_frontend_users__get", + "parameters": [ + { + "required": false, + "schema": { + "title": "Api Client Id", + "type": "string", + "format": "uuid" + }, + "name": "api_client_id", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Max Count", + "maximum": 10000, + "exclusiveMinimum": 0, + "type": "integer", + "default": 100 + }, + "name": "max_count", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Gte", + "type": "string" + }, + "name": "gte", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Lt", + "type": "string" + }, + "name": "lt", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Auth Method", + "type": "string" + }, + "name": "auth_method", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "title": "Response Get Users Api V1 Frontend Users Get", + "type": "array", + "items": { + "$ref": "#/components/schemas/FrontEndUser" + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] + } + }, + "/api/v1/frontend_users/by_display_name": { + "get": { + "tags": [ + "frontend_users" + ], + "summary": "Query Frontend Users By Display Name", + "operationId": "query_frontend_users_by_display_name_api_v1_frontend_users_by_display_name_get", + "parameters": [ + { + "required": true, + "schema": { + "title": "Search Text", + "type": "string" + }, + "name": "search_text", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Exact", + "type": "boolean", + "default": false + }, + "name": "exact", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Api Client Id", + "type": "string", + "format": "uuid" + }, + "name": "api_client_id", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Max Count", + "maximum": 1000, + "exclusiveMinimum": 0, + "type": "integer", + "default": 20 + }, + "name": "max_count", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Auth Method", + "type": "string" + }, + "name": "auth_method", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/frontend_users/{auth_method}/{username}": { "get": { - "tags": ["frontend_users"], + "tags": [ + "frontend_users" + ], "summary": "Query Frontend User", "description": "Query frontend user.", "operationId": "query_frontend_user_api_v1_frontend_users__auth_method___username__get", "parameters": [ { "required": true, - "schema": { "title": "Auth Method", "type": "string" }, + "schema": { + "title": "Auth Method", + "type": "string" + }, "name": "auth_method", "in": "path" }, { "required": true, - "schema": { "title": "Username", "type": "string" }, + "schema": { + "title": "Username", + "type": "string" + }, "name": "username", "in": "path" }, @@ -1091,7 +1846,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/User" } + "schema": { + "$ref": "#/components/schemas/FrontEndUser" + } } } }, @@ -1099,24 +1856,47 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, - "/api/v1/frontend_users/{username}/messages": { + "/api/v1/frontend_users/{auth_method}/{username}/messages": { "get": { - "tags": ["frontend_users"], + "tags": [ + "frontend_users" + ], "summary": "Query Frontend User Messages", "description": "Query frontend user messages.", - "operationId": "query_frontend_user_messages_api_v1_frontend_users__username__messages_get", + "operationId": "query_frontend_user_messages_api_v1_frontend_users__auth_method___username__messages_get", "parameters": [ { "required": true, - "schema": { "title": "Username", "type": "string" }, + "schema": { + "title": "Auth Method", + "type": "string" + }, + "name": "auth_method", + "in": "path" + }, + { + "required": true, + "schema": { + "title": "Username", + "type": "string" + }, "name": "username", "in": "path" }, @@ -1134,8 +1914,8 @@ "required": false, "schema": { "title": "Max Count", - "maximum": 1000.0, - "exclusiveMinimum": 0.0, + "maximum": 1000, + "exclusiveMinimum": 0, "type": "integer", "default": 10 }, @@ -1174,7 +1954,11 @@ }, { "required": false, - "schema": { "title": "Desc", "type": "boolean", "default": true }, + "schema": { + "title": "Desc", + "type": "boolean", + "default": true + }, "name": "desc", "in": "query" }, @@ -1195,9 +1979,11 @@ "content": { "application/json": { "schema": { - "title": "Response Query Frontend User Messages Api V1 Frontend Users Username Messages Get", + "title": "Response Query Frontend User Messages Api V1 Frontend Users Auth Method Username Messages Get", "type": "array", - "items": { "$ref": "#/components/schemas/Message" } + "items": { + "$ref": "#/components/schemas/Message" + } } } } @@ -1206,42 +1992,78 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] }, "delete": { - "tags": ["frontend_users"], + "tags": [ + "frontend_users" + ], "summary": "Mark Frontend User Messages Deleted", - "operationId": "mark_frontend_user_messages_deleted_api_v1_frontend_users__username__messages_delete", + "operationId": "mark_frontend_user_messages_deleted_api_v1_frontend_users__auth_method___username__messages_delete", "parameters": [ { "required": true, - "schema": { "title": "Username", "type": "string" }, + "schema": { + "title": "Auth Method", + "type": "string" + }, + "name": "auth_method", + "in": "path" + }, + { + "required": true, + "schema": { + "title": "Username", + "type": "string" + }, "name": "username", "in": "path" } ], "responses": { - "204": { "description": "Successful Response" }, + "204": { + "description": "Successful Response" + }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/stats/": { "get": { - "tags": ["stats"], + "tags": [ + "stats" + ], "summary": "Get Message Stats", "operationId": "get_message_stats_api_v1_stats__get", "responses": { @@ -1249,52 +2071,92 @@ "description": "Successful Response", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/SystemStats" } + "schema": { + "$ref": "#/components/schemas/SystemStats" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/experimental/leaderboards/create/assistant": { "get": { - "tags": ["leaderboards"], + "tags": [ + "leaderboards" + ], "summary": "Get Assistant Leaderboard", "operationId": "get_assistant_leaderboard_api_v1_experimental_leaderboards_create_assistant_get", "responses": { "200": { "description": "Successful Response", - "content": { "application/json": { "schema": {} } } + "content": { + "application/json": { + "schema": {} + } + } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/experimental/leaderboards/create/prompter": { "get": { - "tags": ["leaderboards"], + "tags": [ + "leaderboards" + ], "summary": "Get Prompter Leaderboard", "operationId": "get_prompter_leaderboard_api_v1_experimental_leaderboards_create_prompter_get", "responses": { "200": { "description": "Successful Response", - "content": { "application/json": { "schema": {} } } + "content": { + "application/json": { + "schema": {} + } + } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } }, "/api/v1/hf/text_toxicity": { "get": { - "tags": ["hugging_face"], + "tags": [ + "hugging_face" + ], "summary": "Get Text Toxicity", "description": "Get the Message Toxicity from HuggingFace Roberta model.\n\nArgs:\n msg (str): the message that we want to analyze.\n api_client (ApiClient, optional): authentification of the user of the request.\n Defaults to Depends(deps.get_trusted_api_client).\n\nReturns:\n ToxicityClassification: the score of toxicity of the message.", "operationId": "get_text_toxicity_api_v1_hf_text_toxicity_get", "parameters": [ { "required": true, - "schema": { "title": "Msg", "type": "string" }, + "schema": { + "title": "Msg", + "type": "string" + }, "name": "msg", "in": "query" } @@ -1302,18 +2164,31 @@ "responses": { "200": { "description": "Successful Response", - "content": { "application/json": { "schema": {} } } + "content": { + "application/json": { + "schema": {} + } + } }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } } } } }, - "security": [{ "APIKeyQuery": [] }, { "APIKeyHeader": [] }] + "security": [ + { + "APIKeyQuery": [] + }, + { + "APIKeyHeader": [] + } + ] } } }, @@ -1321,17 +2196,27 @@ "schemas": { "AssistantReplyTask": { "title": "AssistantReplyTask", - "required": ["conversation"], + "required": [ + "conversation" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["assistant_reply"], + "enum": [ + "assistant_reply" + ], "type": "string", "default": "assistant_reply" }, - "conversation": { "$ref": "#/components/schemas/Conversation" } + "conversation": { + "$ref": "#/components/schemas/Conversation" + } }, "description": "A task to prompt the user to act as the assistant." }, @@ -1342,7 +2227,9 @@ "messages": { "title": "Messages", "type": "array", - "items": { "$ref": "#/components/schemas/ConversationMessage" }, + "items": { + "$ref": "#/components/schemas/ConversationMessage" + }, "default": [] } }, @@ -1350,23 +2237,85 @@ }, "ConversationMessage": { "title": "ConversationMessage", - "required": ["text", "is_assistant"], + "required": [ + "text", + "is_assistant" + ], "type": "object", "properties": { - "text": { "title": "Text", "type": "string" }, - "is_assistant": { "title": "Is Assistant", "type": "boolean" }, - "message_id": { - "title": "Message Id", + "id": { + "title": "Id", "type": "string", "format": "uuid" }, "frontend_message_id": { "title": "Frontend Message Id", "type": "string" + }, + "text": { + "title": "Text", + "type": "string" + }, + "is_assistant": { + "title": "Is Assistant", + "type": "boolean" } }, "description": "Represents a message in a conversation between the user and the assistant." }, + "FrontEndUser": { + "title": "FrontEndUser", + "required": [ + "id", + "display_name", + "auth_method", + "user_id", + "enabled", + "deleted", + "notes" + ], + "type": "object", + "properties": { + "id": { + "title": "Id", + "type": "string" + }, + "display_name": { + "title": "Display Name", + "type": "string" + }, + "auth_method": { + "title": "Auth Method", + "enum": [ + "discord", + "local" + ], + "type": "string" + }, + "user_id": { + "title": "User Id", + "type": "string", + "format": "uuid" + }, + "enabled": { + "title": "Enabled", + "type": "boolean" + }, + "deleted": { + "title": "Deleted", + "type": "boolean" + }, + "notes": { + "title": "Notes", + "type": "string" + }, + "created_date": { + "title": "Created Date", + "type": "string", + "format": "date-time" + } + } + }, "HTTPValidationError": { "title": "HTTPValidationError", "type": "object", @@ -1374,7 +2323,9 @@ "detail": { "title": "Detail", "type": "array", - "items": { "$ref": "#/components/schemas/ValidationError" } + "items": { + "$ref": "#/components/schemas/ValidationError" + } } } }, @@ -1382,11 +2333,20 @@ "title": "InitialPromptTask", "type": "object", "properties": { - "hint": { "title": "Hint", "type": "string" }, - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "hint": { + "title": "Hint", + "type": "string" + }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["initial_prompt"], + "enum": [ + "initial_prompt" + ], "type": "string", "default": "initial_prompt" } @@ -1395,67 +2355,133 @@ }, "LabelAssistantReplyTask": { "title": "LabelAssistantReplyTask", - "required": ["conversation", "message_id", "reply", "valid_labels"], + "required": [ + "conversation", + "message_id", + "reply", + "valid_labels" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["label_assistant_reply"], + "enum": [ + "label_assistant_reply" + ], "type": "string", "default": "label_assistant_reply" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "message_id": { "title": "Message Id", "type": "string", "format": "uuid" }, - "reply": { "title": "Reply", "type": "string" }, + "reply": { + "title": "Reply", + "type": "string" + }, "valid_labels": { "title": "Valid Labels", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "mandatory_labels": { + "title": "Mandatory Labels", + "type": "array", + "items": { + "type": "string" + } + }, + "mode": { + "$ref": "#/components/schemas/LabelTaskMode" } }, "description": "A task to label an assistant reply to a conversation." }, "LabelConversationReplyTask": { "title": "LabelConversationReplyTask", - "required": ["conversation", "message_id", "reply", "valid_labels"], + "required": [ + "conversation", + "message_id", + "reply", + "valid_labels" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["label_conversation_reply"], + "enum": [ + "label_conversation_reply" + ], "type": "string", "default": "label_conversation_reply" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "message_id": { "title": "Message Id", "type": "string", "format": "uuid" }, - "reply": { "title": "Reply", "type": "string" }, + "reply": { + "title": "Reply", + "type": "string" + }, "valid_labels": { "title": "Valid Labels", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "mandatory_labels": { + "title": "Mandatory Labels", + "type": "array", + "items": { + "type": "string" + } + }, + "mode": { + "$ref": "#/components/schemas/LabelTaskMode" } }, "description": "A task to label a reply to a conversation." }, "LabelInitialPromptTask": { "title": "LabelInitialPromptTask", - "required": ["message_id", "prompt", "valid_labels"], + "required": [ + "message_id", + "prompt", + "valid_labels" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["label_initial_prompt"], + "enum": [ + "label_initial_prompt" + ], "type": "string", "default": "label_initial_prompt" }, @@ -1464,51 +2490,104 @@ "type": "string", "format": "uuid" }, - "prompt": { "title": "Prompt", "type": "string" }, + "prompt": { + "title": "Prompt", + "type": "string" + }, "valid_labels": { "title": "Valid Labels", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "mandatory_labels": { + "title": "Mandatory Labels", + "type": "array", + "items": { + "type": "string" + } + }, + "mode": { + "$ref": "#/components/schemas/LabelTaskMode" } }, "description": "A task to label an initial prompt." }, "LabelPrompterReplyTask": { "title": "LabelPrompterReplyTask", - "required": ["conversation", "message_id", "reply", "valid_labels"], + "required": [ + "conversation", + "message_id", + "reply", + "valid_labels" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["label_prompter_reply"], + "enum": [ + "label_prompter_reply" + ], "type": "string", "default": "label_prompter_reply" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "message_id": { "title": "Message Id", "type": "string", "format": "uuid" }, - "reply": { "title": "Reply", "type": "string" }, + "reply": { + "title": "Reply", + "type": "string" + }, "valid_labels": { "title": "Valid Labels", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "mandatory_labels": { + "title": "Mandatory Labels", + "type": "array", + "items": { + "type": "string" + } + }, + "mode": { + "$ref": "#/components/schemas/LabelTaskMode" } }, "description": "A task to label a prompter reply to a conversation." }, + "LabelTaskMode": { + "title": "LabelTaskMode", + "enum": [ + "simple", + "full" + ], + "type": "string", + "description": "Label task mode that allows frontends to select an appropriate UI." + }, "Message": { "title": "Message", - "required": ["text", "is_assistant", "id"], + "required": [ + "text", + "is_assistant" + ], "type": "object", "properties": { - "text": { "title": "Text", "type": "string" }, - "is_assistant": { "title": "Is Assistant", "type": "boolean" }, - "message_id": { - "title": "Message Id", + "id": { + "title": "Id", "type": "string", "format": "uuid" }, @@ -1516,7 +2595,14 @@ "title": "Frontend Message Id", "type": "string" }, - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "text": { + "title": "Text", + "type": "string" + }, + "is_assistant": { + "title": "Is Assistant", + "type": "boolean" + }, "parent_id": { "title": "Parent Id", "type": "string", @@ -1532,42 +2618,66 @@ }, "MessageRanking": { "title": "MessageRanking", - "required": ["user", "message_id", "ranking"], + "required": [ + "user", + "message_id", + "ranking" + ], "type": "object", "properties": { "type": { "title": "Type", - "enum": ["message_ranking"], + "enum": [ + "message_ranking" + ], "type": "string", "default": "message_ranking" }, - "user": { "$ref": "#/components/schemas/User" }, - "message_id": { "title": "Message Id", "type": "string" }, + "user": { + "$ref": "#/components/schemas/User" + }, + "message_id": { + "title": "Message Id", + "type": "string" + }, "ranking": { "title": "Ranking", "minItems": 1, "type": "array", - "items": { "type": "integer" } + "items": { + "type": "integer" + } } }, "description": "A user has given a ranking for a message." }, "MessageRating": { "title": "MessageRating", - "required": ["user", "message_id", "rating"], + "required": [ + "user", + "message_id", + "rating" + ], "type": "object", "properties": { "type": { "title": "Type", - "enum": ["message_rating"], + "enum": [ + "message_rating" + ], "type": "string", "default": "message_rating" }, - "user": { "$ref": "#/components/schemas/User" }, - "message_id": { "title": "Message Id", "type": "string" }, + "user": { + "$ref": "#/components/schemas/User" + }, + "message_id": { + "title": "Message Id", + "type": "string" + }, "rating": { "title": "Rating", - "exclusiveMinimum": 0.0, + "exclusiveMinimum": 0, "type": "integer" } }, @@ -1575,14 +2685,22 @@ }, "MessageTree": { "title": "MessageTree", - "required": ["id"], + "required": [ + "id" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "messages": { "title": "Messages", "type": "array", - "items": { "$ref": "#/components/schemas/Message" }, + "items": { + "$ref": "#/components/schemas/Message" + }, "default": [] } }, @@ -1590,164 +2708,310 @@ }, "PrompterReplyTask": { "title": "PrompterReplyTask", - "required": ["conversation"], + "required": [ + "conversation" + ], "type": "object", "properties": { - "hint": { "title": "Hint", "type": "string" }, - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "hint": { + "title": "Hint", + "type": "string" + }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["prompter_reply"], + "enum": [ + "prompter_reply" + ], "type": "string", "default": "prompter_reply" }, - "conversation": { "$ref": "#/components/schemas/Conversation" } + "conversation": { + "$ref": "#/components/schemas/Conversation" + } }, "description": "A task to prompt the user to submit a reply to the assistant." }, "RankAssistantRepliesTask": { "title": "RankAssistantRepliesTask", - "required": ["conversation", "replies"], + "required": [ + "conversation", + "replies", + "reply_messages" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["rank_assistant_replies"], + "enum": [ + "rank_assistant_replies" + ], "type": "string", "default": "rank_assistant_replies" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "replies": { "title": "Replies", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "reply_messages": { + "title": "Reply Messages", + "type": "array", + "items": { + "$ref": "#/components/schemas/ConversationMessage" + } } }, "description": "A task to rank a set of assistant replies to a conversation." }, "RankConversationRepliesTask": { "title": "RankConversationRepliesTask", - "required": ["conversation", "replies"], + "required": [ + "conversation", + "replies", + "reply_messages" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["rank_conversation_replies"], + "enum": [ + "rank_conversation_replies" + ], "type": "string", "default": "rank_conversation_replies" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "replies": { "title": "Replies", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "reply_messages": { + "title": "Reply Messages", + "type": "array", + "items": { + "$ref": "#/components/schemas/ConversationMessage" + } } }, "description": "A task to rank a set of replies to a conversation." }, "RankInitialPromptsTask": { "title": "RankInitialPromptsTask", - "required": ["prompts"], + "required": [ + "prompts", + "prompt_messages" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["rank_initial_prompts"], + "enum": [ + "rank_initial_prompts" + ], "type": "string", "default": "rank_initial_prompts" }, "prompts": { "title": "Prompts", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "prompt_messages": { + "title": "Prompt Messages", + "type": "array", + "items": { + "$ref": "#/components/schemas/ConversationMessage" + } } }, "description": "A task to rank a set of initial prompts." }, "RankPrompterRepliesTask": { "title": "RankPrompterRepliesTask", - "required": ["conversation", "replies"], + "required": [ + "conversation", + "replies", + "reply_messages" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["rank_prompter_replies"], + "enum": [ + "rank_prompter_replies" + ], "type": "string", "default": "rank_prompter_replies" }, - "conversation": { "$ref": "#/components/schemas/Conversation" }, + "conversation": { + "$ref": "#/components/schemas/Conversation" + }, "replies": { "title": "Replies", "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } + }, + "reply_messages": { + "title": "Reply Messages", + "type": "array", + "items": { + "$ref": "#/components/schemas/ConversationMessage" + } } }, "description": "A task to rank a set of prompter replies to a conversation." }, "RateSummaryTask": { "title": "RateSummaryTask", - "required": ["full_text", "summary"], + "required": [ + "full_text", + "summary" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["rate_summary"], + "enum": [ + "rate_summary" + ], "type": "string", "default": "rate_summary" }, "scale": { "title": "Scale", - "allOf": [{ "$ref": "#/components/schemas/RatingScale" }], - "default": { "min": 1, "max": 5 } + "allOf": [ + { + "$ref": "#/components/schemas/RatingScale" + } + ], + "default": { + "min": 1, + "max": 5 + } }, - "full_text": { "title": "Full Text", "type": "string" }, - "summary": { "title": "Summary", "type": "string" } + "full_text": { + "title": "Full Text", + "type": "string" + }, + "summary": { + "title": "Summary", + "type": "string" + } }, "description": "A task to rate a summary." }, "RatingScale": { "title": "RatingScale", - "required": ["min", "max"], + "required": [ + "min", + "max" + ], "type": "object", "properties": { - "min": { "title": "Min", "type": "integer" }, - "max": { "title": "Max", "type": "integer" } + "min": { + "title": "Min", + "type": "integer" + }, + "max": { + "title": "Max", + "type": "integer" + } } }, "ReplyToConversationTask": { "title": "ReplyToConversationTask", - "required": ["conversation"], + "required": [ + "conversation" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["reply_to_conversation"], + "enum": [ + "reply_to_conversation" + ], "type": "string", "default": "reply_to_conversation" }, - "conversation": { "$ref": "#/components/schemas/Conversation" } + "conversation": { + "$ref": "#/components/schemas/Conversation" + } }, "description": "A task to prompt the user to submit a reply to a conversation." }, "SummarizeStoryTask": { "title": "SummarizeStoryTask", - "required": ["story"], + "required": [ + "story" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["summarize_story"], + "enum": [ + "summarize_story" + ], "type": "string", "default": "summarize_story" }, - "story": { "title": "Story", "type": "string" } + "story": { + "title": "Story", + "type": "string" + } }, "description": "A task to summarize a story." }, @@ -1755,9 +3019,21 @@ "title": "SystemStats", "type": "object", "properties": { - "all": { "title": "All", "type": "integer", "default": 0 }, - "active": { "title": "Active", "type": "integer", "default": 0 }, - "deleted": { "title": "Deleted", "type": "integer", "default": 0 }, + "all": { + "title": "All", + "type": "integer", + "default": 0 + }, + "active": { + "title": "Active", + "type": "integer", + "default": 0 + }, + "deleted": { + "title": "Deleted", + "type": "integer", + "default": 0 + }, "message_trees": { "title": "Message Trees", "type": "integer", @@ -1767,19 +3043,29 @@ }, "TaskAck": { "title": "TaskAck", - "required": ["message_id"], + "required": [ + "message_id" + ], "type": "object", "properties": { - "message_id": { "title": "Message Id", "type": "string" } + "message_id": { + "title": "Message Id", + "type": "string" + } }, "description": "The frontend acknowledges that it has received a task and created a message." }, "TaskClose": { "title": "TaskClose", - "required": ["message_id"], + "required": [ + "message_id" + ], "type": "object", "properties": { - "message_id": { "title": "Message Id", "type": "string" } + "message_id": { + "title": "Message Id", + "type": "string" + } }, "description": "The frontend asks to mark task as done" }, @@ -1787,10 +3073,16 @@ "title": "TaskDone", "type": "object", "properties": { - "id": { "title": "Id", "type": "string", "format": "uuid" }, + "id": { + "title": "Id", + "type": "string", + "format": "uuid" + }, "type": { "title": "Type", - "enum": ["task_done"], + "enum": [ + "task_done" + ], "type": "string", "default": "task_done" } @@ -1799,9 +3091,16 @@ }, "TaskNAck": { "title": "TaskNAck", - "required": ["reason"], + "required": [ + "reason" + ], "type": "object", - "properties": { "reason": { "title": "Reason", "type": "string" } }, + "properties": { + "reason": { + "title": "Reason", + "type": "string" + } + }, "description": "The frontend acknowledges that it has received a task but cannot create a message." }, "TaskRequest": { @@ -1809,12 +3108,20 @@ "type": "object", "properties": { "type": { - "allOf": [{ "$ref": "#/components/schemas/TaskRequestType" }], + "allOf": [ + { + "$ref": "#/components/schemas/TaskRequestType" + } + ], "default": "random" }, "user": { "title": "User", - "allOf": [{ "$ref": "#/components/schemas/User" }], + "allOf": [ + { + "$ref": "#/components/schemas/User" + } + ], "nullable": true }, "collective": { @@ -1846,80 +3153,158 @@ }, "TextLabels": { "title": "TextLabels", - "required": ["user", "text", "labels", "message_id"], + "required": [ + "user", + "text", + "labels", + "message_id" + ], "type": "object", "properties": { "type": { "title": "Type", - "enum": ["text_labels"], + "enum": [ + "text_labels" + ], "type": "string", "default": "text_labels" }, - "user": { "$ref": "#/components/schemas/User" }, - "text": { "title": "Text", "type": "string" }, + "user": { + "$ref": "#/components/schemas/User" + }, + "text": { + "title": "Text", + "type": "string" + }, "labels": { "title": "Labels", "type": "object", - "additionalProperties": { "type": "number" } + "additionalProperties": { + "type": "number" + } }, "message_id": { "title": "Message Id", "type": "string", "format": "uuid" + }, + "task_id": { + "title": "Task Id", + "type": "string", + "format": "uuid" } }, "description": "A set of labels for a piece of text." }, "TextReplyToMessage": { "title": "TextReplyToMessage", - "required": ["user", "message_id", "user_message_id", "text"], + "required": [ + "user", + "message_id", + "user_message_id", + "text" + ], "type": "object", "properties": { "type": { "title": "Type", - "enum": ["text_reply_to_message"], + "enum": [ + "text_reply_to_message" + ], "type": "string", "default": "text_reply_to_message" }, - "user": { "$ref": "#/components/schemas/User" }, - "message_id": { "title": "Message Id", "type": "string" }, - "user_message_id": { "title": "User Message Id", "type": "string" }, - "text": { "title": "Text", "minLength": 1, "type": "string" } + "user": { + "$ref": "#/components/schemas/User" + }, + "message_id": { + "title": "Message Id", + "type": "string" + }, + "user_message_id": { + "title": "User Message Id", + "type": "string" + }, + "text": { + "title": "Text", + "minLength": 1, + "type": "string" + } }, "description": "A user has replied to a message with text." }, "User": { "title": "User", - "required": ["id", "display_name", "auth_method"], + "required": [ + "id", + "display_name", + "auth_method" + ], "type": "object", "properties": { - "id": { "title": "Id", "type": "string" }, - "display_name": { "title": "Display Name", "type": "string" }, + "id": { + "title": "Id", + "type": "string" + }, + "display_name": { + "title": "Display Name", + "type": "string" + }, "auth_method": { "title": "Auth Method", - "enum": ["discord", "local"], + "enum": [ + "discord", + "local" + ], "type": "string" } } }, "ValidationError": { "title": "ValidationError", - "required": ["loc", "msg", "type"], + "required": [ + "loc", + "msg", + "type" + ], "type": "object", "properties": { "loc": { "title": "Location", "type": "array", - "items": { "anyOf": [{ "type": "string" }, { "type": "integer" }] } + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + } }, - "msg": { "title": "Message", "type": "string" }, - "type": { "title": "Error Type", "type": "string" } + "msg": { + "title": "Message", + "type": "string" + }, + "type": { + "title": "Error Type", + "type": "string" + } } } }, "securitySchemes": { - "APIKeyQuery": { "type": "apiKey", "in": "query", "name": "api_key" }, - "APIKeyHeader": { "type": "apiKey", "in": "header", "name": "X-API-Key" } + "APIKeyQuery": { + "type": "apiKey", + "in": "query", + "name": "api_key" + }, + "APIKeyHeader": { + "type": "apiKey", + "in": "header", + "name": "X-API-Key" + } } } } diff --git a/docs/docs/tasks/README.md b/docs/docs/tasks/README.md new file mode 100644 index 00000000..c859d394 --- /dev/null +++ b/docs/docs/tasks/README.md @@ -0,0 +1,8 @@ +# Tasks + +Understand a bit more about each type of Open Assistant labeling task. + +- [Label Assistant Reply](label_assistant_reply.md) +- [Label Prompter Reply](label_prompter_reply.md) +- [Reply as Assistant](reply_as_assistant.md) +- [Reply as User](reply_as_user.md) diff --git a/docs/docs/tasks/label_assistant_reply.md b/docs/docs/tasks/label_assistant_reply.md new file mode 100644 index 00000000..d38cff8f --- /dev/null +++ b/docs/docs/tasks/label_assistant_reply.md @@ -0,0 +1,3 @@ +# Label Assistant Reply + +Given the following discussion, provide labels for the final prompt. diff --git a/docs/docs/tasks/label_prompter_reply.md b/docs/docs/tasks/label_prompter_reply.md new file mode 100644 index 00000000..8ec4a261 --- /dev/null +++ b/docs/docs/tasks/label_prompter_reply.md @@ -0,0 +1,3 @@ +# Label Prompter Reply + +Given the following discussion, provide labels for the final prompt. diff --git a/docs/docs/tasks/reply_as_assistant.md b/docs/docs/tasks/reply_as_assistant.md new file mode 100644 index 00000000..a9a71250 --- /dev/null +++ b/docs/docs/tasks/reply_as_assistant.md @@ -0,0 +1,3 @@ +# Reply as Assistant + +Given the following conversation, provide an adequate reply. diff --git a/docs/docs/tasks/reply_as_user.md b/docs/docs/tasks/reply_as_user.md new file mode 100644 index 00000000..b1bf63b5 --- /dev/null +++ b/docs/docs/tasks/reply_as_user.md @@ -0,0 +1,3 @@ +# Reply as User + +Given the following conversation, provide an adequate reply. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index dfd2c6e5..c3327c77 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -32,12 +32,15 @@ const config = { presets: [ [ - "classic", + "docusaurus-preset-openapi", /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { sidebarPath: require.resolve("./sidebars.js"), }, + api: { + path: "docs/api/openapi.json", + }, blog: false, theme: { customCss: require.resolve("./src/css/custom.css"), @@ -62,11 +65,7 @@ const config = { position: "left", label: "Docs", }, - { - href: "https://editor.swagger.io/?url=https://raw.githubusercontent.com/LAION-AI/Open-Assistant/main/docs/docs/api/openapi.json", - label: "API", - position: "left", - }, + { to: "/api", label: "API", position: "left" }, { href: "https://github.com/LAION-AI/Open-Assistant", label: "GitHub", diff --git a/docs/package.json b/docs/package.json index c7dd70f1..de35a1a1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,9 +19,11 @@ "@docusaurus/preset-classic": "2.2.0", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", + "docusaurus-preset-openapi": "^0.6.3", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "url": "^0.11.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "2.2.0", diff --git a/docs/sidebars.js b/docs/sidebars.js index d928324e..2f7baedf 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -24,6 +24,20 @@ const sidebars = { }, items: ["guides/prompting"], }, + { + type: "category", + label: "Tasks", + link: { + type: "doc", + id: "tasks/README", + }, + items: [ + "tasks/label_assistant_reply", + "tasks/label_prompter_reply", + "tasks/reply_as_assistant", + "tasks/reply_as_user", + ], + }, { type: "category", label: "Data", diff --git a/docs/yarn.lock b/docs/yarn.lock index 560bf037..da04c19f 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1137,7 +1137,7 @@ core-js-pure "^3.25.1" regenerator-runtime "^0.13.11" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.6", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== @@ -1293,7 +1293,7 @@ chalk "^4.1.2" tslib "^2.4.0" -"@docusaurus/mdx-loader@2.2.0": +"@docusaurus/mdx-loader@2.2.0", "@docusaurus/mdx-loader@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.2.0.tgz#fd558f429e5d9403d284bd4214e54d9768b041a0" integrity sha512-X2bzo3T0jW0VhUU+XdQofcEeozXOTmKQMvc8tUnWRdTnCvj4XEcBVdC3g+/jftceluiwSTNRAX4VBOJdNt18jA== @@ -1352,7 +1352,7 @@ utility-types "^3.10.0" webpack "^5.73.0" -"@docusaurus/plugin-content-docs@2.2.0": +"@docusaurus/plugin-content-docs@2.2.0", "@docusaurus/plugin-content-docs@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.2.0.tgz#0fcb85226fcdb80dc1e2d4a36ef442a650dcc84d" integrity sha512-BOazBR0XjzsHE+2K1wpNxz5QZmrJgmm3+0Re0EVPYFGW8qndCWGNtXW/0lGKhecVPML8yyFeAmnUCIs7xM2wPw== @@ -1435,7 +1435,7 @@ sitemap "^7.1.1" tslib "^2.4.0" -"@docusaurus/preset-classic@2.2.0": +"@docusaurus/preset-classic@2.2.0", "@docusaurus/preset-classic@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.2.0.tgz#bece5a043eeb74430f7c6c7510000b9c43669eb7" integrity sha512-yKIWPGNx7BT8v2wjFIWvYrS+nvN04W+UameSFf8lEiJk6pss0kL6SG2MRvyULiI3BDxH+tj6qe02ncpSPGwumg== @@ -1492,7 +1492,7 @@ tslib "^2.4.0" utility-types "^3.10.0" -"@docusaurus/theme-common@2.2.0": +"@docusaurus/theme-common@2.2.0", "@docusaurus/theme-common@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.2.0.tgz#2303498d80448aafdd588b597ce9d6f4cfa930e4" integrity sha512-R8BnDjYoN90DCL75gP7qYQfSjyitXuP9TdzgsKDmSFPNyrdE3twtPNa2dIN+h+p/pr+PagfxwWbd6dn722A1Dw== @@ -1563,7 +1563,7 @@ dependencies: tslib "^2.4.0" -"@docusaurus/utils-validation@2.2.0": +"@docusaurus/utils-validation@2.2.0", "@docusaurus/utils-validation@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.2.0.tgz#04d4d103137ad0145883971d3aa497f4a1315f25" integrity sha512-I1hcsG3yoCkasOL5qQAYAfnmVoLei7apugT6m4crQjmDGxq+UkiRrq55UqmDDyZlac/6ax/JC0p+usZ6W4nVyg== @@ -1574,7 +1574,7 @@ js-yaml "^4.1.0" tslib "^2.4.0" -"@docusaurus/utils@2.2.0": +"@docusaurus/utils@2.2.0", "@docusaurus/utils@^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.2.0.tgz#3d6f9b7a69168d5c92d371bf21c556a4f50d1da6" integrity sha512-oNk3cjvx7Tt1Lgh/aeZAmFpGV2pDr5nHKrBVx6hTkzGhrnMuQqLt6UPlQjdYQ3QHXwyF/ZtZMO1D5Pfi0lu7SA== @@ -1595,6 +1595,11 @@ url-loader "^4.1.1" webpack "^5.73.0" +"@faker-js/faker@5.5.3": + version "5.5.3" + resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-5.5.3.tgz#18e3af6b8eae7984072bbeb0c0858474d7c4cefe" + integrity sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw== + "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -1714,6 +1719,21 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== +"@monaco-editor/loader@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.3.2.tgz#04effbb87052d19cd7d3c9d81c0635490f9bb6d8" + integrity sha512-BTDbpHl3e47r3AAtpfVFTlAi7WXv4UQ/xZmz8atKl4q7epQV5e7+JbigFDViWF71VBi4IIBdcWP57Hj+OWuc9g== + dependencies: + state-local "^1.0.6" + +"@monaco-editor/react@^4.3.1": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.4.6.tgz#8ae500b0edf85276d860ed702e7056c316548218" + integrity sha512-Gr3uz3LYf33wlFE3eRnta4RxP5FSNxiIV9ENn2D2/rN8KgGAD8ecvcITRtsbbyuOuNkwbuHYxfeaz2Vr+CtyFA== + dependencies: + "@monaco-editor/loader" "^1.3.2" + prop-types "^15.7.2" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1740,6 +1760,16 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== +"@reduxjs/toolkit@^1.7.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.1.tgz#4c34dc4ddcec161535288c60da5c19c3ef15180e" + integrity sha512-HikrdY+IDgRfRYlCTGUQaiCxxDDgM1mQrRbZ6S1HFZX5ZYuJ4o8EstNmhTwHdPl2rTmLxzwSu0b3AyeyTlR+RA== + dependencies: + immer "^9.0.16" + redux "^4.2.0" + redux-thunk "^2.4.2" + reselect "^4.1.7" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -1986,6 +2016,14 @@ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" @@ -2069,6 +2107,16 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/react-redux@^7.1.20": + version "7.1.25" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.25.tgz#de841631205b24f9dfb4967dd4a7901e048f9a88" + integrity sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react-router-config@*", "@types/react-router-config@^5.0.6": version "5.0.6" resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.6.tgz#87c5c57e72d241db900d9734512c50ccec062451" @@ -2353,6 +2401,16 @@ ajv-keywords@^5.0.0: dependencies: fast-deep-equal "^3.1.3" +ajv@6.12.3: + version "6.12.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -2481,11 +2539,33 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asap@~2.0.3: +array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +asap@^2.0.0, asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +async@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -2510,6 +2590,13 @@ axios@^0.25.0: dependencies: follow-redirects "^1.14.7" +axios@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" + integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== + dependencies: + follow-redirects "^1.14.8" + babel-loader@^8.2.5: version "8.3.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" @@ -2581,6 +2668,11 @@ base16@^1.0.0: resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" integrity sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -2687,6 +2779,14 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2736,6 +2836,11 @@ camelcase-css@2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" @@ -2756,12 +2861,12 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e" integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg== -ccount@^1.0.0: +ccount@^1.0.0, ccount@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2793,6 +2898,11 @@ character-reference-invalid@^1.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +charset@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/charset/-/charset-1.0.1.tgz#8d59546c355be61049a8fa9164747793319852bd" + integrity sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg== + cheerio-select@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" @@ -2879,6 +2989,15 @@ cli-table3@^0.6.2: optionalDependencies: "@colors/colors" "1.5.0" +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -2895,7 +3014,7 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -clsx@^1.2.1: +clsx@^1.1.1, clsx@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -2944,12 +3063,19 @@ combine-promises@^1.1.0: resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.1.0.tgz#72db90743c0ca7aab7d0d8d2052fd7b0f674de71" integrity sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + comma-separated-tokens@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -commander@^2.20.0: +commander@2.20.3, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2969,11 +3095,21 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@~4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== +component-emitter@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + compressible@~2.0.16: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -3053,6 +3189,11 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookiejar@^2.1.3: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + copy-text-to-clipboard@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c" @@ -3130,6 +3271,11 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypto-js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" + integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -3286,13 +3432,18 @@ debug@2.6.9, debug@^2.6.0: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" @@ -3349,6 +3500,11 @@ del@^6.1.1: rimraf "^3.0.2" slash "^3.0.0" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -3392,6 +3548,14 @@ detect-port@^1.3.0: address "^1.0.1" debug "4" +dezalgo@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -3411,6 +3575,68 @@ dns-packet@^5.2.2: dependencies: "@leichtgewicht/ip-codec" "^2.0.1" +docusaurus-plugin-openapi@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/docusaurus-plugin-openapi/-/docusaurus-plugin-openapi-0.6.3.tgz#03049eb843211a6fa36d7209dfd278438bfdcf01" + integrity sha512-2i/f4zfW5aCNe8Ids6WsgSPQHFEdAwvhoe0lwb83QkNE33bYerZmoqSjJr6wSZsAEsb1HkDW+JLZNxkjSAHe2w== + dependencies: + "@docusaurus/mdx-loader" "^2.0.0" + "@docusaurus/plugin-content-docs" "^2.0.0" + "@docusaurus/utils" "^2.0.0" + "@docusaurus/utils-validation" "^2.0.0" + axios "^0.26.1" + chalk "^4.1.2" + clsx "^1.1.1" + fs-extra "^9.0.1" + js-yaml "^4.1.0" + json-refs "^3.0.15" + json-schema-resolve-allof "^1.5.0" + lodash "^4.17.20" + openapi-to-postmanv2 "^1.2.1" + postman-collection "^4.1.0" + remark-admonitions "^1.2.1" + webpack "^5.73.0" + +docusaurus-plugin-proxy@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/docusaurus-plugin-proxy/-/docusaurus-plugin-proxy-0.6.3.tgz#4ef3193e49ef851a3b5b57f349e3549c41a7a20e" + integrity sha512-HAR76IsuSWlVI1K6P8fEJDjhHxT3LLdXGr+ZxNBm6DJTUQ8Xf057nHR8BhB5sfwmzrDPup5wChP/nuOVAfU6wg== + +docusaurus-preset-openapi@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/docusaurus-preset-openapi/-/docusaurus-preset-openapi-0.6.3.tgz#31537616923bd374884aa41a38670515480ccc65" + integrity sha512-zAkQE9SrA4WannHjLhO6PX8QaSqKVATDjFF/ZEj+0jmCikoBzyvsvh+qSGHszAb0Gkg/vKrAXYYBs/Iq1a4O7Q== + dependencies: + "@docusaurus/preset-classic" "^2.0.0" + docusaurus-plugin-openapi "^0.6.3" + docusaurus-plugin-proxy "^0.6.3" + docusaurus-theme-openapi "^0.6.3" + +docusaurus-theme-openapi@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/docusaurus-theme-openapi/-/docusaurus-theme-openapi-0.6.3.tgz#eace4982a6d969b4c4f8fad85478d283553126b9" + integrity sha512-9cFFbfP2arRHxs/HgSX4phbfpwawN1sxY8H8REZYiqwzEpirNE++qkz507K3bYz7WfOqYwYJAITkPtnPaKzjag== + dependencies: + "@docusaurus/theme-common" "^2.0.0" + "@mdx-js/react" "^1.6.22" + "@monaco-editor/react" "^4.3.1" + "@reduxjs/toolkit" "^1.7.1" + buffer "^6.0.3" + clsx "^1.1.1" + crypto-js "^4.1.1" + docusaurus-plugin-openapi "^0.6.3" + immer "^9.0.7" + lodash "^4.17.20" + monaco-editor "^0.31.1" + postman-code-generators "^1.0.0" + postman-collection "^4.1.0" + prism-react-renderer "^1.2.1" + process "^0.11.10" + react-magic-dropzone "^1.0.1" + react-redux "^7.2.0" + redux-devtools-extension "^2.13.8" + webpack "^5.73.0" + dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -3418,6 +3644,14 @@ dom-converter@^0.2.0: dependencies: utila "~0.4" +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + dom-serializer@^1.0.1: version "1.4.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" @@ -3436,11 +3670,23 @@ dom-serializer@^2.0.0: domhandler "^5.0.2" entities "^4.2.0" +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" @@ -3455,6 +3701,14 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" @@ -3553,6 +3807,11 @@ enhanced-resolve@^5.10.0: graceful-fs "^4.2.4" tapable "^2.2.0" +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -3585,7 +3844,7 @@ escape-goat@^2.0.0: resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== -escape-html@^1.0.3, escape-html@~1.0.3: +escape-html@1.0.3, escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== @@ -3727,6 +3986,16 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +faker@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-5.1.0.tgz#e10fa1dec4502551aee0eb771617a7e7b94692e8" + integrity sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw== + +faker@5.5.3: + version "5.5.3" + resolved "https://registry.yarnpkg.com/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e" + integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3748,6 +4017,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-safe-stringify@^2.0.7, fast-safe-stringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + fast-url-parser@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" @@ -3809,6 +4083,11 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" +file-type@3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + filesize@^8.0.6: version "8.0.7" resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" @@ -3850,7 +4129,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3874,7 +4153,7 @@ flux@^4.0.1: fbemitter "^3.0.0" fbjs "^3.0.1" -follow-redirects@^1.0.0, follow-redirects@^1.14.7: +follow-redirects@^1.0.0, follow-redirects@^1.14.7, follow-redirects@^1.14.8: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -3898,6 +4177,25 @@ fork-ts-checker-webpack-plugin@^6.5.0: semver "^7.3.2" tapable "^1.0.0" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formidable@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-2.1.1.tgz#81269cbea1a613240049f5f61a9d97731517414f" + integrity sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ== + dependencies: + dezalgo "^1.0.4" + hexoid "^1.0.0" + once "^1.4.0" + qs "^6.11.0" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -3922,7 +4220,7 @@ fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0: +fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -3957,6 +4255,11 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" @@ -3971,6 +4274,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA== + get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -4099,6 +4407,13 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== + dependencies: + lodash "^4.17.15" + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -4168,6 +4483,17 @@ hast-to-hyperscript@^9.0.0: unist-util-is "^4.0.0" web-namespaces "^1.0.0" +hast-util-from-parse5@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz#3089dc0ee2ccf6ec8bc416919b51a54a589e097c" + integrity sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA== + dependencies: + ccount "^1.0.3" + hastscript "^5.0.0" + property-information "^5.0.0" + web-namespaces "^1.1.2" + xtend "^4.0.1" + hast-util-from-parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" @@ -4212,6 +4538,16 @@ hast-util-to-parse5@^6.0.0: xtend "^4.0.0" zwitch "^1.0.0" +hastscript@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" + integrity sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -4228,6 +4564,11 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hexoid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" + integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== + history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" @@ -4240,7 +4581,7 @@ history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hoist-non-react-statics@^3.1.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -4296,6 +4637,18 @@ html-webpack-plugin@^5.5.0: pretty-error "^4.0.0" tapable "^2.0.0" +htmlparser2@^3.10.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + htmlparser2@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" @@ -4372,6 +4725,16 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-reasons@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/http-reasons/-/http-reasons-0.1.0.tgz#a953ca670078669dde142ce899401b9d6e85d3b4" + integrity sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ== + +http2-client@^1.2.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/http2-client/-/http2-client-1.3.5.tgz#20c9dc909e3cc98284dd20af2432c524086df181" + integrity sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -4384,11 +4747,30 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" + integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -4401,7 +4783,7 @@ image-size@^1.0.1: dependencies: queue "6.0.2" -immer@^9.0.7: +immer@^9.0.16, immer@^9.0.7: version "9.0.17" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.17.tgz#7cfe8fbb8b461096444e9da7a5ec4a67c6c4adf4" integrity sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg== @@ -4734,6 +5116,14 @@ joi@^17.6.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" @@ -4769,6 +5159,28 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-refs@^3.0.15: + version "3.0.15" + resolved "https://registry.yarnpkg.com/json-refs/-/json-refs-3.0.15.tgz#1089f4acf263a3152c790479485195cd6449e855" + integrity sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw== + dependencies: + commander "~4.1.1" + graphlib "^2.1.8" + js-yaml "^3.13.1" + lodash "^4.17.15" + native-promise-only "^0.8.1" + path-loader "^1.0.10" + slash "^3.0.0" + uri-js "^4.2.2" + +json-schema-resolve-allof@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/json-schema-resolve-allof/-/json-schema-resolve-allof-1.5.0.tgz#06acbd1077a69d1e8d262055192fe000bb661fcb" + integrity sha512-Jgn6BQGSLDp3D7bTYrmCbP/p7SRFz5BfpeEJ9A7sXuVADMc14aaDN1a49zqk9D26wwJlcNvjRpT63cz1VgFZeg== + dependencies: + get-stdin "^5.0.1" + lodash "^4.14.0" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -4837,6 +5249,11 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +liquid-json@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/liquid-json/-/liquid-json-0.3.1.tgz#9155a18136d8a6b2615e5f16f9a2448ab6b50eea" + integrity sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ== + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -4878,6 +5295,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.curry@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" @@ -4888,22 +5310,47 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw== + lodash.flow@^3.3.0: version "3.5.0" resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" integrity sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw== +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== +lodash.mergewith@^4.6.1: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash.uniq@4.5.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash@4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lodash@4.17.21, lodash@^4.14.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4958,6 +5405,16 @@ markdown-escapes@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== +marked@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/marked/-/marked-1.1.1.tgz#e5d61b69842210d5df57b05856e0c91572703e6a" + integrity sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw== + +marked@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.1.tgz#5e7ed7009bfa5c95182e4eb696f85e948cefcee3" + integrity sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw== + mdast-squeeze-paragraphs@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" @@ -5028,7 +5485,7 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@~1.1.2: +methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== @@ -5041,6 +5498,16 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-db@1.47.0: + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== + mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -5051,6 +5518,20 @@ mime-db@~1.33.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== +mime-format@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mime-format/-/mime-format-2.0.0.tgz#e29f8891e284d78270246f0050d6834bdbbe1332" + integrity sha512-sv1KDeJFutfXbT+MpIuExruuVZ7LSNQVHIxf7IZVr0a/qWKcHY8DHklWoO6CWf7QnGLl0eC8vBEghl5paWSqqg== + dependencies: + charset "^1.0.0" + +mime-format@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mime-format/-/mime-format-2.0.1.tgz#1274876d58bc803332427a515f5f7036e07b9413" + integrity sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg== + dependencies: + charset "^1.0.0" + mime-types@2.1.18: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" @@ -5058,7 +5539,21 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@2.1.27: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime-types@2.1.30: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + dependencies: + mime-db "1.47.0" + +mime-types@2.1.35, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -5070,6 +5565,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -5104,6 +5604,11 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +monaco-editor@^0.31.1: + version "0.31.1" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.31.1.tgz#67f597b3e45679d1f551237e12a3a42c4438b97b" + integrity sha512-FYPwxGZAeP6mRRyrr5XTGHD9gRXVjy7GUzF4IPChnyt3fS5WrNxIkS8DNujWf6EQy0Zlzpxw8oTVE+mWI2/D1Q== + mrmime@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" @@ -5137,6 +5642,11 @@ nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +native-promise-only@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" + integrity sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg== + negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -5162,6 +5672,13 @@ node-emoji@^1.10.0: dependencies: lodash "^4.17.21" +node-fetch-h2@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz#c6188325f9bd3d834020bf0f2d6dc17ced2241ac" + integrity sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg== + dependencies: + http2-client "^1.2.5" + node-fetch@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -5218,6 +5735,30 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +oas-kit-common@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/oas-kit-common/-/oas-kit-common-1.0.8.tgz#6d8cacf6e9097967a4c7ea8bcbcbd77018e1f535" + integrity sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ== + dependencies: + fast-safe-stringify "^2.0.7" + +oas-resolver-browser@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/oas-resolver-browser/-/oas-resolver-browser-2.3.3.tgz#e8c1bcb587dcb92a5ca008674bc26aed460612f9" + integrity sha512-KvggQ6xU7WlUWRYZKEktR90zJtNCHi1wbTAZuUX6oSfmBSdZo/b26rzfg3w2AdPVwQPRXMga6tqLW3OhbUF0Qg== + dependencies: + node-fetch-h2 "^2.3.0" + oas-kit-common "^1.0.8" + path-browserify "^1.0.1" + reftools "^1.1.1" + yaml "^1.8.3" + yargs "^15.3.1" + object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -5283,6 +5824,21 @@ open@^8.0.9, open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" +openapi-to-postmanv2@^1.2.1: + version "1.2.7" + resolved "https://registry.yarnpkg.com/openapi-to-postmanv2/-/openapi-to-postmanv2-1.2.7.tgz#920ab286b080914d6afd18bb9ad37929cbd2dff3" + integrity sha512-oG3PZfAAljy5ebot8DZGLFDNNmDZ/qWqI/dboWlgg5hRj6dSSrXeiyXL6VQpcGDalxVX4jSChufOq2eDsFXp4w== + dependencies: + ajv "6.12.3" + async "3.2.0" + commander "2.20.3" + js-yaml "3.13.1" + lodash "4.17.20" + oas-resolver-browser "2.3.3" + path-browserify "1.0.1" + postman-collection "3.6.6" + yaml "1.8.3" + opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" @@ -5408,6 +5964,11 @@ parse5-htmlparser2-tree-adapter@^7.0.0: domhandler "^5.0.2" parse5 "^7.0.0" +parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -5433,6 +5994,11 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" +path-browserify@1.0.1, path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -5458,6 +6024,14 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-loader@^1.0.10: + version "1.0.12" + resolved "https://registry.yarnpkg.com/path-loader/-/path-loader-1.0.12.tgz#c5a99d464da27cfde5891d158a68807abbdfa5f5" + integrity sha512-n7oDG8B+k/p818uweWrOixY9/Dsr89o2TkCm6tOTex3fpdo2+BFDgR+KpB37mGKBRsBAlR8CIJMFN0OEy/7hIQ== + dependencies: + native-promise-only "^0.8.1" + superagent "^7.1.6" + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -5485,6 +6059,19 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +path@0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== + dependencies: + process "^0.11.1" + util "^0.10.3" + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -5790,6 +6377,14 @@ postcss-zindex@^5.1.0: resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.1.0.tgz#4a5c7e5ff1050bd4c01d95b1847dfdcc58a496ff" integrity sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A== +postcss@^7.0.5: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + postcss@^8.3.11, postcss@^8.4.14, postcss@^8.4.17, postcss@^8.4.19: version "8.4.20" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" @@ -5799,6 +6394,95 @@ postcss@^8.3.11, postcss@^8.4.14, postcss@^8.4.17, postcss@^8.4.19: picocolors "^1.0.0" source-map-js "^1.0.2" +postman-code-generators@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postman-code-generators/-/postman-code-generators-1.2.2.tgz#29ef1ababdbb1c3c8d207d911f34b6659a30f462" + integrity sha512-5AEeMzzn/jdrnWCUu4oA3W1eXVvpWW60g0YSnK5nLCDA6WZjeaX932I1RW0n16PVs1cyFm7NuVXMs+7NNaZRrA== + dependencies: + async "2.6.3" + path "0.12.7" + postman-collection "3.6.11" + shelljs "0.8.4" + +postman-collection@3.6.11, postman-collection@^3.6.4: + version "3.6.11" + resolved "https://registry.yarnpkg.com/postman-collection/-/postman-collection-3.6.11.tgz#b7932aa98d4334064d4601a042b66a5ebcdd8b58" + integrity sha512-22oIsOXwigdEGQJuTgS44964hj0/gN20E6/aiDoO469WiqqOk5JEEVQpW8zCDjsb9vynyk384JqE9zRyvfrH5A== + dependencies: + escape-html "1.0.3" + faker "5.5.3" + file-type "3.9.0" + http-reasons "0.1.0" + iconv-lite "0.6.2" + liquid-json "0.3.1" + lodash "4.17.21" + marked "2.0.1" + mime-format "2.0.1" + mime-types "2.1.30" + postman-url-encoder "3.0.1" + sanitize-html "1.20.1" + semver "7.3.5" + uuid "3.4.0" + +postman-collection@3.6.6: + version "3.6.6" + resolved "https://registry.yarnpkg.com/postman-collection/-/postman-collection-3.6.6.tgz#f9bc108b078669ae614dc1a18b050a78023ced64" + integrity sha512-fm9AGKHbL2coSzD5nw+F07JrX7jzqu2doGIXevPPrwlpTZyTM6yagEdENeO/Na8rSUrI1+tKPj+TgAFiLvtF4w== + dependencies: + escape-html "1.0.3" + faker "5.1.0" + file-type "3.9.0" + http-reasons "0.1.0" + iconv-lite "0.6.2" + liquid-json "0.3.1" + lodash "4.17.20" + marked "1.1.1" + mime-format "2.0.0" + mime-types "2.1.27" + postman-url-encoder "2.1.3" + sanitize-html "1.20.1" + semver "7.3.2" + uuid "3.4.0" + +postman-collection@^4.1.0: + version "4.1.6" + resolved "https://registry.yarnpkg.com/postman-collection/-/postman-collection-4.1.6.tgz#91746b683f9cc0ef8ddfd961dde66c326a7c48bf" + integrity sha512-9A2PFDS6KDasUTpNRjvbCUkWmVrsfVALsqy1xdnWxwV81jpBS/dvTeoGEM//M12EH9qa7VxZ5O2KrSC2oItEOg== + dependencies: + "@faker-js/faker" "5.5.3" + file-type "3.9.0" + http-reasons "0.1.0" + iconv-lite "0.6.3" + liquid-json "0.3.1" + lodash "4.17.21" + mime-format "2.0.1" + mime-types "2.1.35" + postman-url-encoder "3.0.5" + semver "7.3.8" + uuid "8.3.2" + +postman-url-encoder@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/postman-url-encoder/-/postman-url-encoder-2.1.3.tgz#094342e2da40e8b6b757bfcc8028413800315a5e" + integrity sha512-CwQjnoxaugCGeOyzVeZ4k1cNQ6iS8OBCzuWzcf4kLStKeRp0MwmLKYv25frynmDpugUUimq/d+FZCq6GtIX9Ag== + dependencies: + postman-collection "^3.6.4" + punycode "^2.1.1" + +postman-url-encoder@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postman-url-encoder/-/postman-url-encoder-3.0.1.tgz#a7434a169567c45f022dc435d46a86d71de6a8aa" + integrity sha512-dMPqXnkDlstM2Eya+Gw4MIGWEan8TzldDcUKZIhZUsJ/G5JjubfQPhFhVWKzuATDMvwvrWbSjF+8VmAvbu6giw== + dependencies: + punycode "^2.1.1" + +postman-url-encoder@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz#af2efee3bb7644e2b059d8a78bc8070fae0467a5" + integrity sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA== + dependencies: + punycode "^2.1.1" + prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -5817,7 +6501,7 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@^1.3.5: +prism-react-renderer@^1.2.1, prism-react-renderer@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz#786bb69aa6f73c32ba1ee813fbe17a0115435085" integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg== @@ -5832,6 +6516,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.1, process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -5879,6 +6568,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + punycode@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -5889,6 +6583,11 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +punycode@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.2.0.tgz#2092cc57cd2582c38e4e7e8bb869dc8d3148bc74" + integrity sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw== + pupa@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" @@ -5901,13 +6600,18 @@ pure-color@^1.2.0: resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== -qs@6.11.0: +qs@6.11.0, qs@^6.10.3, qs@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -6032,6 +6736,11 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-json-view@^1.21.3: version "1.21.3" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" @@ -6054,6 +6763,23 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" +react-magic-dropzone@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-magic-dropzone/-/react-magic-dropzone-1.0.1.tgz#bfd25b77b57e7a04aaef0a28910563b707ee54df" + integrity sha512-0BIROPARmXHpk4AS3eWBOsewxoM5ndk2psYP/JmbCq8tz3uR2LIV1XiroZ9PKrmDRMctpW+TvsBCtWasuS8vFA== + +react-redux@^7.2.0: + version "7.2.9" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" + integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== + dependencies: + "@babel/runtime" "^7.15.4" + "@types/react-redux" "^7.1.20" + hoist-non-react-statics "^3.3.2" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^17.0.2" + react-router-config@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" @@ -6119,7 +6845,7 @@ readable-stream@^2.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6: +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -6154,6 +6880,28 @@ recursive-readdir@^2.2.2: dependencies: minimatch "^3.0.5" +redux-devtools-extension@^2.13.8: + version "2.13.9" + resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.9.tgz#6b764e8028b507adcb75a1cae790f71e6be08ae7" + integrity sha512-cNJ8Q/EtjhQaZ71c8I9+BPySIBVEKssbPpskBfsXqb8HJ002A3KRVHfeRzwRo6mGPqsm7XuHTqNSNeS1Khig0A== + +redux-thunk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" + integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== + +redux@^4.0.0, redux@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" + integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== + dependencies: + "@babel/runtime" "^7.9.2" + +reftools@^1.1.1: + version "1.1.9" + resolved "https://registry.yarnpkg.com/reftools/-/reftools-1.1.9.tgz#e16e19f662ccd4648605312c06d34e5da3a2b77e" + integrity sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w== + regenerate-unicode-properties@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" @@ -6216,11 +6964,29 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" +rehype-parse@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.2.tgz#aeb3fdd68085f9f796f1d3137ae2b85a98406964" + integrity sha512-0S3CpvpTAgGmnz8kiCyFLGuW5yA4OQhyNTm/nwPopZ7+PI11WnGl1TTWTGv/2hPEe/g2jRLlhVVSsoDH8waRug== + dependencies: + hast-util-from-parse5 "^5.0.0" + parse5 "^5.0.0" + xtend "^4.0.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== +remark-admonitions@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/remark-admonitions/-/remark-admonitions-1.2.1.tgz#87caa1a442aa7b4c0cafa04798ed58a342307870" + integrity sha512-Ji6p68VDvD+H1oS95Fdx9Ar5WA2wcDA4kwrrhVU7fGctC6+d3uiMICu7w7/2Xld+lnU7/gi+432+rRbup5S8ow== + dependencies: + rehype-parse "^6.0.2" + unified "^8.4.2" + unist-util-visit "^2.0.1" + remark-emoji@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" @@ -6294,6 +7060,11 @@ repeat-string@^1.5.4: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -6304,11 +7075,21 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" integrity sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A== +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +reselect@^4.1.7: + version "4.1.7" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42" + integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -6391,11 +7172,27 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sanitize-html@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.1.tgz#f6effdf55dd398807171215a62bfc21811bacf85" + integrity sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA== + dependencies: + chalk "^2.4.1" + htmlparser2 "^3.10.0" + lodash.clonedeep "^4.5.0" + lodash.escaperegexp "^4.1.2" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.mergewith "^4.6.1" + postcss "^7.0.5" + srcset "^1.0.0" + xtend "^4.0.1" + sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -6473,6 +7270,25 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" +semver@7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + +semver@7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@7.3.8, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + semver@^5.4.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -6483,13 +7299,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -6553,6 +7362,11 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -6597,6 +7411,15 @@ shell-quote@^1.7.3: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== +shelljs@0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + shelljs@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" @@ -6724,11 +7547,24 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +srcset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" + integrity sha512-UH8e80l36aWnhACzjdtLspd4TAWldXJMa45NuOkTTU+stwekswObdqM63TtQixN4PPd/vO/kxLa6RD+tUPeFMg== + dependencies: + array-uniq "^1.0.2" + number-is-nan "^1.0.0" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +state-local@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/state-local/-/state-local-1.0.7.tgz#da50211d07f05748d53009bee46307a37db386d5" + integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -6839,6 +7675,23 @@ stylehacks@^5.1.1: browserslist "^4.21.4" postcss-selector-parser "^6.0.4" +superagent@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-7.1.6.tgz#64f303ed4e4aba1e9da319f134107a54cacdc9c6" + integrity sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g== + dependencies: + component-emitter "^1.3.0" + cookiejar "^2.1.3" + debug "^4.3.4" + fast-safe-stringify "^2.1.1" + form-data "^4.0.0" + formidable "^2.0.1" + methods "^1.1.2" + mime "2.6.0" + qs "^6.10.3" + readable-stream "^3.6.0" + semver "^7.3.7" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -7064,6 +7917,17 @@ unified@9.2.0: trough "^1.0.0" vfile "^4.0.0" +unified@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" + integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + unified@^9.2.2: version "9.2.2" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" @@ -7132,7 +7996,7 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: +unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== @@ -7202,6 +8066,14 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + use-composed-ref@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" @@ -7224,6 +8096,13 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -7239,7 +8118,12 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^8.3.2: +uuid@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@8.3.2, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -7303,7 +8187,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -web-namespaces@^1.0.0: +web-namespaces@^1.0.0, web-namespaces@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== @@ -7449,6 +8333,11 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -7482,6 +8371,15 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -7542,6 +8440,11 @@ xtend@^4.0.0, xtend@^4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -7552,11 +8455,43 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: +yaml@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a" + integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw== + dependencies: + "@babel/runtime" "^7.8.7" + +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2, yaml@^1.8.3: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/model/supervised_finetuning/README.md b/model/supervised_finetuning/README.md index bd202397..822121d8 100644 --- a/model/supervised_finetuning/README.md +++ b/model/supervised_finetuning/README.md @@ -58,6 +58,8 @@ the end to trigger deepspeed python trainer.py --configs defaults your-model-name --deepspeed ``` +## Dataset choices + ## Results Experimental results in wandb diff --git a/model/supervised_finetuning/configs/config.yaml b/model/supervised_finetuning/configs/config.yaml index bd35f168..2eaa6686 100644 --- a/model/supervised_finetuning/configs/config.yaml +++ b/model/supervised_finetuning/configs/config.yaml @@ -6,7 +6,7 @@ defaults: per_device_eval_batch_size: 2 weight_decay: 0.00 warmup_steps: 600 - eval_steps: 100 + eval_steps: 500 save_steps: 500 max_length: 512 num_train_epochs: 3 @@ -18,7 +18,19 @@ defaults: datasets: - webgpt - prompt_dialogue - cache_dir: ~/.cache + - squad_v2 + - adversarial_qa + - trivia_qa_nocontext + - xsum + - cnn_dailymail + - prompt_dialogue + - multi_news + - scitldr + - soda + - joke + - gsm8k + - samsum + cache_dir: .cache loss_fn: CrossEntropyLoss eval_size: log_dir: "base" @@ -48,14 +60,14 @@ gpt-jt: per_device_eval_batch_size: 4 codegen: - learning_rate: 2e-6 + learning_rate: 8e-6 model_name: Salesforce/codegen-2B-multi weight_decay: 0.01 - max_length: 812 - warmup_steps: 600 + max_length: 520 + warmup_steps: 1000 gradient_checkpointing: false - gradient_accumulation_steps: 5 - per_device_train_batch_size: 4 + gradient_accumulation_steps: 9 + per_device_train_batch_size: 2 per_device_eval_batch_size: 4 debug: diff --git a/model/supervised_finetuning/custom_datasets/__init__.py b/model/supervised_finetuning/custom_datasets/__init__.py index c0cd424b..e293af3d 100644 --- a/model/supervised_finetuning/custom_datasets/__init__.py +++ b/model/supervised_finetuning/custom_datasets/__init__.py @@ -1,136 +1,11 @@ -import numpy as np -from datasets import load_dataset +from custom_datasets.prompt_dialogue import PromptGeneratedDataset +from custom_datasets.qa_datasets import SODA, JokeExplaination, QADataset, WebGPT +from custom_datasets.summarization import SummarizationDataset from sklearn.model_selection import train_test_split -from torch.utils.data import Dataset, Subset +from torch.utils.data import Subset -from .prompt_dialogue import PromptGeneratedDataset - -QA_SPECIAL_TOKENS = {"Question": "", "Answer": ""} -SUMMARIZATION_SPECIAL_TOKENS = {"Text": "", "Summary": "TL;DR:"} - -summarization_name_mapping = { - "cnn_dailymail": ("article", "highlights"), - "samsum": ("dialogue", "summary"), - "xsum": ("document", "summary"), - "multi_news": ("document", "summary"), - "scitldr": ("source", "target"), - "billsum": ("text", "summary"), - "reddit": ("content", "summary"), -} -summarization_config_mapping = { - "cnn_dailymail": ("3.0.0",), - "samsum": (), - "xsum": (), - "multi_news": (), - "scitldr": ("AIC",), - "billsum": (), - "reddit": (), -} - -QA_DATASETS = ["squad_v2", "adversarial_qa", "trivia_qa_context", "trivia_qa_noconext"] -SUMMARIZATION_DATASETS = ["xsum", "cnn_dailymail", "samsum", "multi_news"] - - -def index_squad_v2(example): - return example["title"] + ". " + example["context"] + " " + example["question"], example["answers"]["text"][0] - - -def index_trivia_qa_nocontext(example): - # dummy return one randomly - return example["question"], example["answer"]["aliases"][np.random.randint(len(example["answer"]["aliases"]))] - - -def index_trivia_qa_context(example): - question = example["question"] - title = example["title"][np.random.randint(len(example["title"]))] - context = example["search_context"][np.random.randint(len(example["search_context"]))] - answer = example["answer"]["aliases"][np.random.randint(len(example["answer"]["aliases"]))] - - return title + ". " + context + " " + question, answer - - -def index_adversarial_qa(example): - return example["title"] + ". " + example["context"] + " " + example["question"], example["answers"]["text"][0] - - -class QADataset(Dataset): - def __init__(self, dataset, cache_dir, split): - if dataset == "squad_v2": - self.index_fn = index_squad_v2 - self.dataset = load_dataset("squad_v2", cache_dir=cache_dir, split=split) - elif dataset == "trivia_qa_nocontext": - self.index_fn = index_trivia_qa_nocontext - self.dataset = load_dataset("trivia_qa", "rc.nocontext") - elif dataset == "trivia_qa_context": - self.index_fn = index_trivia_qa_context - self.dataset = load_dataset("trivia_qa", "rc") - elif dataset == "adversarial_qa": - self.index_fn = index_adversarial_qa - self.dataset = load_dataset("adversarial_qa", "adversarialQA") - else: - raise ValueError("Unknown dataset : " + dataset) - - def __len__(self): - return len(self.dataset) - - def __getitem__(self, idx): - data = self.dataset[idx] - return self.index_fn(data) - - -def index_summary_default(text, summary): - return text, summary - - -def index_summary_merge(text, summary): - return " ".join(text), " ".join(summary) - - -class SummarizationDataset(Dataset): - def __init__(self, dataset, cache_dir, split): - self.dataset = load_dataset(dataset, *summarization_config_mapping[dataset], cache_dir=cache_dir, split=split) - self.summary_column, self.text_column = summarization_name_mapping[dataset] - self.preprocess_fn = index_summary_merge if dataset == "scitdlr" else index_summary_merge - - def __len__(self): - return len(self.dataset) - - def __getitem__(self, idx): - data = self.dataset[idx] - text, summary = data[self.text_column], data[self.summary_column] - text, summary = self.preprocess_fn(text, summary) - - return "".join( - SUMMARIZATION_SPECIAL_TOKENS["Text"], text, " ", SUMMARIZATION_SPECIAL_TOKENS["Summary"], summary - ) - - -class WebGPT(Dataset): - def __init__(self) -> None: - super().__init__() - - dataset = load_dataset("openai/webgpt_comparisons") - questions = {} - # using prompt as our index will allows us - # to add additional generated prompt later - self.index2question = {} - for row in dataset["train"]: - question = row["question"]["full_text"] - if question not in self.index2question: - self.index2question[len(self.index2question)] = question - - # only keep the best answer - questions[question] = row["answer_0" if row["score_0"] > row["score_1"] else "answer_1"] - - self.questions = questions - - def __len__(self): - return len(self.index2question) - - def __getitem__(self, index): - question = self.index2question[index] - answer = self.questions[question] - return [question, answer] +QA_DATASETS = ["squad_v2", "adversarial_qa", "trivia_qa_context", "trivia_qa_nocontext", "gsm8k"] +SUMMARIZATION_DATASETS = ["xsum", "cnn_dailymail", "samsum", "multi_news", "scitldr", "billsum"] def train_val_dataset(dataset, val_split=0.2): @@ -143,19 +18,26 @@ def train_val_dataset(dataset, val_split=0.2): def get_one_dataset(conf, dataset_name): dataset_name = dataset_name.lower() - if dataset_name in ["squad_v2", "adversarial_qa", "trivia_qa_context", "trivia_qa_noconext"]: + if dataset_name in QA_DATASETS: train = QADataset(dataset_name, conf.cache_dir, "train") - eval = QADataset(dataset_name, conf.cache_dir, "validation") + val_name = "validation" if dataset_name not in ["gsm8k"] else "test" + eval = QADataset(dataset_name, conf.cache_dir, val_name) - elif dataset_name in ["xsum", "cnn_dailymail", "samsum", "multi_news", "scitldr", "billsum", "reddit"]: + elif dataset_name in SUMMARIZATION_DATASETS: train = SummarizationDataset(dataset_name, conf.cache_dir, "train") - eval = SummarizationDataset(dataset_name, conf.cache_dir, "validation") - + val_name = "validation" if dataset_name not in ["billsum"] else "test" + eval = SummarizationDataset(dataset_name, conf.cache_dir, val_name) elif dataset_name == "webgpt": dataset = WebGPT() train, eval = train_val_dataset(dataset, val_split=0.2) elif dataset_name == "prompt_dialogue": - dataset = PromptGeneratedDataset() + dataset = PromptGeneratedDataset(conf.cache_dir) + train, eval = train_val_dataset(dataset, val_split=0.2) + elif dataset_name == "soda": + dataset = SODA(conf.cache_dir) + train, eval = train_val_dataset(dataset, val_split=0.1) + elif dataset_name == "joke": + dataset = JokeExplaination(conf.cache_dir) train, eval = train_val_dataset(dataset, val_split=0.2) else: raise ValueError(f"Unknown dataset {dataset_name}") diff --git a/model/supervised_finetuning/custom_datasets/dialogue_collator.py b/model/supervised_finetuning/custom_datasets/dialogue_collator.py index 479931f6..2efe160f 100644 --- a/model/supervised_finetuning/custom_datasets/dialogue_collator.py +++ b/model/supervised_finetuning/custom_datasets/dialogue_collator.py @@ -3,11 +3,10 @@ from typing import Optional, Union import numpy as np import torch +from custom_datasets.qa_datasets import QA_SPECIAL_TOKENS from torch.nn import functional as F from transformers.tokenization_utils_base import PaddingStrategy, PreTrainedTokenizerBase -from . import QA_SPECIAL_TOKENS - @dataclass class DialogueDataCollator: @@ -35,7 +34,7 @@ class DialogueDataCollator: # Add a way for the model to terminate generation # When we predict the start of a new expected question, we want to be able to stop generation - messages.append(QA_SPECIAL_TOKENS["Question"]) + messages.append(self.tokenizer.eos_token) flatten_message = self.tokenizer( "".join(messages), diff --git a/model/supervised_finetuning/custom_datasets/prompt_dialogue.py b/model/supervised_finetuning/custom_datasets/prompt_dialogue.py index 17911141..372ea27f 100644 --- a/model/supervised_finetuning/custom_datasets/prompt_dialogue.py +++ b/model/supervised_finetuning/custom_datasets/prompt_dialogue.py @@ -16,10 +16,10 @@ class PromptGeneratedDataset(Dataset): url = "https://github.com/Rallio67/language-model-agents/raw/main/chat_dialogue_v2_c.txt" - def __init__(self) -> None: + def __init__(self, cache_dir) -> None: super().__init__() - os.makedirs("datasets", exist_ok=True) - chat_dialogue = os.path.join("datasets", "chat_dialogue_v2_c.txt") + os.makedirs(cache_dir, exist_ok=True) + chat_dialogue = os.path.join(cache_dir, "chat_dialogue_v2_c.txt") if not os.path.exists(chat_dialogue): with urlopen(self.url) as file: content = file.read().decode() @@ -49,18 +49,3 @@ class PromptGeneratedDataset(Dataset): def __getitem__(self, index): question, answer = self.pairs[index] return question, answer - - -if __name__ == "__main__": - from torch.utils.data import DataLoader - from transformers import AutoTokenizer - - from .dialogue_collator import DialogueDataCollator - - tokenizer = AutoTokenizer.from_pretrained("Salesforce/codegen-2B-multi") - tokenizer.add_special_tokens({"pad_token": "<|endoftext|>", "sep_token": "<|endoftext|>"}) - dataset = PromptGeneratedDataset() - collate_fn = DialogueDataCollator(tokenizer, padding=True, max_length=128) - dataloader = DataLoader(dataset, collate_fn=collate_fn, batch_size=5) - for batch in dataloader: - print(batch["input_ids"].shape) diff --git a/model/supervised_finetuning/custom_datasets/qa_datasets.py b/model/supervised_finetuning/custom_datasets/qa_datasets.py new file mode 100644 index 00000000..eed9c644 --- /dev/null +++ b/model/supervised_finetuning/custom_datasets/qa_datasets.py @@ -0,0 +1,184 @@ +import json +import os +from urllib.request import urlopen + +import numpy as np +from datasets import load_dataset +from torch.utils.data import Dataset + +QA_SPECIAL_TOKENS = {"Question": "", "Answer": "", "StartPrefix": "", "EndPrefix": ""} + + +def index_squad_v2(example): + if len(example["answers"]["text"]): + answer = example["answers"]["text"][0] + else: + answer = "I do not have answer for that" + return example["context"] + " " + example["question"], answer + + +def index_trivia_qa_nocontext(example): + # dummy return one randomly + return example["question"], example["answer"]["aliases"][np.random.randint(len(example["answer"]["aliases"]))] + + +def index_trivia_qa_context(example): + question = example["question"] + if len(example["search_results"]["search_context"]): + context = example["search_results"]["search_context"][ + np.random.randint(len(example["search_results"]["search_context"])) + ] + else: + context = "" + answer = example["answer"]["aliases"][np.random.randint(len(example["answer"]["aliases"]))] + + return context + " " + question, answer + + +def index_adversarial_qa(example): + return example["title"] + ". " + example["context"] + " " + example["question"], example["answers"]["text"][0] + + +def index_gsm8k(example): + return example["question"], example["answer"] + + +class QADataset(Dataset): + def __init__(self, dataset, cache_dir, split): + if dataset == "squad_v2": + self.index_fn = index_squad_v2 + self.dataset = load_dataset("squad_v2", cache_dir=cache_dir, split=split) + elif dataset == "trivia_qa_nocontext": + self.index_fn = index_trivia_qa_nocontext + self.dataset = load_dataset("trivia_qa", "rc.nocontext", split=split, cache_dir=cache_dir) + elif dataset == "trivia_qa_context": + self.index_fn = index_trivia_qa_context + self.dataset = load_dataset("trivia_qa", "rc", split=split, cache_dir=cache_dir) + elif dataset == "adversarial_qa": + self.index_fn = index_adversarial_qa + self.dataset = load_dataset("adversarial_qa", "adversarialQA", split=split, cache_dir=cache_dir) + elif dataset == "gsm8k": + self.index_fn = index_gsm8k + self.dataset = load_dataset("gsm8k", "main", split=split, cache_dir=cache_dir) + elif dataset == "adversarial_qa": + self.index_fn = index_adversarial_qa + self.dataset = load_dataset("adversarial_qa", "adversarialQA", split=split, cache_dir=cache_dir) + else: + raise ValueError("Unknown dataset : " + dataset) + + def __len__(self): + return len(self.dataset) + + def __getitem__(self, idx): + data = self.dataset[idx] + return self.index_fn(data) + + +class WebGPT(Dataset): + def __init__(self) -> None: + super().__init__() + + dataset = load_dataset("openai/webgpt_comparisons") + questions = {} + # using prompt as our index will allows us + # to add additional generated prompt later + self.index2question = {} + for row in dataset["train"]: + question = row["question"]["full_text"] + if question not in self.index2question: + self.index2question[len(self.index2question)] = question + + # only keep the best answer + questions[question] = row["answer_0" if row["score_0"] > row["score_1"] else "answer_1"] + + self.questions = questions + + def __len__(self): + return len(self.index2question) + + def __getitem__(self, index): + question = self.index2question[index] + answer = self.questions[question] + return [question, answer] + + +class SODA(Dataset): + def process_soda_convo(self, data): + pairs = [] + play_as = data["speakers"][1] + prefix = "{}. {}".format(data["narrative"], "your name {}".format(play_as)) + question, answer = "", "" + prefix, postfix = "", "" + previous_chat = [] + + for idx, convo in enumerate(data["dialogue"]): + if idx % 2 == 0: + question = convo + prefix = data["speakers"][idx] + else: + answer = convo + postfix = data["speakers"][idx] + if len(question) and len(answer) and prefix != postfix and postfix == play_as: + history = "".join(["{}{}".format(*p) for p in previous_chat]) + if len(history): + history += "" + pairs.append((prefix + history + question, answer)) + previous_chat.append((question, answer)) + return pairs + + def __init__(self, cache_dir, max_sample_size=10000, input_max_length=1024) -> None: + super().__init__() + + self.pairs = [] + dataset = load_dataset("allenai/soda", cache_dir=cache_dir)["train"] + for data in dataset: + data_pair = self.process_soda_convo(data) + for (prompt, answer) in data_pair: + if len(prompt) < input_max_length: + self.pairs.append((prompt, answer)) + + if len(self.pairs) > max_sample_size: + break + + def __len__(self): + return len(self.pairs) + + def __getitem__(self, index): + question, answer = self.pairs[index] + return question, answer + + +class JokeExplaination(Dataset): + """ """ + + url = "https://gist.github.com/theblackcat102/42b697e24a13fdb499e20edfbf618361/raw/1834dca207898c15f93b809d1195f6f6e47c9e1e/joke_explained.jsonl" + + def __init__(self, cache_dir) -> None: + super().__init__() + os.makedirs(cache_dir, exist_ok=True) + joke_explain_filename = os.path.join(cache_dir, "joke_explaination.jsonl") + if not os.path.exists(joke_explain_filename): + with urlopen(self.url) as file: + content = file.read().decode() + with open(joke_explain_filename, "w") as fout: + fout.write(content) + + question = "" + answer = "" + self.pairs = [] + with open(joke_explain_filename, "r") as f: + for line in f: + data = json.loads(line) + joke = data["joke"] + explanation = data["explaination"] + self.pairs.append((joke, explanation)) + + if len(question) > 0 and len(answer) > 0: + self.pairs.append((question, answer)) + + def __len__(self): + return len(self.pairs) + + def __getitem__(self, index): + question, answer = self.pairs[index] + return question, answer diff --git a/model/supervised_finetuning/custom_datasets/summarization.py b/model/supervised_finetuning/custom_datasets/summarization.py new file mode 100644 index 00000000..69e4b51d --- /dev/null +++ b/model/supervised_finetuning/custom_datasets/summarization.py @@ -0,0 +1,62 @@ +import random + +from datasets import load_dataset +from torch.utils.data import Dataset + +SUMMARIZATION_SPECIAL_TOKENS = {"Text": "", "Summary": ["TL;DR:", "Summarize this", "Give me the summary"]} + +SUMMARY_SPECIAL_PROMPT = { + "multi_news": ["Summarize in bullet points", "Generate summary in list of points"], + "xsum": ["Give me summary in one sentence", "Short TLDR", "Give me a concise summary"], + "samsum": ["TLDR;", "Summarize this dialogue", "Summarize dialogue"], +} + +summarization_config_mapping = { + "cnn_dailymail": ("3.0.0",), + "samsum": (), + "xsum": (), + "multi_news": (), + "scitldr": ("AIC",), + "billsum": (), + "reddit": (), +} + +summarization_name_mapping = { + "cnn_dailymail": ("article", "highlights"), + "samsum": ("dialogue", "summary"), + "xsum": ("document", "summary"), + "multi_news": ("document", "summary"), + "scitldr": ("source", "target"), + "billsum": ("text", "summary"), + "reddit": ("content", "summary"), +} + + +def index_summary_default(text, summary): + return text.replace("\n\n", "\n"), summary + + +def index_summary_merge(text, summary): + return " ".join(text), " ".join(summary) + + +class SummarizationDataset(Dataset): + def __init__(self, dataset, cache_dir, split): + self.name = dataset + self.dataset = load_dataset(dataset, *summarization_config_mapping[dataset], cache_dir=cache_dir, split=split) + self.text_column, self.summary_column = summarization_name_mapping[dataset] + self.preprocess_fn = index_summary_merge if dataset == "scitldr" else index_summary_default + + def __len__(self): + return len(self.dataset) + + def __getitem__(self, idx): + data = self.dataset[idx] + text, summary = data[self.text_column], data[self.summary_column] + text, summary = self.preprocess_fn(text, summary) + if self.name in SUMMARY_SPECIAL_PROMPT: + prompt = random.choice(SUMMARIZATION_SPECIAL_TOKENS["Summary"]) + else: + prompt = random.choice(SUMMARIZATION_SPECIAL_TOKENS["Summary"]) + + return ("".join([SUMMARIZATION_SPECIAL_TOKENS["Text"], " ".join(text.split(" ")[:256]), prompt]), summary) diff --git a/model/supervised_finetuning/tests/test_datasets.py b/model/supervised_finetuning/tests/test_datasets.py new file mode 100644 index 00000000..c9363303 --- /dev/null +++ b/model/supervised_finetuning/tests/test_datasets.py @@ -0,0 +1,54 @@ +from argparse import Namespace + +from custom_datasets import QA_DATASETS, SUMMARIZATION_DATASETS, get_one_dataset +from custom_datasets.dialogue_collator import DialogueDataCollator + + +def test_all_datasets(): + qa_base = QA_DATASETS + summarize_base = SUMMARIZATION_DATASETS + others = ["prompt_dialogue", "webgpt", "soda", "joke"] + + config = Namespace(cache_dir=".cache") + for dataset_name in others + qa_base + summarize_base: + print(dataset_name) + train, eval = get_one_dataset(config, dataset_name) + # sanity check + for idx in range(min(len(train), 1000)): + train[idx] + for idx in range(min(len(eval), 1000)): + eval[idx] + + +def test_collate_fn(): + from torch.utils.data import ConcatDataset, DataLoader + from utils import get_tokenizer + + config = Namespace(cache_dir=".cache", model_name="Salesforce/codegen-2B-multi") + tokenizer = get_tokenizer(config) + collate_fn = DialogueDataCollator(tokenizer, max_length=512) + qa_base = QA_DATASETS + summarize_base = SUMMARIZATION_DATASETS + others = ["prompt_dialogue", "webgpt", "soda", "joke", "gsm8k"] + + trains, evals = [], [] + for dataset_name in others + qa_base + summarize_base: + print(dataset_name) + train, eval = get_one_dataset(config, dataset_name) + trains.append(train) + evals.append(eval) + + dataloader = DataLoader(ConcatDataset(trains), collate_fn=collate_fn, batch_size=128) + for batch in dataloader: + # print(batch.keys()) + # print(tokenizer.decode(batch['input_ids'][0])) + # print('-----') + # print(tokenizer.decode(batch['targets'][0][batch['label_masks'][0]])) + assert batch["targets"].shape[1] <= 512 + dataloader = DataLoader(ConcatDataset(evals), collate_fn=collate_fn, batch_size=128) + for batch in dataloader: + assert batch["targets"].shape[1] <= 512 + + +if __name__ == "__main__": + test_collate_fn() diff --git a/model/supervised_finetuning/tests/test_utils.py b/model/supervised_finetuning/tests/test_utils.py new file mode 100644 index 00000000..ad40e534 --- /dev/null +++ b/model/supervised_finetuning/tests/test_utils.py @@ -0,0 +1,9 @@ +from argparse import Namespace + +from utils import get_tokenizer + + +def test_tokenizer(): + get_tokenizer(Namespace(model_name="Salesforce/codegen-2B-multi", cache_dir=".cache")) + get_tokenizer(Namespace(model_name="facebook/galactica-1.3b", cache_dir=".cache")) + get_tokenizer(Namespace(model_name="", cache_dir=".cache")) diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index f598dde1..7b6e03b6 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -1,13 +1,15 @@ -from functools import partial +# from functools import partial from pathlib import Path import evaluate -import nltk -import numpy as np + +# import nltk +# import numpy as np import transformers import yaml -from custom_datasets import QA_DATASETS, QA_SPECIAL_TOKENS, SUMMARIZATION_DATASETS, get_one_dataset +from custom_datasets import get_one_dataset from custom_datasets.dialogue_collator import DialogueDataCollator +from custom_datasets.qa_datasets import QA_SPECIAL_TOKENS from losses import CrossEntropyLoss, PolyLoss from models import freeze_top_n_layers, get_specific_model from sklearn.model_selection import train_test_split @@ -51,25 +53,25 @@ def preprocess_qa(eval_pred): return (eval_pred.predictions, eval_pred.label_ids) -def postprocess_summarization(preds, labels): - preds = [pred.strip() for pred in preds] - labels = [label.strip() for label in labels] +# def postprocess_summarization(preds, labels): +# preds = [pred.strip() for pred in preds] +# labels = [label.strip() for label in labels] - preds = ["\n".join(nltk.sent_tokenize(pred)) for pred in preds] - labels = ["\n".join(nltk.sent_tokenize(label)) for label in labels] +# preds = ["\n".join(nltk.sent_tokenize(pred)) for pred in preds] +# labels = ["\n".join(nltk.sent_tokenize(label)) for label in labels] - return preds, labels +# return preds, labels -def preprocess_summarization(eval_pred, tokenizer, ignore_pad_token_for_loss=True): - preds, labels = eval_pred - decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True) - if ignore_pad_token_for_loss: - labels = np.where(labels != -100, labels, tokenizer.pad_token_id) - decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) +# def preprocess_summarization(eval_pred, tokenizer, ignore_pad_token_for_loss=True): +# preds, labels = eval_pred +# decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True) +# if ignore_pad_token_for_loss: +# labels = np.where(labels != -100, labels, tokenizer.pad_token_id) +# decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) - decoded_preds, decoded_labels = postprocess_summarization(decoded_preds, decoded_labels) - return decoded_preds, decoded_labels +# decoded_preds, decoded_labels = postprocess_summarization(decoded_preds, decoded_labels) +# return decoded_preds, decoded_labels def get_metrics(conf, tokenizer): @@ -77,16 +79,16 @@ def get_metrics(conf, tokenizer): # metrics in the future for more thorough evaluation metrics, preprocess_fns = [evaluate.load("accuracy")], [default_preprocess] - if any(dataset in QA_DATASETS for dataset in conf.datasets): - raise ValueError("TODO") - metrics.append(evaluate.load("squad_v2")) - preprocess_fns.append(preprocess_qa) - if any(dataset in SUMMARIZATION_DATASETS for dataset in conf.datasets): - raise ValueError("TODO") - metrics.append(evaluate.load("rouge")) - preprocess_fns.append( - partial(preprocess_summarization, tokenizer, ignore_pad_token_for_loss=conf.ignore_pad_token_for_loss) - ) + # if any(dataset in QA_DATASETS for dataset in conf.datasets): + # raise ValueError("TODO") + # metrics.append(evaluate.load("squad_v2")) + # preprocess_fns.append(preprocess_qa) + # if any(dataset in SUMMARIZATION_DATASETS for dataset in conf.datasets): + # raise ValueError("TODO") + # metrics.append(evaluate.load("rouge")) + # preprocess_fns.append( + # partial(preprocess_summarization, tokenizer, ignore_pad_token_for_loss=conf.ignore_pad_token_for_loss) + # ) return metrics, preprocess_fns diff --git a/notebooks/closed-book-qa/T5_closed_book_QA_generator.md b/notebooks/closed-book-qa/README.md similarity index 53% rename from notebooks/closed-book-qa/T5_closed_book_QA_generator.md rename to notebooks/closed-book-qa/README.md index 2cae860e..0dedd56f 100644 --- a/notebooks/closed-book-qa/T5_closed_book_QA_generator.md +++ b/notebooks/closed-book-qa/README.md @@ -1,17 +1,18 @@ -# Generate Topics, Questions, and Answers from a text +# Generate Topics, Questions, and Answers from a paragraph of text This python code can be used to generate topics, questions, and answers from a paragraph of text. This is a good way to generate ground truth knowledge about a topic from a trusted source. -The output of this is a dictionary with: +The output of this is a dictionary with the following information: 1. submitted paragraph -1. generated topics -1. generated questions -1. generated topic prefixes that can be prepended to the questions -1. open book answer based only on the provided paragraph -1. closed book answers generated by FLAN-T5-11B +2. generated topics +3. generated questions +4. generated topic prefixes that can be prepended to the questions +5. open book answer based only on the provided paragraph +6. closed book answers generated by FLAN-T5-11B (uses only question and + optionally question prefix to generate the answer) ## Contributing diff --git a/notebooks/closed-book-qa/T5_closed_book_QA_generator.py b/notebooks/closed-book-qa/T5_closed_book_QA_generators.py similarity index 55% rename from notebooks/closed-book-qa/T5_closed_book_QA_generator.py rename to notebooks/closed-book-qa/T5_closed_book_QA_generators.py index 68c40100..d6bcac19 100644 --- a/notebooks/closed-book-qa/T5_closed_book_QA_generator.py +++ b/notebooks/closed-book-qa/T5_closed_book_QA_generators.py @@ -1,4 +1,4 @@ -# This notebook will run on a system with a single RTX3090 (24 GB vram). +# This notebook will run on a system with a single RTX3090 (24 GB vram) GPU. # You need to install accelerate, bitsandbytes, and transformers import math @@ -10,8 +10,7 @@ import torch # load all needed libraries from transformers import AutoModelForSeq2SeqLM, AutoTokenizer -# This device map will work a GPU with > 24GB vram. -# It uses nearly all the memory. +# This device map will work a GPU with > 24GB vram. It uses nearly all the memory. device_map_T5_13B = { "shared": 0, "decoder.embed_tokens": 0, @@ -71,31 +70,32 @@ device_map_T5_13B = { "lm_head": 0, } - -# Load the model in bfloat16. Make sure to use bfloat16 -# if you are doing inference with 16bit precision. +# Load the model in bfloat16. Make sure to use bfloat16 if you are doing inference with 16bit precision. tokenizer = AutoTokenizer.from_pretrained("flan-t5-xxl") model = AutoModelForSeq2SeqLM.from_pretrained( - "flan-t5-xxl", - device_map=device_map_T5_13B, - torch_dtype=torch.bfloat16, - load_in_8bit=False, + "flan-t5-xxl", device_map=device_map_T5_13B, torch_dtype=torch.bfloat16, load_in_8bit=False ) - -# Load strings as knowledge sources for QA generation. -# You can do this with a pickle. +# Load an array of strings that are are reference or verified knowledge sources for QA generation. You can do this with a pickle. objects = [] with (open("paragraphs.pkl", "rb")) as openfile: while True: try: objects.append(pickle.load(openfile)) except EOFError: + print("Problem laoding your pickle file, using the default array") + pickle_fail = True break -paragraphs = objects[0] -# Make sure no paragraphs are too long for T5. -# It handles up to 512 tokens context length. +# If you don't know how to get an array of paragraphs, you can uncomment the next line. +if pickle_fail: + paragraphs = [ + "Like for me, this thing is like a little side hobby, but it's also one that's deeply fulfilling. So not just from a business perspective, which is not the way I think about it. I just think from a life human perspective, it's I probably wouldn't have this kind of conversation with you off mic, like this long, this deep, this attentive. There's something really fulfilling about these conversations. So what advice would you have for me? What advice do you have for yourself? Oh, have you not introspected this that deeply? Oh, I have advice. I think the first advice I would give to you is I think you should have me on more often. Yeah. Yeah. That's first and foremost. And second is go on your podcast and have a conversation. Well, I would say you come on my podcast when you're ready. Yeah. When you feel like the product that I'm putting out would benefit from your presence and vice versa, not as a favor to a bro, but at the right time.", + "Well, we really are looking through a two dimensional screen until it's what we intuit to be a three dimensional world and also inferring dynamic stuff, making it 4D. Anyway, is it possible to visualize some pretty pictures that give us a deeper sense of the truth of reality? I think that we will incrementally be able to do that. I think that, for example, the picture that we have of electrons and photons interacting and scattering, it may have not been possible until Faraday did all of his experiments and then Maxwell wrote down his equations. And we were then sort of forced by his equations to think in a new way. And then when Planck in 1900, desperate to try to solve the problem of black body radiation, what they call the ultraviolet catastrophe where Newton was predicting infinite energies where there weren't infinite energies in black body radiation. And he in desperation proposed packets of energy. Then once you've done that, and then you have an Einstein come along five years later and show how that explains the photoelectric effect.", + "But man, I don't know how I would feel about just bacteria everywhere. Well, it would be depressing if it was true. I suppose depressing, I don't think, I don't. I don't know what's more depressing, bacteria everywhere or nothing everywhere. Yes, either of them are chilling. Yeah. But whether it's chilling or not, I don't think should force us to change our view about whether it's real or not. Yes. And what I'm saying may or may not be true. So how would you feel if we discovered life on Mars? Absolutely. It sounds like you would be less excited than some others because you're like, well. What I would be most interested in is how similar to life on Earth it would be. It would actually turn into quite a subtle problem because the likelihood of life having gone to and fro between Mars and the Earth is quite, I wouldn't say high, but it's not low, it's quite feasible. And so if we found life on Mars and it had very similar genetic code, but it was slightly different, most people would interpret that immediately as evidence that they've been transit one way or the other and that it was a common origin of life on Mars or on the Earth and it went one way or the other way.", + ] + +# Make sure no paragraphs are too long for T5. It handles up to 512 tokens context length. fixed_paragraphs = [] for k in paragraphs: if len(k) > 1100: @@ -107,16 +107,13 @@ print("Length filtered number of paragraphs:", len(fixed_paragraphs)) paragraphs = fixed_paragraphs -# Sort_Tuple sorts a list of tuples -# by the second element. +# Sort_Tuple sorts a list of tuples where the first element is text and the second element is logits e.g. ("text",-1.5) def Sort_Tuple(tup): tup.sort(key=lambda x: x[1], reverse=True) return tup -# ask_flan_T5 takes a text input and returns the -# response of FLAN_T5 and a normalized logits -# score for the generation. +# ask_flan_T5 is a function that takes an input text and returns the response of FLAN_T5 and a normalized logits score for the generation. def ask_flan_T5(input_text): inputs = tokenizer.encode(input_text, return_tensors="pt").cuda(0) outputs = model.generate( @@ -135,17 +132,20 @@ def ask_flan_T5(input_text): for i in outputs.sequences: logprobs = 0 counter = 0 + output_scores = "" for k in i[1:]: + word_piece = tokenizer.decode(k.item()) word_prob = (round(probs[0][counter][k.item()].item(), 2)) + 0.001 + word_logprob = round(math.log(word_prob), 2) logprobs = logprobs + math.log(word_prob) + next_piece = word_piece + "(" + str(word_prob) + " " + str(word_logprob) + ")" + output_scores = output_scores + " " + next_piece counter += 1 out_tuple = (out_text, round(logprobs, 2)) return out_tuple -# ask_flan_T5D is a function that takes an input text and -# returns the deterministic(do_sample=False) output of -# FLAN_T5 and logits. +# ask_flan_T5D is a function that takes an input text and returns the deterministic(do_sample=False) output of FLAN_T5 and a normalized logits score for the generation. def ask_flan_T5D(input_text): inputs = tokenizer.encode(input_text, return_tensors="pt").cuda(0) outputs = model.generate( @@ -162,9 +162,14 @@ def ask_flan_T5D(input_text): for i in outputs.sequences: logprobs = 0 counter = 0 + output_scores = "" for k in i[1:]: + word_piece = tokenizer.decode(k.item()) word_prob = (round(probs[0][counter][k.item()].item(), 2)) + 0.001 + word_logprob = round(math.log(word_prob), 2) logprobs = logprobs + math.log(word_prob) + next_piece = word_piece + "(" + str(word_prob) + " " + str(word_logprob) + ")" + output_scores = output_scores + " " + next_piece counter += 1 out_tuple = (out_text, round(logprobs, 2)) return out_tuple @@ -173,12 +178,7 @@ def ask_flan_T5D(input_text): # Generate a topic classifier for a paragraph of text def generate_topic(paragraph): results = set() - input_text = ( - "Task: Create a topic classifier for the provided \ - paragraph.\nParagraph:\n" - + paragraph - + "\nTopic: " - ) + input_text = "Task: Create a topic classifier for the provided paragraph.\nParagraph:\n" + paragraph + "\nTopic: " for k in range(0, 20): result = ask_flan_T5(input_text) if result[1] > -4: @@ -196,11 +196,7 @@ def generate_topic_prefix(topic_set): for entry in topic_set: topic = entry[0] input_text = ( - "Task: Create a prepositional phrase about the topic.\n\ - Example 1\n Topic: climbing mount everest\nPrepositional \ - Phrase: With regards to climbing mount everest,\nExample \ - 2\nTopic: United States Air Force\nPrepositional Phrase: \ - On the topic of the United States Air Force,\n Example 3\nTopic: " + "Task: Create a prepositional phrase about the topic.\nExample 1\nTopic: climbing mount everest\nPrepositional Phrase: With regards to climbing mount everest,\nExample 2\nTopic: United States Air Force\nPrepositional Phrase: On the topic of the United States Air Force,\nExample 3\nTopic: " + topic + "\nPrepositional Phrase: " ) @@ -210,12 +206,10 @@ def generate_topic_prefix(topic_set): return sorted_results[0:5] -# Generate who/what/where/when/why questions from a paragraph. -# Number of questions variable is an integer which indicates how -# many of each question type to try to generate. +# Generate who/what/where/when/why questions from a paragraph. Number of questions variable is an integer which indicates how many of each question type to try to generate. def generate_questions(paragraph, number_of_questions): if len(tokenizer.encode(paragraph)) > 480: - print("Warning, the context length is too long.") + print("Warning, the context length is too long and could give bad results.") question_set = set() question_types = [ "What", @@ -239,17 +233,12 @@ def generate_questions(paragraph, number_of_questions): return question_set -# Generate answers for a set of questions. -# Input is the paragraph of text and a set of questions where each question -# is a tuple generated from the generate_questions() function. +# Generate answers for a set of questions. Input is the paragraph of text and a set of questions where each question is a tuple generated from the generate_questions() function. def generate_answers(paragraph, question_set): possible_answers = set() for question in question_set: input_text = ( - "Please read the following paragraph and \ - then answer the question using only data \ - found in the text. If no answer is possible, respond \ - 'NA'.\nText:\n" + "Please read the following paragraph and then answer the question using only data found in the text. If no answer is possible, respond 'NA'.\nText:\n" + paragraph + "\nQuestion:\n" + question[1][0] @@ -263,16 +252,13 @@ def generate_answers(paragraph, question_set): return possible_answers -# Generate questions from a paragraph and set of answers. -# Input is the paragraph of text and a set of answers where each question -# is a tuple generated from the generate_answers() function. +# Generate questions from a paragraph and set of answers. Input is the paragraph of text and a set of answers where each question is a tuple generated from the generate_answers() function. def generate_question2(paragraph, qa_set): qaq_results = set() for qa_item in qa_set: answer = qa_item[2][0] input_text = ( - "Please read the following paragraph and \ - then generate a question whose answer is: " + "Please read the following paragraph and then generate a question whose answer is: " + answer + "\nParagraph:\n" + paragraph @@ -283,23 +269,20 @@ def generate_question2(paragraph, qa_set): return qaq_results -# Generate answers from a paragraph and set of questions. -# Input is the paragraph of text and a set of questions where each answer -# is a tuple generated from the generate_questions2() function. +# Generate answers from a paragraph and set of questions. Input is the paragraph of text and a set of questions where each answer is a tuple generated from the generate_questions2() function. def generate_answers2(paragraph, question_set): possible_answers = set() for question in question_set: input_text = ( - "Please read the following paragraph and \ - then answer the question using only data \ - found in the text. If no answer is possible, respond \ - 'NA'.\nText:\n" + "Please read the following paragraph and then answer the question using only data found in the text. If no answer is possible, respond 'NA'.\nText:\n" + paragraph + "\nQuestion:\n" + question + "\nAnswer:\n" ) answer = ask_flan_T5D(input_text) + # print(question) + # print(answer) possible_answers.add((question, answer)) return possible_answers @@ -314,10 +297,7 @@ def generate_declarative(qaq_set): pass else: input_text = ( - "Generate a declarative statement based on the \ - given question and answer pair.\nQ: What is \ - sitting on the couch?\nA: poodle\nA poodle is \ - sitting on the couch.\nQ: " + "Generate a declarative statement based on the given question and answer pair.\nQ: What is sitting on the couch?\nA: poodle\nA poodle is sitting on the couch.\nQ: " + question + "\nA: " + answer @@ -339,20 +319,7 @@ def generate_closed_answer(qaqd_set): pass else: input_text = ( - "Task: Answer the question in a detailed fashion. \ - If the question cannot be answered without more \ - information, please answer NA.\nExample 1:\nQuestion: \ - Why does Shala like cookies?\nAnswer: It is not possible \ - to know why Shala likes cookies without more information, \ - but many people that like cookies enjoy their taste or \ - some of their ingredients (e.g. chocolate chips or \ - peanut butter).\nExample 2:\nQuestion: Why would someone \ - vote in an election?\nAnswer: There are many reasons \ - someone might vote in an election, for instance to have \ - their voice heard or to help a candidate they like win the \ - race.\nExample 3\nQuestion: What decoration goes on top of \ - a Christmas tree?\nAnswer: Usually a star is placed at the \ - top of a Christmas tree.\nExample 4:\nQuestion: " + "Task: Answer the question in a detailed fashion. If the question cannot be answered without more information, please answer NA.\nExample 1:\nQuestion: Why does Shala like cookies?\nAnswer: It is not possible to know why Shala likes cookies without more information, but many people that like cookies enjoy their taste or some of their ingredients (e.g. chocolate chips or peanut butter).\nExample 2:\nQuestion: Why would someone vote in an election?\nAnswer: There are many reasons someone might vote in an election, for instance to have their voice heard or to help a candidate they like win the race.\nExample 3\nQuestion: What decoration goes on top of a Christmas tree?\nAnswer: Usually a star is placed at the top of a Christmas tree.\nExample 4:\nQuestion: " + question + "\nAnswer: " ) @@ -361,8 +328,7 @@ def generate_closed_answer(qaqd_set): return qaqd_results -# Create a dictionary of questions and answers from a list of paragraphs. -# Takes about 20 seconds per paragraph to process. +# Create a dictionary of questions and answers from a list of paragraphs. Takes about 20 seconds per paragraph to process. start_time = time.perf_counter() questions_dict = {} uniq_id = 100000 @@ -399,8 +365,11 @@ generation_time = stop_time - start_time print(questions_dict[uniq_id - 1]) print(generation_time) - # create a binary pickle file to save your dictionary f = open("questions_dict.pkl", "wb") + +# write the python object (dict) to pickle file pickle.dump(questions_dict, f) + +# close file f.close() diff --git a/notebooks/data-augmentation/README.md b/notebooks/data-augmentation/README.md new file mode 100644 index 00000000..f6260009 --- /dev/null +++ b/notebooks/data-augmentation/README.md @@ -0,0 +1,5 @@ +# Data Augmentation + +This folder contains subfolders of notebooks broadly relating to data +augmentation. Each subfolder contains a README.md file explaining what the +notebooks in that folder do. diff --git a/notebooks/data-argumentation/EssayInstructions.md b/notebooks/data-augmentation/essay-instructions/README.md similarity index 100% rename from notebooks/data-argumentation/EssayInstructions.md rename to notebooks/data-augmentation/essay-instructions/README.md diff --git a/notebooks/data-argumentation/EssayInstructions.ipynb b/notebooks/data-augmentation/essay-instructions/essay-instructions.ipynb similarity index 97% rename from notebooks/data-argumentation/EssayInstructions.ipynb rename to notebooks/data-augmentation/essay-instructions/essay-instructions.ipynb index 30834d32..47b628aa 100644 --- a/notebooks/data-argumentation/EssayInstructions.ipynb +++ b/notebooks/data-augmentation/essay-instructions/essay-instructions.ipynb @@ -5,7 +5,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-argumentation/EssayInstructions.ipynb)" + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-augmentation/essay-instructions/essay-instructions.ipynb)" ] }, { @@ -210,7 +210,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "Python 3.8.10 64-bit", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -224,11 +224,11 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" }, "vscode": { "interpreter": { - "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" } } }, diff --git a/notebooks/data-argumentation/EssayRevision.md b/notebooks/data-augmentation/essay-revision/README.md similarity index 100% rename from notebooks/data-argumentation/EssayRevision.md rename to notebooks/data-augmentation/essay-revision/README.md diff --git a/notebooks/data-argumentation/EssayRevision.ipynb b/notebooks/data-augmentation/essay-revision/essay-revision.ipynb similarity index 97% rename from notebooks/data-argumentation/EssayRevision.ipynb rename to notebooks/data-augmentation/essay-revision/essay-revision.ipynb index 2397131c..1f21fd73 100644 --- a/notebooks/data-argumentation/EssayRevision.ipynb +++ b/notebooks/data-augmentation/essay-revision/essay-revision.ipynb @@ -5,16 +5,24 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-argumentation/EssayRevision.ipynb)" + "# Essay Revision" ] }, { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-augmentation/essay-revision/essay-revision.ipynb)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": { "id": "o0lAqmWhsiUe" }, "source": [ - "#Essay Revision\n", "The goal of this notebook is to use data argumentation to have data on improving essays. The way this is done is by taking a template \"good\" essay and making step by step changes that make it worse and add intructions on how to fix it." ] }, @@ -319,11 +327,11 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" }, "vscode": { "interpreter": { - "hash": "492d89208e1af30f4727fd53e254ea56e6b1a843b376782bfa5f6ce13d676265" + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" } } }, diff --git a/notebooks/data-argumentation/StackExchangeBuilder.md b/notebooks/data-augmentation/stackexchange-builder/README.md similarity index 100% rename from notebooks/data-argumentation/StackExchangeBuilder.md rename to notebooks/data-augmentation/stackexchange-builder/README.md diff --git a/notebooks/data-argumentation/StackExchangeBuilder.ipynb b/notebooks/data-augmentation/stackexchange-builder/stackexchange-builder.ipynb similarity index 99% rename from notebooks/data-argumentation/StackExchangeBuilder.ipynb rename to notebooks/data-augmentation/stackexchange-builder/stackexchange-builder.ipynb index b0dd9a8b..165ac336 100644 --- a/notebooks/data-argumentation/StackExchangeBuilder.ipynb +++ b/notebooks/data-augmentation/stackexchange-builder/stackexchange-builder.ipynb @@ -5,16 +5,24 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-argumentation/StackExchangeBuilder.ipynb)" + "# Ingest StackExchange data dumps" ] }, { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-augmentation/stackexchange-builder/stackexchange-builder.ipynb)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": { "id": "TB7CEfs8F-8u" }, "source": [ - "# Ingest StackExchange data dumps\n", "This notebook takes a StackExchange Data dump \"Posts.xml\" file and ingests it into a Pandas Dataframe. Outputs of the file can be JSON, JSONL, Parquet, or CSV. " ] }, @@ -1842,10 +1850,17 @@ }, "kernelspec": { "display_name": "Python 3", + "language": "python", "name": "python3" }, "language_info": { - "name": "python" + "name": "python", + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" + }, + "vscode": { + "interpreter": { + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" + } } }, "nbformat": 4, diff --git a/notebooks/data-argumentation/UnifiedQA.md b/notebooks/data-augmentation/unified-qa/README.md similarity index 100% rename from notebooks/data-argumentation/UnifiedQA.md rename to notebooks/data-augmentation/unified-qa/README.md diff --git a/notebooks/data-argumentation/UnifiedQA.ipynb b/notebooks/data-augmentation/unified-qa/unified-qa.ipynb similarity index 97% rename from notebooks/data-argumentation/UnifiedQA.ipynb rename to notebooks/data-augmentation/unified-qa/unified-qa.ipynb index 4b93f596..37c85b3d 100644 --- a/notebooks/data-argumentation/UnifiedQA.ipynb +++ b/notebooks/data-augmentation/unified-qa/unified-qa.ipynb @@ -9,11 +9,12 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "b2e3c95c", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/data-argumentation/UnifiedQA.ipynb)" + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-augmentation/unified-qa/unified-qa.ipynb)" ] }, { @@ -493,7 +494,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -507,7 +508,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" + }, + "vscode": { + "interpreter": { + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" + } } }, "nbformat": 4, diff --git a/notebooks/detoxify-evaluation/DetoxityEvaluation.ipynb b/notebooks/detoxify-evaluation/detoxify-evaluation.ipynb similarity index 99% rename from notebooks/detoxify-evaluation/DetoxityEvaluation.ipynb rename to notebooks/detoxify-evaluation/detoxify-evaluation.ipynb index 5ec0f019..ff2eca83 100644 --- a/notebooks/detoxify-evaluation/DetoxityEvaluation.ipynb +++ b/notebooks/detoxify-evaluation/detoxify-evaluation.ipynb @@ -5,7 +5,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/detoxify-evaluation/DetoxityEvaluation.ipynb)" + "# Detoxify evaluation" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/detoxify-evaluation/detoxify-evaluation.ipynb)" ] }, { @@ -23,7 +31,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Detoxify evaluation\n", "[Detoxify](https://github.com/unitaryai/detoxify) is a open source model used to identify prompts as toxic\n", "\n", "\"Image\n", @@ -472,7 +479,7 @@ ], "metadata": { "kernelspec": { - "display_name": "DetoxifyEvaluation", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -486,12 +493,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "aeda4fe49bddd52f429be231bf767df53f2b167abae0a465a8ef142aa6b97b8a" + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" } } }, diff --git a/notebooks/code-bugger/openbugger_example.md b/notebooks/openbugger/README.md similarity index 99% rename from notebooks/code-bugger/openbugger_example.md rename to notebooks/openbugger/README.md index d8611dd7..428bdfec 100644 --- a/notebooks/code-bugger/openbugger_example.md +++ b/notebooks/openbugger/README.md @@ -1,4 +1,4 @@ -# OpenBuggerNotebook +# OpenBugger https://github.com/furlat/OpenBugger/blob/main/README.md is a Python package that allows you to inject syntax and logic errors into your code. This can be diff --git a/notebooks/code-bugger/openbugger_example.ipynb b/notebooks/openbugger/openbugger_example.ipynb similarity index 96% rename from notebooks/code-bugger/openbugger_example.ipynb rename to notebooks/openbugger/openbugger_example.ipynb index 6e2acd27..62085f8e 100644 --- a/notebooks/code-bugger/openbugger_example.ipynb +++ b/notebooks/openbugger/openbugger_example.ipynb @@ -5,7 +5,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/code-bugger/openbugger_example.ipynb)" + "# OpenBugger Example" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/openbugger/openbugger_example.ipynb)" ] }, { @@ -272,12 +280,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6 (tags/v3.10.6:9c7b4bd, Aug 1 2022, 21:53:49) [MSC v.1932 64 bit (AMD64)]" + "version": "3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "ceba285e8b4e6478fe8ad229bc63940a90ad5cf3d143521e7c38823a2e915b21" + "hash": "25d5c2324055587ceaeef27650c79ce8358ea61d7689f2e0b8ada5d53f85bce4" } } }, diff --git a/openassistant/templates/__init__.py b/openassistant/templates/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/backend-development/run-local.sh b/scripts/backend-development/run-local.sh index 2433c67e..22701ace 100755 --- a/scripts/backend-development/run-local.sh +++ b/scripts/backend-development/run-local.sh @@ -6,6 +6,7 @@ pushd "$parent_path/../../backend" export DEBUG_SKIP_API_KEY_CHECK=True export DEBUG_USE_SEED_DATA=True +export DEBUG_SKIP_TOXICITY_CALCULATION=True export DEBUG_ALLOW_SELF_LABELING=True export DEBUG_SKIP_EMBEDDING_COMPUTATION=True diff --git a/scripts/backend-development/start-mock-server.sh b/scripts/backend-development/start-mock-server.sh index 35a202a6..e985d1cc 100755 --- a/scripts/backend-development/start-mock-server.sh +++ b/scripts/backend-development/start-mock-server.sh @@ -11,6 +11,9 @@ echo "Generating OpenAPI schema..." python -m main --print-openapi-schema > $OPENAPI_JSON_FILE_NAME echo "Done!" +echo "Formatting & Copying OpenAPI schema to docs directory..." +jq . $OPENAPI_JSON_FILE_NAME > ../docs/docs/api/openapi.json + # If oasst-mock-backend docker container is already running, # just restart it if [ "$(docker ps -q -f name=oasst-mock-backend)" ]; then diff --git a/website/package-lock.json b/website/package-lock.json index 672ddb05..b215f733 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -41,6 +41,7 @@ "react-dom": "18.2.0", "react-feature-flags": "^1.0.0", "react-icons": "^4.7.1", + "sharp": "^0.31.3", "swr": "^2.0.0", "tailwindcss": "^3.2.4", "use-debounce": "^9.0.2" @@ -14993,7 +14994,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -15083,6 +15083,16 @@ "file-uri-to-path": "1.0.0" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -15439,7 +15449,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -15859,8 +15868,7 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chrome-trace-event": { "version": "1.0.3", @@ -16162,6 +16170,18 @@ "node": ">=0.10.0" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -16175,6 +16195,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -16184,6 +16213,22 @@ "color-support": "bin.js" } }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/color2k": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.0.tgz", @@ -17524,6 +17569,20 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -17556,6 +17615,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -17701,6 +17768,14 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -18123,7 +18198,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -19255,6 +19329,14 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", @@ -20400,6 +20482,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -20665,6 +20752,11 @@ "assert-plus": "^1.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", @@ -21454,7 +21546,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -27077,6 +27168,17 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -27253,6 +27355,11 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -27342,6 +27449,11 @@ "node": ">=0.10.0" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -27494,6 +27606,52 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abi": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", + "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -31758,6 +31916,31 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -32009,7 +32192,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -32196,6 +32378,33 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -32530,7 +32739,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -33159,8 +33367,7 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-regex": { "version": "1.1.0", @@ -33712,6 +33919,58 @@ "node": ">=8" } }, + "node_modules/sharp": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -33750,6 +34009,62 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -34434,7 +34749,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -34443,7 +34757,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -34877,6 +35190,32 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -35439,7 +35778,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -48424,8 +48762,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -48485,6 +48822,16 @@ "file-uri-to-path": "1.0.0" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -48774,7 +49121,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -49079,8 +49425,7 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "chrome-trace-event": { "version": "1.0.3", @@ -49314,6 +49659,30 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -49327,6 +49696,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -50417,6 +50795,14 @@ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -50446,6 +50832,11 @@ "which-typed-array": "^1.1.8" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -50552,6 +50943,11 @@ "repeat-string": "^1.5.4" } }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -50898,7 +51294,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -51761,6 +52156,11 @@ } } }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "expect": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", @@ -52669,6 +53069,11 @@ } } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -52875,6 +53280,11 @@ "assert-plus": "^1.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", @@ -53468,8 +53878,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "iferr": { "version": "0.1.5", @@ -57731,6 +58140,11 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -57872,6 +58286,11 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -57948,6 +58367,11 @@ "to-regex": "^3.0.1" } }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -58046,6 +58470,42 @@ "tslib": "^2.0.3" } }, + "node-abi": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", + "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "requires": { + "semver": "^7.3.5" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + }, "node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -61022,6 +61482,25 @@ } } }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -61214,7 +61693,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -61346,6 +61824,29 @@ "schema-utils": "^3.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, "react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -61580,7 +62081,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -62062,8 +62562,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -62524,6 +63023,44 @@ "kind-of": "^6.0.2" } }, + "sharp": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", + "requires": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -62553,6 +63090,36 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -63139,7 +63706,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" }, @@ -63147,8 +63713,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, @@ -63474,6 +64039,29 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "telejson": { "version": "6.0.8", "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", @@ -63885,7 +64473,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } diff --git a/website/package.json b/website/package.json index 917c819b..dd0ca93a 100644 --- a/website/package.json +++ b/website/package.json @@ -58,6 +58,7 @@ "react-dom": "18.2.0", "react-feature-flags": "^1.0.0", "react-icons": "^4.7.1", + "sharp": "^0.31.3", "swr": "^2.0.0", "tailwindcss": "^3.2.4", "use-debounce": "^9.0.2" diff --git a/website/prisma/schema.prisma b/website/prisma/schema.prisma index f9eab3b7..dc6a700d 100644 --- a/website/prisma/schema.prisma +++ b/website/prisma/schema.prisma @@ -41,6 +41,7 @@ model User { email String? @unique emailVerified DateTime? image String? + isNew Boolean @default(true) role String @default("general") accounts Account[] diff --git a/website/src/components/FlaggableElement.tsx b/website/src/components/FlaggableElement.tsx index 05b0b923..b9e41a32 100644 --- a/website/src/components/FlaggableElement.tsx +++ b/website/src/components/FlaggableElement.tsx @@ -3,7 +3,6 @@ import { Button, Checkbox, Flex, - Grid, Popover, PopoverAnchor, PopoverArrow, @@ -15,7 +14,6 @@ import { SliderFilledTrack, SliderThumb, SliderTrack, - Spacer, Tooltip, useBoolean, useColorMode, @@ -23,6 +21,7 @@ import { useId, } from "@chakra-ui/react"; import { QuestionMarkCircleIcon } from "@heroicons/react/20/solid"; +import clsx from "clsx"; import { useEffect, useReducer } from "react"; import { FiAlertCircle } from "react-icons/fi"; import { get, post } from "src/lib/api"; @@ -146,24 +145,25 @@ export const FlaggableElement = (props: FlaggableElementProps) => { isLazy lazyBehavior="keepMounted" > - + {props.children} + -
+ -
+
-
+ - + -
+ -
+ {report.label_values.map(({ label, checked, value }, i) => ( + @@ -221,23 +221,30 @@ export function FlagCheckbox(props: FlagCheckboxProps): JSX.Element { const labelTextClass = colorMode === "light" - ? `text-${colors.light.text} hover:text-blue-700 float-left` - : `text-${colors.dark.text} hover:text-blue-400 float-left`; + ? `text-${colors.light.text} hover:text-blue-700` + : `text-${colors.dark.text} hover:text-blue-400`; return ( - - { - props.checkboxHandler(e.target.checked, props.idx); - }} - /> - - + +
+ { + props.checkboxHandler(e.target.checked, props.idx); + }} + /> + +
{ if (!props.checked) { diff --git a/website/src/components/Layout.tsx b/website/src/components/Layout.tsx index b8e196cd..b26b9bf2 100644 --- a/website/src/components/Layout.tsx +++ b/website/src/components/Layout.tsx @@ -54,6 +54,7 @@ export const getDashboardLayout = (page: React.ReactElement) => ( > {page} +
); diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index 22fee71c..2af60bbe 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -19,7 +19,7 @@ export function MessageTableEntry(props: MessageTableEntryProps) { return ( - + {props.enabled ? ( - + - + {item.text} ) : ( {item.text} diff --git a/website/src/components/UsersCell.tsx b/website/src/components/UsersCell.tsx index 63c923a7..f5545be1 100644 --- a/website/src/components/UsersCell.tsx +++ b/website/src/components/UsersCell.tsx @@ -15,6 +15,7 @@ import { import Link from "next/link"; import { useState } from "react"; import { get } from "src/lib/api"; +import type { User } from "src/types/Users"; import useSWR from "swr"; /** @@ -22,7 +23,7 @@ import useSWR from "swr"; */ const UsersCell = () => { const [pageIndex, setPageIndex] = useState(0); - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); // Fetch and save the users. // This follows useSWR's recommendation for simple pagination: @@ -53,21 +54,23 @@ const UsersCell = () => { Id - Email + Auth Id + Auth Method Name Role Update - {users.map((user, index) => ( - - {user.id} - {user.email} - {user.name} - {user.role} + {users.map(({ id, user_id, auth_method, display_name, role }) => ( + + {user_id} + {id} + {auth_method} + {display_name} + {role} - Manage + Manage ))} diff --git a/website/src/lib/oasst_api_client.ts b/website/src/lib/oasst_api_client.ts index b2ece97b..43ca6c49 100644 --- a/website/src/lib/oasst_api_client.ts +++ b/website/src/lib/oasst_api_client.ts @@ -1,4 +1,6 @@ import { JWT } from "next-auth/jwt"; +import type { Message } from "src/types/Conversation"; +import type { BackendUser } from "src/types/Users"; export class OasstError { message: string; @@ -43,6 +45,32 @@ export class OasstApiClient { return await resp.json(); } + private async put(path: string): Promise { + const resp = await fetch(`${this.oasstApiUrl}${path}`, { + method: "PUT", + headers: { + "X-API-Key": this.oasstApiKey, + }, + }); + + if (resp.status === 204) { + return null; + } + + if (resp.status >= 300) { + const errorText = await resp.text(); + let error: any; + try { + error = JSON.parse(errorText); + } catch (e) { + throw new OasstError(errorText, 0, resp.status); + } + throw new OasstError(error.message ?? error, error.error_code, resp.status); + } + + return await resp.json(); + } + private async get(path: string): Promise { const resp = await fetch(`${this.oasstApiUrl}${path}`, { method: "GET", @@ -121,6 +149,34 @@ export class OasstApiClient { }); } + /** + * Returns the `BackendUser` associated with `user_id` + */ + async fetch_user(user_id: string): Promise { + return this.get(`/api/v1/users/users/${user_id}`); + } + + /** + * Returns the `max_count` `BackendUser`s stored by the backend. + */ + async fetch_users(max_count: number): Promise { + return this.get(`/api/v1/frontend_users/?max_count=${max_count}`); + } + + /** + * Returns the `Message`s associated with `user_id` in the backend. + */ + async fetch_user_messages(user_id: string): Promise { + return this.get(`/api/v1/users/${user_id}/messages`); + } + + /** + * Updates the backend's knowledge about the `user_id`. + */ + async set_user_status(user_id: string, is_enabled: boolean, notes): Promise { + return this.put(`/api/v1/users/users/${user_id}?enabled=${is_enabled}¬es=${notes}`); + } + /** * Returns the valid labels for messages. */ diff --git a/website/src/pages/admin/manage_user/[id].tsx b/website/src/pages/admin/manage_user/[id].tsx index 6386c155..90698f4a 100644 --- a/website/src/pages/admin/manage_user/[id].tsx +++ b/website/src/pages/admin/manage_user/[id].tsx @@ -7,6 +7,7 @@ import { useEffect } from "react"; import { getAdminLayout } from "src/components/Layout"; import { UserMessagesCell } from "src/components/UserMessagesCell"; import { post } from "src/lib/api"; +import { oasstApiClient } from "src/lib/oasst_api_client"; import prisma from "src/lib/prismadb"; import useSWRMutation from "swr/mutation"; @@ -68,24 +69,17 @@ const ManageUser = ({ user }) => { }} >
+ - + + {({ field }) => ( - Username + Display Name )} - - {({ field }) => ( - - Email - - - )} - - {({ field }) => ( @@ -98,13 +92,21 @@ const ManageUser = ({ user }) => { )} + + {({ field }) => ( + + Notes + + + )} + - + ); @@ -114,15 +116,17 @@ const ManageUser = ({ user }) => { * Fetch the user's data on the server side when rendering. */ export async function getServerSideProps({ query }) { - const user = await prisma.user.findUnique({ - where: { id: query.id }, + const backend_user = await oasstApiClient.fetch_user(query.id); + const local_user = await prisma.user.findUnique({ + where: { id: backend_user.id }, select: { - id: true, - name: true, - email: true, role: true, }, }); + const user = { + ...backend_user, + role: local_user?.role || "general", + }; return { props: { user, diff --git a/website/src/pages/api/admin/update_user.ts b/website/src/pages/api/admin/update_user.ts index 95ddff4b..341ec736 100644 --- a/website/src/pages/api/admin/update_user.ts +++ b/website/src/pages/api/admin/update_user.ts @@ -1,22 +1,28 @@ import { withRole } from "src/lib/auth"; +import { oasstApiClient } from "src/lib/oasst_api_client"; import prisma from "src/lib/prismadb"; /** * Update's the user's data in the database. Accessible only to admins. */ const handler = withRole("admin", async (req, res) => { - const { id, role } = req.body; + const { id, auth_method, user_id, notes, role } = req.body; - await prisma.user.update({ - where: { - id, - }, - data: { - role, - }, - }); + // If the user is authorized by the web, update their role. + if (auth_method === "local") { + await prisma.user.update({ + where: { + id, + }, + data: { + role, + }, + }); + } + // Tell the backend the user's enabled or not enabled status. + await oasstApiClient.set_user_status(user_id, role !== "banned", notes); - res.status(200).end(); + res.status(200).json({}); }); export default handler; diff --git a/website/src/pages/api/admin/user_messages.ts b/website/src/pages/api/admin/user_messages.ts index 254bf9c6..236afa2d 100644 --- a/website/src/pages/api/admin/user_messages.ts +++ b/website/src/pages/api/admin/user_messages.ts @@ -1,15 +1,13 @@ import { withRole } from "src/lib/auth"; +import { oasstApiClient } from "src/lib/oasst_api_client"; +import type { Message } from "src/types/Conversation"; +/** + * Returns the messages recorded by the backend for a user. + */ const handler = withRole("admin", async (req, res) => { const { user } = req.query; - - const messagesRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/frontend_users/local/${user}/messages`, { - method: "GET", - headers: { - "X-API-Key": process.env.FASTAPI_KEY, - }, - }); - const messages = await messagesRes.json(); + const messages: Message[] = await oasstApiClient.fetch_user_messages(user as string); res.status(200).json(messages); }); diff --git a/website/src/pages/api/admin/users.ts b/website/src/pages/api/admin/users.ts index 7c71b667..04bcacf0 100644 --- a/website/src/pages/api/admin/users.ts +++ b/website/src/pages/api/admin/users.ts @@ -1,31 +1,44 @@ import { withRole } from "src/lib/auth"; +import { oasstApiClient } from "src/lib/oasst_api_client"; import prisma from "src/lib/prismadb"; -// The number of users to fetch in any request. -const PAGE_SIZE = 20; - /** * Returns a list of user results from the database when the requesting user is * a logged in admin. */ const handler = withRole("admin", async (req, res) => { - // Figure out the pagination index and skip that number of users. - // - // Note: with Prisma this isn't the most efficient but it's the only possible - // option with cuid based User IDs. - const { pageIndex } = req.query; - const skip = parseInt(pageIndex as string) * PAGE_SIZE || 0; + // TODO(#673): Update this to support pagination. - // Fetch 20 users. - const users = await prisma.user.findMany({ + // First, get all the users according to the backend. + const all_users = await oasstApiClient.fetch_users(20); + + // Next, get all the users stored in the web's auth datbase to fetch their role. + const local_user_ids = all_users.map(({ id }) => id); + const local_users = await prisma.user.findMany({ + where: { + id: { + in: local_user_ids, + }, + }, select: { id: true, role: true, - name: true, - email: true, }, - skip, - take: PAGE_SIZE, + }); + + // Combine the information by updating the set of full users with their role. + // Default any users without a role set locally as "general". + const local_user_map = local_users.reduce((result, user) => { + result.set(user.id, user.role); + return result; + }, new Map()); + + const users = all_users.map((user) => { + const role = local_user_map.get(user.id) || "general"; + return { + ...user, + role, + }; }); res.status(200).json(users); diff --git a/website/src/pages/api/auth/[...nextauth].ts b/website/src/pages/api/auth/[...nextauth].ts index 363c1404..58b4d8dd 100644 --- a/website/src/pages/api/auth/[...nextauth].ts +++ b/website/src/pages/api/auth/[...nextauth].ts @@ -50,7 +50,7 @@ if (boolean(process.env.DEBUG_LOGIN) || process.env.NODE_ENV === "development") where: { id: user.id, }, - update: {}, + update: user, create: user, }); return user; @@ -86,6 +86,7 @@ export const authOptions: AuthOptions = { */ async session({ session, token }) { session.user.role = token.role; + session.user.isNew = token.isNew; return session; }, /** @@ -93,11 +94,12 @@ export const authOptions: AuthOptions = { * This let's use forward the role to the session object. */ async jwt({ token }) { - const { role } = await prisma.user.findUnique({ + const { isNew, role } = await prisma.user.findUnique({ where: { id: token.sub }, - select: { role: true }, + select: { role: true, isNew: true }, }); token.role = role; + token.isNew = isNew; return token; }, }, diff --git a/website/src/pages/api/update_task.ts b/website/src/pages/api/update_task.ts index f3aa6fb1..02982daa 100644 --- a/website/src/pages/api/update_task.ts +++ b/website/src/pages/api/update_task.ts @@ -17,6 +17,9 @@ const handler = withoutRole("banned", async (req, res, token) => { // Parse out the local task ID and the interaction contents. const { id: frontendId, content, update_type } = req.body; + // Record that the user has done meaningful work and is no longer new. + await prisma.user.update({ where: { id: token.sub }, data: { isNew: false } }); + // Accept the task so that we can complete it, this will probably go away soon. const registeredTask = await prisma.registeredTask.findUniqueOrThrow({ where: { id: frontendId } }); const task = registeredTask.task as Prisma.JsonObject; diff --git a/website/src/pages/auth/signin.tsx b/website/src/pages/auth/signin.tsx index 9a1d91a8..c2f05e69 100644 --- a/website/src/pages/auth/signin.tsx +++ b/website/src/pages/auth/signin.tsx @@ -94,7 +94,14 @@ function Signin({ csrfToken, providers }) { {email && (
- +