mirror of
https://github.com/kevinthedang/discord-ollama.git
synced 2025-12-12 11:56:06 -05:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f61f6bc6c | ||
|
|
5d02800c3f | ||
|
|
5061dab335 | ||
|
|
947ff89958 | ||
|
|
6a9ee2d6d0 |
@@ -1,12 +1,6 @@
|
||||
# Discord token for the bot
|
||||
CLIENT_TOKEN = BOT_TOKEN
|
||||
|
||||
# model for the bot to query from (i.e. llama2 [llama2:13b], mistral, codellama, etc... )
|
||||
MODEL = MODEL_NAME
|
||||
|
||||
# discord bot user id for mentions
|
||||
CLIENT_UID = BOT_USER_ID
|
||||
|
||||
# ip/port address of docker container, I use 172.18.0.3 for docker, 127.0.0.1 for local
|
||||
OLLAMA_IP = IP_ADDRESS
|
||||
OLLAMA_PORT = PORT
|
||||
|
||||
25
.github/CONTRIBUTING.md
vendored
25
.github/CONTRIBUTING.md
vendored
@@ -1,31 +1,38 @@
|
||||
<!--
|
||||
Author: Kevin Dang
|
||||
Date: 1-30-2024
|
||||
Author: Kevin Dang
|
||||
Date: 1-30-2024
|
||||
Changes:
|
||||
10-01-2024 - Jonathan Smoley
|
||||
-->
|
||||
|
||||
## Naming Conventions
|
||||
* Branches
|
||||
* prefix your branch name with the type of contribution:
|
||||
* features: `'feature/**'`
|
||||
* releases: `'releases/**'`
|
||||
* bugs: `'bug/**'`
|
||||
|
||||
## Run the Bot
|
||||
* Refer to all sections below before running the bot.
|
||||
* You should now have `Ollama`, `NodeJS`, ran `npm install`.
|
||||
* You will also need a discord bot to run. Refer to the [developer portal](https://discord.com/developers/) to learn how to set one up and invite it to your server. If that does not help then look up a YouTube video like this [one](https://www.youtube.com/watch?v=KZ3tIGHU314&ab_channel=UnderCtrl).
|
||||
* Now run `npm run start` to run the client and ollama at the same time (this must be one in wsl or a Linux distro)
|
||||
|
||||
* Now run `npm run client` to run the client (this must be done in wsl or a Linux distro)
|
||||
|
||||
## Set up (Development-side)
|
||||
* Pull the repository using `https://github.com/kevinthedang/discord-ollama.git`.
|
||||
* Refer to `Ollama Setup` in the readme to set up Ollama.
|
||||
* Refer to `Environment Setup` in the readme to set up Ollama.
|
||||
* This must be set up in a Linux environment or wsl2.
|
||||
* Install NodeJS `v18.18.2`
|
||||
* You can check out `Resources` and `To Run` in the readme for a bit of help.
|
||||
* You can check out `Resources` in the readme for a bit of help.
|
||||
* You can also reference [NodeJS Setup](#nodejs-setup)
|
||||
* When you have the project pulled from github, open up a terminal and run `npm i` or `npm install` to get all of the packages for the project.
|
||||
* In some kind of terminal (`git bash` is good) to run the client. You can run Ollama but opening up wsl2 and typing `ollama serve`.
|
||||
* Refer to `Ollama Setup` if there are any issues.
|
||||
|
||||
## Environment
|
||||
* You will need two environment files:
|
||||
* You will need an environment file:
|
||||
* `.env`: for running the bot
|
||||
* Please refer to `.env.sample` for all environment variables to include
|
||||
* `.env.dev.local`: also runs the bot, but with development variables
|
||||
* Currently there are no differences between the two, but when needed, you may add environment variables as needed.
|
||||
|
||||
## NodeJS Setup
|
||||
* Install [nvm](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) using `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash`
|
||||
|
||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -31,8 +31,6 @@ jobs:
|
||||
run: |
|
||||
touch .env
|
||||
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
|
||||
echo MODEL = ${{ secrets.MODEL }} >> .env
|
||||
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
|
||||
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
|
||||
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
|
||||
|
||||
@@ -59,8 +57,6 @@ jobs:
|
||||
run: |
|
||||
touch .env
|
||||
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
|
||||
echo MODEL = ${{ secrets.MODEL }} >> .env
|
||||
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
|
||||
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
|
||||
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
|
||||
|
||||
|
||||
49
.github/workflows/coverage.yml
vendored
Normal file
49
.github/workflows/coverage.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Coverage
|
||||
run-name: Code Coverage
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
Discord-Node-Coverage:
|
||||
runs-on: ubuntu-latest
|
||||
environment: coverage
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node Environment lts/hydrogen
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/hydrogen
|
||||
cache: "npm"
|
||||
|
||||
- name: Install Project Dependencies
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Create Environment Variables
|
||||
run: |
|
||||
touch .env
|
||||
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
|
||||
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
|
||||
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
|
||||
|
||||
- name: Collect Code Coverage
|
||||
run: |
|
||||
LINE_PCT=$(npm run test:coverage | tail -2 | head -1 | awk '{print $3}')
|
||||
echo "COVERAGE=$LINE_PCT" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload Code Coverage
|
||||
uses: schneegans/dynamic-badges-action@v1.7.0
|
||||
with:
|
||||
auth: ${{ secrets.GIST_SECRET }}
|
||||
gistID: ${{ vars.GIST_ID }}
|
||||
filename: coverage.json
|
||||
label: Coverage
|
||||
message: ${{ env.COVERAGE }}
|
||||
valColorRange: ${{ env.COVERAGE }}
|
||||
maxColorRange: 100
|
||||
minColorRange: 0
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -24,8 +24,6 @@ jobs:
|
||||
run: |
|
||||
touch .env
|
||||
echo CLIENT_TOKEN = NOT_REAL_TOKEN >> .env
|
||||
echo MODEL = ${{ secrets.MODEL }} >> .env
|
||||
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
|
||||
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
|
||||
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
|
||||
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -39,8 +39,6 @@ jobs:
|
||||
run: |
|
||||
touch .env
|
||||
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
|
||||
echo MODEL = ${{ secrets.MODEL }} >> .env
|
||||
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
|
||||
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
|
||||
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/build.yml"><img alt="Build Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/build.yml/badge.svg" /></a>
|
||||
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/release.yml"><img alt="Release Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/release.yml/badge.svg" /></a>
|
||||
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/test.yml"><img alt="Testing Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/test.yml/badge.svg" /></a>
|
||||
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/coverage.yml"><img alt="Code Coverage" src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/kevinthedang/bc7b5dcfa16561ab02bb3df67a99b22d/raw/coverage.json"></a>
|
||||
</div>
|
||||
|
||||
## About/Goals
|
||||
@@ -24,8 +25,8 @@ The project aims to:
|
||||
* [x] User vs. Server Preferences
|
||||
* [ ] Redis Caching
|
||||
* [x] Administrator Role Compatible
|
||||
* [x] Multi-User Chat Generation (Multiple users chatting at the same time) - This was built into from Ollama `v0.2.1+`
|
||||
* [ ] Automatic and Manual model pulling through the Discord client
|
||||
* [x] Multi-User Chat Generation (Multiple users chatting at the same time) - This was built in from Ollama `v0.2.1+`
|
||||
* [x] Automatic and Manual model pulling through the Discord client
|
||||
* [ ] Allow others to create their own models personalized for their own servers!
|
||||
* [ ] Documentation on creating your own LLM
|
||||
* [ ] Documentation on web scrapping and cleaning
|
||||
@@ -54,4 +55,4 @@ The project aims to:
|
||||
* [Kevin Dang](https://github.com/kevinthedang)
|
||||
* [Jonathan Smoley](https://github.com/JT2M0L3Y)
|
||||
|
||||
[discord-ollama](https://github.com/kevinthedang/discord-ollama) © 2023 by [Kevin Dang](https://github.com/kevinthedang) is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
||||
[discord-ollama](https://github.com/kevinthedang/discord-ollama) © 2023 by [Kevin Dang](https://github.com/kevinthedang) is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
||||
|
||||
@@ -7,11 +7,9 @@ services:
|
||||
build: ./ # find docker file in designated path
|
||||
container_name: discord
|
||||
restart: always # rebuild container always
|
||||
image: kevinthedang/discord-ollama:0.6.0
|
||||
image: kevinthedang/discord-ollama:0.7.0
|
||||
environment:
|
||||
CLIENT_TOKEN: ${CLIENT_TOKEN}
|
||||
MODEL: ${MODEL}
|
||||
CLIENT_UID: ${CLIENT_UID}
|
||||
OLLAMA_IP: ${OLLAMA_IP}
|
||||
OLLAMA_PORT: ${OLLAMA_PORT}
|
||||
networks:
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||

|
||||
|
||||
* You will also need your App's **Client ID**, navigate to **OAuth2** and copy your id.
|
||||
|
||||

|
||||
|
||||
* That should be all of the environment variables needed from Discord, now we need this app on your server.
|
||||
* Navigate to **Installation** and Copy the provided **Install Link** to allow your App to your server.
|
||||
* You should set the **Guild Install** permissions as you like, for this purpose we will allow admin priviledges for now. Ensure the **bot** scope is added to do this.
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
* Follow this guide to setup [Docker](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04)
|
||||
* If on Windows, download [Docker Desktop](https://docs.docker.com/desktop/install/windows-install/) to get the docker engine.
|
||||
* Please also install [Docker Compose](https://docs.docker.com/compose/install/linux/) for easy running. If not, there are [scripts](#manual-run-with-docker) to set everything up.
|
||||
* **IMPORTANT NOTE**: Currently, it seems like wsl does not like Nvidia Container Toolkit. It will work initially then reset it for some odd reason. For now, it is advised to use an actually Linux machine to run using Docker. If you do not care about utilizing your GPU or don't even have a Nvidia GPU then disregard this.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Currently, it seems like wsl does not like Nvidia Container Toolkit. It will work initially then reset it for some odd reason. For now, it is advised to use an actually Linux machine to run using Docker. If you do not care about utilizing your GPU or don't even have a Nvidia GPU then disregard this.
|
||||
|
||||
## Nvidia Container Toolkit Setup
|
||||
### Installation with Apt
|
||||
@@ -48,8 +50,6 @@ sudo systemctl restart docker
|
||||
* `SUBNET_ADDRESS = 172.18.0.0`
|
||||
* Don't understand any of this? watch a Networking video to understand subnetting.
|
||||
* You also need all environment variables shown in [`.env.sample`](../.env.sample)
|
||||
* You will need a model in the container for this to work properly, on Docker Desktop go to the `Containers` tab, select the `ollama` container, and select `Exec` to run as root on your container. Now, run `ollama pull [model name]` to get your model.
|
||||
* For Linux Servers, you need another shell to pull the model, or if you run `docker compose build && docker compose up -d`, then it will run in the background to keep your shell. Run `docker exec -it ollama bash` to get into the container and run the samme pull command above.
|
||||
* Otherwise, there is no need to install any npm packages for this, you just need to run `npm run start` to pull the containers and spin them up.
|
||||
* For cleaning up on Linux (or Windows), run the following commands:
|
||||
* `docker compose stop`
|
||||
|
||||
@@ -11,14 +11,17 @@
|
||||
* You can now interact with the model you just ran (it might take a second to startup).
|
||||
* Response time varies with processing power!
|
||||
|
||||
> [!NOTE]
|
||||
> You can now pull models directly from the Discord client using `/pull-model <model-name>` or `/switch-model <model-name>`. They must exist from your local model library or from the [Ollama Model Library](https://ollama.com/library)
|
||||
|
||||
## To Run Locally (without Docker)
|
||||
* Run `npm install` to install the npm packages.
|
||||
* Ensure that your [.env](../.env.sample) file's `OLLAMA_IP` is `127.0.0.1` to work properly.
|
||||
* You only need your `CLIENT_TOKEN`, `MODEL`, `CLIENT_UID`, `OLLAMA_IP`, `OLLAMA_PORT`.
|
||||
* You only need your `CLIENT_TOKEN`, `OLLAMA_IP`, `OLLAMA_PORT`.
|
||||
* The ollama ip and port should just use it's defaults by nature. If not, utilize `OLLAMA_IP = 127.0.0.1` and `OLLAMA_PORT = 11434`.
|
||||
* Now, you can run the bot by running `npm run client` which will build and run the decompiled typescript and run the setup for ollama.
|
||||
* **IMPORTANT**: This must be ran in the wsl/Linux instance to work properly! Using Command Prompt/Powershell/Git Bash/etc. will not work on Windows (at least in my experience).
|
||||
* Refer to the [resources](../README.md#resources) on what node version to use.
|
||||
* If you are using wsl, open up a separate terminal/shell to startup the ollama service. Again, if you are running an older ollama, you must run `ollama serve` in that shell.
|
||||
* If you are on an actual Linux machine/VM there is no need for another terminal (unless you have an older ollama version).
|
||||
* If you do not have a model, you will need to run `ollama pull [model name]` in a separate terminal to get it.
|
||||
* If you do not have a model, you **can optionally** run `ollama pull [model name]` in wsl prior to application start. You are not required as it can be pulled from the Discord client.
|
||||
529
package-lock.json
generated
529
package-lock.json
generated
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "discord-ollama",
|
||||
"version": "0.6.0",
|
||||
"version": "0.7.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "discord-ollama",
|
||||
"version": "0.6.0",
|
||||
"version": "0.7.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.15.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"ollama": "^0.5.8"
|
||||
"ollama": "^0.5.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.1",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"@types/node": "^22.7.5",
|
||||
"@vitest/coverage-v8": "^2.1.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
"tsx": "^4.19.1",
|
||||
"typescript": "^5.6.3",
|
||||
"vitest": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
@@ -700,9 +700,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
|
||||
"integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
|
||||
"integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -713,9 +713,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
|
||||
"integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
|
||||
"integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -726,9 +726,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
|
||||
"integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
|
||||
"integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -739,9 +739,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
|
||||
"integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
|
||||
"integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -752,9 +752,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
|
||||
"integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
|
||||
"integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -765,9 +765,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
|
||||
"integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
|
||||
"integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -778,9 +778,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -791,9 +791,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
|
||||
"integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
|
||||
"integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -804,9 +804,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -817,9 +817,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -830,9 +830,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -843,9 +843,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -856,9 +856,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
|
||||
"integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
|
||||
"integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -869,9 +869,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -882,9 +882,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -895,9 +895,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -966,15 +966,15 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz",
|
||||
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
|
||||
"version": "22.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
|
||||
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
@@ -988,19 +988,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
|
||||
"integrity": "sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.2.tgz",
|
||||
"integrity": "sha512-b7kHrFrs2urS0cOk5N10lttI8UdJ/yP3nB4JYTREvR5o18cR99yPpK4gK8oQgI42BVv0ILWYUSYB7AXkAUDc0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.3.0",
|
||||
"@bcoe/v8-coverage": "^0.2.3",
|
||||
"debug": "^4.3.5",
|
||||
"debug": "^4.3.6",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-lib-source-maps": "^5.0.6",
|
||||
"istanbul-reports": "^3.1.7",
|
||||
"magic-string": "^0.30.10",
|
||||
"magic-string": "^0.30.11",
|
||||
"magicast": "^0.3.4",
|
||||
"std-env": "^3.7.0",
|
||||
"test-exclude": "^7.0.1",
|
||||
@@ -1010,17 +1010,23 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vitest": "2.0.5"
|
||||
"@vitest/browser": "2.1.2",
|
||||
"vitest": "2.1.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vitest/browser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz",
|
||||
"integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz",
|
||||
"integrity": "sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/spy": "2.0.5",
|
||||
"@vitest/utils": "2.0.5",
|
||||
"@vitest/spy": "2.1.2",
|
||||
"@vitest/utils": "2.1.2",
|
||||
"chai": "^5.1.1",
|
||||
"tinyrainbow": "^1.2.0"
|
||||
},
|
||||
@@ -1028,10 +1034,37 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.2.tgz",
|
||||
"integrity": "sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/spy": "^2.1.0-beta.1",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.11"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitest/spy": "2.1.2",
|
||||
"msw": "^2.3.5",
|
||||
"vite": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"msw": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz",
|
||||
"integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz",
|
||||
"integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tinyrainbow": "^1.2.0"
|
||||
@@ -1041,12 +1074,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz",
|
||||
"integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.2.tgz",
|
||||
"integrity": "sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/utils": "2.0.5",
|
||||
"@vitest/utils": "2.1.2",
|
||||
"pathe": "^1.1.2"
|
||||
},
|
||||
"funding": {
|
||||
@@ -1054,13 +1087,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz",
|
||||
"integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.2.tgz",
|
||||
"integrity": "sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "2.0.5",
|
||||
"magic-string": "^0.30.10",
|
||||
"@vitest/pretty-format": "2.1.2",
|
||||
"magic-string": "^0.30.11",
|
||||
"pathe": "^1.1.2"
|
||||
},
|
||||
"funding": {
|
||||
@@ -1068,9 +1101,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz",
|
||||
"integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz",
|
||||
"integrity": "sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tinyspy": "^3.0.0"
|
||||
@@ -1080,13 +1113,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz",
|
||||
"integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.2.tgz",
|
||||
"integrity": "sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "2.0.5",
|
||||
"estree-walker": "^3.0.3",
|
||||
"@vitest/pretty-format": "2.1.2",
|
||||
"loupe": "^3.1.1",
|
||||
"tinyrainbow": "^1.2.0"
|
||||
},
|
||||
@@ -1249,12 +1281,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
||||
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@@ -1385,29 +1417,6 @@
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
|
||||
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^8.0.1",
|
||||
"human-signals": "^5.0.0",
|
||||
"is-stream": "^3.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^5.1.0",
|
||||
"onetime": "^6.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
@@ -1443,27 +1452,6 @@
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-func-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
|
||||
"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.7.6",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz",
|
||||
@@ -1535,15 +1523,6 @@
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
@@ -1553,18 +1532,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -1647,13 +1614,10 @@
|
||||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
|
||||
},
|
||||
"node_modules/loupe": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz",
|
||||
"integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-func-name": "^2.0.1"
|
||||
}
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
|
||||
"integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
@@ -1667,9 +1631,9 @@
|
||||
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.11",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
|
||||
"integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
|
||||
"version": "0.30.12",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
|
||||
"integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||
@@ -1708,24 +1672,6 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
@@ -1736,9 +1682,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
@@ -1759,56 +1705,14 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path/node_modules/path-key": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
|
||||
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ollama": {
|
||||
"version": "0.5.8",
|
||||
"resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.8.tgz",
|
||||
"integrity": "sha512-frBGdfSV34i7JybLZUeyCYDx0CMyDiG4On8xOK+cNRWM04HImhoWgIMpF4p7vTkQumadbSxOteR7SZyKqNmOXg==",
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.9.tgz",
|
||||
"integrity": "sha512-F/KZuDRC+ZsVCuMvcOYuQ6zj42/idzCkkuknGyyGVmNStMZ/sU3jQpvhnl4SyC0+zBzLiKNZJnJeuPFuieWZvQ==",
|
||||
"dependencies": {
|
||||
"whatwg-fetch": "^3.6.20"
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
|
||||
@@ -1856,15 +1760,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.41",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
|
||||
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
|
||||
"version": "8.4.47",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -1882,8 +1786,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.1",
|
||||
"source-map-js": "^1.2.0"
|
||||
"picocolors": "^1.1.0",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
@@ -1899,12 +1803,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
|
||||
"integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz",
|
||||
"integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.5"
|
||||
"@types/estree": "1.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
@@ -1914,22 +1818,22 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.21.2",
|
||||
"@rollup/rollup-android-arm64": "4.21.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.21.2",
|
||||
"@rollup/rollup-darwin-x64": "4.21.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.21.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.21.2",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.21.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.21.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.21.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.21.2",
|
||||
"@rollup/rollup-android-arm-eabi": "4.24.0",
|
||||
"@rollup/rollup-android-arm64": "4.24.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.24.0",
|
||||
"@rollup/rollup-darwin-x64": "4.24.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.24.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.24.0",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.24.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.24.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.24.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.24.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -1985,9 +1889,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2101,18 +2005,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
|
||||
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
@@ -2169,6 +2061,12 @@
|
||||
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tinyexec": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz",
|
||||
"integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tinypool": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz",
|
||||
@@ -2188,9 +2086,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tinyspy": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz",
|
||||
"integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
|
||||
"integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -2260,9 +2158,9 @@
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.19.0",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz",
|
||||
"integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==",
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
|
||||
"integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "~0.23.0",
|
||||
@@ -2279,9 +2177,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
||||
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@@ -2312,13 +2210,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
|
||||
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
|
||||
"version": "5.4.8",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
|
||||
"integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.41",
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2371,15 +2269,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-node": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz",
|
||||
"integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.2.tgz",
|
||||
"integrity": "sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cac": "^6.7.14",
|
||||
"debug": "^4.3.5",
|
||||
"debug": "^4.3.6",
|
||||
"pathe": "^1.1.2",
|
||||
"tinyrainbow": "^1.2.0",
|
||||
"vite": "^5.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2799,29 +2696,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz",
|
||||
"integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.2.tgz",
|
||||
"integrity": "sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.3.0",
|
||||
"@vitest/expect": "2.0.5",
|
||||
"@vitest/pretty-format": "^2.0.5",
|
||||
"@vitest/runner": "2.0.5",
|
||||
"@vitest/snapshot": "2.0.5",
|
||||
"@vitest/spy": "2.0.5",
|
||||
"@vitest/utils": "2.0.5",
|
||||
"@vitest/expect": "2.1.2",
|
||||
"@vitest/mocker": "2.1.2",
|
||||
"@vitest/pretty-format": "^2.1.2",
|
||||
"@vitest/runner": "2.1.2",
|
||||
"@vitest/snapshot": "2.1.2",
|
||||
"@vitest/spy": "2.1.2",
|
||||
"@vitest/utils": "2.1.2",
|
||||
"chai": "^5.1.1",
|
||||
"debug": "^4.3.5",
|
||||
"execa": "^8.0.1",
|
||||
"magic-string": "^0.30.10",
|
||||
"debug": "^4.3.6",
|
||||
"magic-string": "^0.30.11",
|
||||
"pathe": "^1.1.2",
|
||||
"std-env": "^3.7.0",
|
||||
"tinybench": "^2.8.0",
|
||||
"tinybench": "^2.9.0",
|
||||
"tinyexec": "^0.3.0",
|
||||
"tinypool": "^1.0.0",
|
||||
"tinyrainbow": "^1.2.0",
|
||||
"vite": "^5.0.0",
|
||||
"vite-node": "2.0.5",
|
||||
"vite-node": "2.1.2",
|
||||
"why-is-node-running": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2836,8 +2733,8 @@
|
||||
"peerDependencies": {
|
||||
"@edge-runtime/vm": "*",
|
||||
"@types/node": "^18.0.0 || >=20.0.0",
|
||||
"@vitest/browser": "2.0.5",
|
||||
"@vitest/ui": "2.0.5",
|
||||
"@vitest/browser": "2.1.2",
|
||||
"@vitest/ui": "2.1.2",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
},
|
||||
|
||||
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "discord-ollama",
|
||||
"version": "0.6.0",
|
||||
"version": "0.7.0",
|
||||
"description": "Ollama Integration into discord",
|
||||
"main": "build/index.js",
|
||||
"exports": "./build/index.js",
|
||||
@@ -28,15 +28,15 @@
|
||||
"dependencies": {
|
||||
"discord.js": "^14.15.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"ollama": "^0.5.8"
|
||||
"ollama": "^0.5.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.1",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"@types/node": "^22.7.5",
|
||||
"@vitest/coverage-v8": "^2.1.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
"tsx": "^4.19.1",
|
||||
"typescript": "^5.6.3",
|
||||
"vitest": "^2.1.2"
|
||||
},
|
||||
"type": "module",
|
||||
"engines": {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Client, GatewayIntentBits } from 'discord.js'
|
||||
import { UserMessage, registerEvents } from './utils/events.js'
|
||||
import Events from './events/index.js'
|
||||
import { Ollama } from 'ollama'
|
||||
import { Queue } from './queues/queue.js'
|
||||
|
||||
// Import keys/tokens
|
||||
import { UserMessage, registerEvents } from './utils/index.js'
|
||||
import Events from './events/index.js'
|
||||
import Keys from './keys.js'
|
||||
|
||||
|
||||
@@ -19,21 +17,15 @@ const client = new Client({
|
||||
});
|
||||
|
||||
// initialize connection to ollama container
|
||||
const ollama = new Ollama({
|
||||
export const ollama = new Ollama({
|
||||
host: `http://${Keys.ipAddress}:${Keys.portAddress}`,
|
||||
})
|
||||
|
||||
// Create Queue managed by Events
|
||||
const messageHistory: Queue<UserMessage> = new Queue<UserMessage>
|
||||
|
||||
/**
|
||||
* register events for bot to listen to in discord
|
||||
* @param messageHistory message history for the llm
|
||||
* @param Events events to register
|
||||
* @param client the bot reference
|
||||
* @param Keys tokens from .env files
|
||||
*/
|
||||
registerEvents(client, Events, messageHistory, Keys, ollama)
|
||||
// register all events
|
||||
registerEvents(client, Events, messageHistory, ollama)
|
||||
|
||||
// Try to log in the client
|
||||
await client.login(Keys.clientToken)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openConfig } from '../utils/index.js'
|
||||
import { openConfig, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const Capacity: SlashCommand = {
|
||||
name: 'modify-capacity',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, TextChannel } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { clearChannelInfo } from '../utils/index.js'
|
||||
import { clearChannelInfo, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const ClearUserChannelHistory: SlashCommand = {
|
||||
name: 'clear-user-channel-history',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openConfig } from '../utils/index.js'
|
||||
import { openConfig, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const Disable: SlashCommand = {
|
||||
name: 'toggle-chat',
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Shutoff } from './shutoff.js'
|
||||
import { Capacity } from './capacity.js'
|
||||
import { PrivateThreadCreate } from './threadPrivateCreate.js'
|
||||
import { ClearUserChannelHistory } from './cleanUserChannelHistory.js'
|
||||
import { PullModel } from './pullModel.js'
|
||||
import { SwitchModel } from './switchModel.js'
|
||||
|
||||
export default [
|
||||
ThreadCreate,
|
||||
@@ -16,5 +18,7 @@ export default [
|
||||
Disable,
|
||||
Shutoff,
|
||||
Capacity,
|
||||
ClearUserChannelHistory
|
||||
ClearUserChannelHistory,
|
||||
PullModel,
|
||||
SwitchModel
|
||||
] as SlashCommand[]
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ApplicationCommandOptionType, ChannelType, Client, CommandInteraction } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openConfig } from '../utils/index.js'
|
||||
import { openConfig, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const MessageStream: SlashCommand = {
|
||||
name: 'message-stream',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openConfig } from '../utils/index.js'
|
||||
import { openConfig, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const MessageStyle: SlashCommand = {
|
||||
name: 'message-style',
|
||||
|
||||
47
src/commands/pullModel.ts
Normal file
47
src/commands/pullModel.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ApplicationCommandOptionType, ChannelType, Client, CommandInteraction } from "discord.js";
|
||||
import { SlashCommand } from "../utils/commands.js";
|
||||
import { ollama } from "../client.js";
|
||||
|
||||
export const PullModel: SlashCommand = {
|
||||
name: 'pull-model',
|
||||
description: 'pulls a model from the ollama model library',
|
||||
|
||||
// set available user options to pass to the command
|
||||
options: [
|
||||
{
|
||||
name: 'model-to-pull',
|
||||
description: 'the name of the model to pull',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true
|
||||
}
|
||||
],
|
||||
|
||||
// Pull for model from Ollama library
|
||||
run: async (client: Client, interaction: CommandInteraction) => {
|
||||
// defer reply to avoid timeout
|
||||
await interaction.deferReply()
|
||||
const modelInput: string = interaction.options.get('model-to-pull')!!.value as string
|
||||
|
||||
// fetch channel and message
|
||||
const channel = await client.channels.fetch(interaction.channelId)
|
||||
if (!channel || channel.type !== (ChannelType.PrivateThread && ChannelType.PublicThread && ChannelType.GuildText)) return
|
||||
|
||||
try {
|
||||
// call ollama to pull desired model
|
||||
await ollama.pull({
|
||||
model: modelInput
|
||||
})
|
||||
} catch (error) {
|
||||
// could not resolve pull or model unfound
|
||||
interaction.editReply({
|
||||
content: `Could not pull/locate the **${modelInput}** model within the [Ollama Model Library](https://ollama.com/library).\n\nPlease check the model library and try again.`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// successful pull
|
||||
interaction.editReply({
|
||||
content: `Successfully added **${modelInput}** into your local model library.`
|
||||
})
|
||||
}
|
||||
}
|
||||
75
src/commands/switchModel.ts
Normal file
75
src/commands/switchModel.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { ApplicationCommandOptionType, ChannelType, Client, CommandInteraction } from "discord.js";
|
||||
import { SlashCommand } from "../utils/commands.js";
|
||||
import { ollama } from "../client.js";
|
||||
import { ModelResponse } from "ollama";
|
||||
import { openConfig } from "../utils/index.js";
|
||||
|
||||
export const SwitchModel: SlashCommand = {
|
||||
name: 'switch-model',
|
||||
description: 'switches current model to preferred model to use.',
|
||||
|
||||
// set available user options to pass to the command
|
||||
options: [
|
||||
{
|
||||
name: 'model-to-use',
|
||||
description: 'the name of the model to use',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true
|
||||
}
|
||||
],
|
||||
|
||||
// Switch user preferred model if available in local library
|
||||
run: async (client: Client, interaction: CommandInteraction) => {
|
||||
await interaction.deferReply()
|
||||
|
||||
const modelInput: string = interaction.options.get('model-to-use')!!.value as string
|
||||
|
||||
// fetch channel and message
|
||||
const channel = await client.channels.fetch(interaction.channelId)
|
||||
if (!channel || channel.type !== (ChannelType.PrivateThread && ChannelType.PublicThread && ChannelType.GuildText)) return
|
||||
|
||||
try {
|
||||
// Phase 1: Set the model
|
||||
let switchSuccess = false
|
||||
await ollama.list()
|
||||
.then(response => {
|
||||
for (const model in response.models) {
|
||||
const currentModel: ModelResponse = response.models[model]
|
||||
if (currentModel.name.startsWith(modelInput)) {
|
||||
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, modelInput)
|
||||
|
||||
// successful switch
|
||||
interaction.editReply({
|
||||
content: `Successfully switched to **${modelInput}** as the preferred model for ${interaction.user.username}.`
|
||||
})
|
||||
switchSuccess = true
|
||||
}
|
||||
}
|
||||
})
|
||||
if (switchSuccess) return
|
||||
|
||||
// Phase 2: Try to get it regardless
|
||||
interaction.editReply({
|
||||
content: `Could not find **${modelInput}** in local model library, trying to pull it now...\n\nThis could take a few moments... Please be patient!`
|
||||
})
|
||||
|
||||
await ollama.pull({
|
||||
model: modelInput
|
||||
})
|
||||
|
||||
// set model now that it exists
|
||||
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, modelInput)
|
||||
|
||||
// We got the model!
|
||||
interaction.editReply({
|
||||
content: `Successfully added and set **${modelInput}** as your preferred model.`
|
||||
})
|
||||
} catch (error) {
|
||||
// could not resolve user model switch
|
||||
interaction.editReply({
|
||||
content: `Unable to switch user preferred model to **${modelInput}**.\n\n${error}\n\nPossible solution is to run \`/pull-model ${modelInput}\` and try again.`
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, TextChannel, ThreadChannel } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openChannelInfo } from '../utils/index.js'
|
||||
import { openChannelInfo, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const ThreadCreate: SlashCommand = {
|
||||
name: 'thread',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ChannelType, Client, CommandInteraction, TextChannel, ThreadChannel } from 'discord.js'
|
||||
import { SlashCommand } from '../utils/commands.js'
|
||||
import { openChannelInfo } from '../utils/index.js'
|
||||
import { openChannelInfo, SlashCommand } from '../utils/index.js'
|
||||
|
||||
export const PrivateThreadCreate: SlashCommand = {
|
||||
name: 'private-thread',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { embedMessage, event, Events, normalMessage, UserMessage } from '../utils/index.js'
|
||||
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, UserConfig, getAttachmentData } from '../utils/index.js'
|
||||
import { clean } from '../utils/mentionClean.js'
|
||||
import { TextChannel } from 'discord.js'
|
||||
import { embedMessage, event, Events, normalMessage, UserMessage, clean } from '../utils/index.js'
|
||||
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, UserConfig, getAttachmentData } from '../utils/index.js'
|
||||
|
||||
/**
|
||||
* Max Message length for free users is 2000 characters (bot or not).
|
||||
@@ -9,14 +8,16 @@ import { TextChannel } from 'discord.js'
|
||||
*
|
||||
* @param message the message received from the channel
|
||||
*/
|
||||
export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama }, message) => {
|
||||
log(`Message \"${clean(message.content)}\" from ${message.author.tag} in channel/thread ${message.channelId}.`)
|
||||
export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client }, message) => {
|
||||
const clientId = client.user!!.id
|
||||
const cleanedMessage = clean(message.content, clientId)
|
||||
log(`Message \"${cleanedMessage}\" from ${message.author.tag} in channel/thread ${message.channelId}.`)
|
||||
|
||||
// Do not respond if bot talks in the chat
|
||||
if (message.author.username === message.client.user.username) return
|
||||
|
||||
// Only respond if message mentions the bot
|
||||
if (!message.mentions.has(tokens.clientUid)) return
|
||||
if (!message.mentions.has(clientId)) return
|
||||
|
||||
// default stream to false
|
||||
let shouldStream = false
|
||||
@@ -48,7 +49,7 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
|
||||
getUserConfig(`${message.author.username}-config.json`, (config) => {
|
||||
if (config === undefined) {
|
||||
openConfig(`${message.author.username}-config.json`, 'message-style', false)
|
||||
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with \`message-style\` set as \`false\` for regular messages.\nPlease try chatting again.'))
|
||||
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with \`message-style\` set as \`false\` for regular message style.\nPlease try chatting again.'))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -64,6 +65,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
|
||||
|
||||
// set stream state
|
||||
shouldStream = config.options['message-stream'] as boolean || false
|
||||
|
||||
if (typeof config.options['switch-model'] !== 'string')
|
||||
reject(new Error(`No Model was set. Please set a model by running \`/switch-model <model of choice>\`.\n\nIf you do not have any models. Run \`/pull-model <model name>\`.`))
|
||||
|
||||
resolve(config)
|
||||
})
|
||||
@@ -104,6 +108,7 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
|
||||
|
||||
// get message attachment if exists
|
||||
const messageAttachment: string[] = await getAttachmentData(message.attachments.first())
|
||||
const model: string = userConfig.options['switch-model']
|
||||
|
||||
// set up new queue
|
||||
msgHist.setQueue(chatMessages)
|
||||
@@ -114,15 +119,15 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
|
||||
// push user response before ollama query
|
||||
msgHist.enqueue({
|
||||
role: 'user',
|
||||
content: clean(message.content),
|
||||
content: cleanedMessage,
|
||||
images: messageAttachment || []
|
||||
})
|
||||
|
||||
// undefined or false, use normal, otherwise use embed
|
||||
if (userConfig.options['message-style'])
|
||||
response = await embedMessage(message, ollama, tokens, msgHist, shouldStream)
|
||||
response = await embedMessage(message, ollama, model, msgHist, shouldStream)
|
||||
else
|
||||
response = await normalMessage(message, ollama, tokens, msgHist, shouldStream)
|
||||
response = await normalMessage(message, ollama, model, msgHist, shouldStream)
|
||||
|
||||
// If something bad happened, remove user query and stop
|
||||
if (response == undefined) { msgHist.pop(); return }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { event, Events, registerCommands } from '../utils/index.js'
|
||||
import { ActivityType } from 'discord.js'
|
||||
import { event, Events, registerCommands } from '../utils/index.js'
|
||||
import commands from '../commands/index.js'
|
||||
|
||||
// Log when the bot successfully logs in and export it
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { getEnvVar } from './utils/env.js'
|
||||
import { getEnvVar } from './utils/index.js'
|
||||
|
||||
export const Keys = {
|
||||
clientToken: getEnvVar('CLIENT_TOKEN'),
|
||||
model: getEnvVar('MODEL'),
|
||||
clientUid: getEnvVar('CLIENT_UID'),
|
||||
ipAddress: getEnvVar('OLLAMA_IP'),
|
||||
portAddress: getEnvVar('OLLAMA_PORT'),
|
||||
ipAddress: getEnvVar('OLLAMA_IP', '127.0.0.1'), // default ollama ip if none
|
||||
portAddress: getEnvVar('OLLAMA_PORT', '11434'), // default ollama port if none
|
||||
} as const // readonly keys
|
||||
|
||||
export default Keys
|
||||
@@ -1,9 +1,10 @@
|
||||
import { UserMessage } from './events.js'
|
||||
import { UserMessage } from './index.js'
|
||||
|
||||
export interface UserConfiguration {
|
||||
'message-stream'?: boolean,
|
||||
'message-style'?: boolean,
|
||||
'modify-capacity': number
|
||||
'modify-capacity': number,
|
||||
'switch-model': string
|
||||
}
|
||||
|
||||
export interface ServerConfiguration {
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
import { resolve } from 'path'
|
||||
import { config } from 'dotenv'
|
||||
|
||||
// Find config - ONLY WORKS WITH NODEMON
|
||||
const envFile = process.env.NODE_ENV === 'development' ? '.env.dev.local' : '.env'
|
||||
|
||||
// resolve config file
|
||||
const envFilePath = resolve(process.cwd(), envFile)
|
||||
const envFilePath = resolve(process.cwd(), '.env')
|
||||
const ipValidate: RegExp = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/
|
||||
|
||||
// set current environment variable file
|
||||
config({ path: envFilePath })
|
||||
|
||||
// Getter for environment variables
|
||||
/**
|
||||
* Method to validate if environment variables found in file utils/env.ts
|
||||
*
|
||||
* @param name Name of the environment variable in .env
|
||||
* @param fallback fallback value to set if environment variable is not set (used manually in src/keys.ts)
|
||||
* @returns environment variable value
|
||||
*/
|
||||
export function getEnvVar(name: string, fallback?: string): string {
|
||||
const value = process.env[name] ?? fallback
|
||||
if (value == undefined)
|
||||
if (!value)
|
||||
throw new Error(`Environment variable ${name} is not set.`)
|
||||
|
||||
// validate User-Generated Discord Application Tokens
|
||||
if (name === "CLIENT_TOKEN")
|
||||
if (value.length < 72) throw new Error(`The "CLIENT_TOKEN" provided is not of at least length 72.
|
||||
This is probably an invalid token unless Discord updated their token policy. Please provide a valid token.`)
|
||||
|
||||
// validate IPv4 address found in environment variables
|
||||
if (name.endsWith("_IP") || name.endsWith("_ADDRESS"))
|
||||
if (!ipValidate.test(value))
|
||||
throw new Error(`Environment variable ${name} does not follow IPv4 formatting.`)
|
||||
|
||||
// return env variable
|
||||
return value
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ClientEvents, Awaitable, Client, User } from 'discord.js'
|
||||
import type { ClientEvents, Awaitable, Client } from 'discord.js'
|
||||
import { Ollama } from 'ollama'
|
||||
import { Queue } from '../queues/queue.js'
|
||||
|
||||
@@ -8,17 +8,6 @@ export { Events } from 'discord.js'
|
||||
export type LogMethod = (...args: unknown[]) => void
|
||||
export type EventKeys = keyof ClientEvents // only wants keys of ClientEvents object
|
||||
|
||||
/**
|
||||
* Tokens to run the bot as intended
|
||||
* @param channel the channel where the bot will respond to queries
|
||||
* @param model chosen model for the ollama to utilize
|
||||
* @param clientUid the discord id for the bot
|
||||
*/
|
||||
export type Tokens = {
|
||||
model: string,
|
||||
clientUid: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters to run the chat query
|
||||
* @param model the model to run
|
||||
@@ -47,7 +36,6 @@ export interface EventProps {
|
||||
client: Client
|
||||
log: LogMethod
|
||||
msgHist: Queue<UserMessage>
|
||||
tokens: Tokens,
|
||||
ollama: Ollama
|
||||
}
|
||||
export type EventCallback<T extends EventKeys> = (
|
||||
@@ -70,14 +58,12 @@ export function event<T extends EventKeys>(key: T, callback: EventCallback<T>):
|
||||
* @param client initialized bot client
|
||||
* @param events all the exported events from the index.ts in the events dir
|
||||
* @param msgHist The message history of the bot
|
||||
* @param tokens the passed in environment tokens for the service
|
||||
* @param ollama the initialized ollama instance
|
||||
*/
|
||||
export function registerEvents(
|
||||
client: Client,
|
||||
events: Event[],
|
||||
msgHist: Queue<UserMessage>,
|
||||
tokens: Tokens,
|
||||
ollama: Ollama
|
||||
): void {
|
||||
for (const { key, callback } of events) {
|
||||
@@ -87,7 +73,7 @@ export function registerEvents(
|
||||
|
||||
// Handle Errors, call callback, log errors as needed
|
||||
try {
|
||||
callback({ client, log, msgHist, tokens, ollama }, ...args)
|
||||
callback({ client, log, msgHist, ollama }, ...args)
|
||||
} catch (error) {
|
||||
log('[Uncaught Error]', error)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ export * from './messageEmbed.js'
|
||||
export * from './messageNormal.js'
|
||||
export * from './commands.js'
|
||||
export * from './configInterfaces.js'
|
||||
export * from './mentionClean.js'
|
||||
|
||||
// handler imports
|
||||
export * from './handlers/chatHistoryHandler.js'
|
||||
|
||||
@@ -8,9 +8,9 @@ import Keys from "../keys.js"
|
||||
* - replace function works well for this
|
||||
*
|
||||
* @param message
|
||||
* @returns
|
||||
* @returns message without client id
|
||||
*/
|
||||
export function clean(message: string): string {
|
||||
const cleanedMessage: string = message.replace(`<@${Keys.clientUid}>`, '').trim()
|
||||
export function clean(message: string, clientId: string): string {
|
||||
const cleanedMessage: string = message.replace(`<@${clientId}>`, '').trim()
|
||||
return cleanedMessage
|
||||
}
|
||||
@@ -7,15 +7,13 @@ import { AbortableAsyncIterator } from 'ollama/src/utils.js'
|
||||
/**
|
||||
* Method to send replies as normal text on discord like any other user
|
||||
* @param message message sent by the user
|
||||
* @param tokens tokens to run query
|
||||
* @param model name of model to run query
|
||||
* @param msgHist message history between user and model
|
||||
*/
|
||||
export async function embedMessage(
|
||||
message: Message,
|
||||
ollama: Ollama,
|
||||
tokens: {
|
||||
model: string
|
||||
},
|
||||
model: string,
|
||||
msgHist: Queue<UserMessage>,
|
||||
stream: boolean
|
||||
): Promise<string> {
|
||||
@@ -34,7 +32,7 @@ export async function embedMessage(
|
||||
|
||||
// create params
|
||||
const params: ChatParams = {
|
||||
model: tokens.model,
|
||||
model: model,
|
||||
ollama: ollama,
|
||||
msgHist: msgHist.getItems()
|
||||
}
|
||||
|
||||
@@ -7,15 +7,13 @@ import { AbortableAsyncIterator } from 'ollama/src/utils.js'
|
||||
/**
|
||||
* Method to send replies as normal text on discord like any other user
|
||||
* @param message message sent by the user
|
||||
* @param tokens tokens to run query
|
||||
* @param model name of model to run query
|
||||
* @param msgHist message history between user and model
|
||||
*/
|
||||
export async function normalMessage(
|
||||
message: Message,
|
||||
ollama: Ollama,
|
||||
tokens: {
|
||||
model: string
|
||||
},
|
||||
model: string,
|
||||
msgHist: Queue<UserMessage>,
|
||||
stream: boolean
|
||||
): Promise<string> {
|
||||
@@ -26,7 +24,7 @@ export async function normalMessage(
|
||||
await message.channel.send('Generating Response . . .').then(async sentMessage => {
|
||||
try {
|
||||
const params: ChatParams = {
|
||||
model: tokens.model,
|
||||
model: model,
|
||||
ollama: ollama,
|
||||
msgHist: msgHist.getItems()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// expect takes a value from an expression
|
||||
// it marks a test case
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import commands from '../src/commands'
|
||||
import commands from '../src/commands/index.js'
|
||||
|
||||
/**
|
||||
* Commands test suite, tests the commands object
|
||||
@@ -12,7 +12,7 @@ import commands from '../src/commands'
|
||||
* @param name name of the test suite
|
||||
* @param fn function holding tests to run
|
||||
*/
|
||||
describe('#commands', () => {
|
||||
describe('Commands Existence', () => {
|
||||
// test definition of commands object
|
||||
it('references defined object', () => {
|
||||
// toBe compares the value to the expected value
|
||||
@@ -22,6 +22,51 @@ describe('#commands', () => {
|
||||
// test specific commands in the object
|
||||
it('references specific commands', () => {
|
||||
const commandsString = commands.map(e => e.name).join(', ')
|
||||
expect(commandsString).toBe('thread, private-thread, message-style, message-stream, toggle-chat, shutoff, modify-capacity, clear-user-channel-history')
|
||||
expect(commandsString).toBe('thread, private-thread, message-style, message-stream, toggle-chat, shutoff, modify-capacity, clear-user-channel-history, pull-model, switch-model')
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* User Commands Test suite for testing out commands
|
||||
* that would be run by users when using the application.
|
||||
*/
|
||||
describe('User Command Tests', () => {
|
||||
// test capacity command
|
||||
it('run modify-capacity command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run clear-user-channel-history command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run message-stream command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run message-style command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run thread command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run private-thread command', () => {
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Admin Commands Test suite for running administrative
|
||||
* commands with the application.
|
||||
*/
|
||||
describe('Admin Command Tests', () => {
|
||||
it('run shutoff command', () => {
|
||||
|
||||
})
|
||||
|
||||
it('run toggle-chat command', () => {
|
||||
|
||||
})
|
||||
})
|
||||
@@ -1,15 +1,23 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import events from '../src/events'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import events from '../src/events/index.js'
|
||||
|
||||
/**
|
||||
* Mocking ollama found in client.ts because pullModel.ts
|
||||
* relies on the existence on ollama. To prevent the mock,
|
||||
* we will have to pass through ollama to the commands somehow.
|
||||
*/
|
||||
vi.mock('../src/client.js', () => ({
|
||||
ollama: {
|
||||
pull: vi.fn() // Mock the pull method found with ollama
|
||||
}
|
||||
}))
|
||||
|
||||
/**
|
||||
* Events test suite, tests the events object
|
||||
* Each event is to be tested elsewhere, this file
|
||||
* is to ensure that the events object is defined.
|
||||
*
|
||||
* @param name name of the test suite
|
||||
* @param fn function holding tests to run
|
||||
*/
|
||||
describe('#events', () => {
|
||||
describe('Events Existence', () => {
|
||||
// test definition of events object
|
||||
it('references defined object', () => {
|
||||
expect(typeof events).toBe('object')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { getEnvVar } from '../src/utils'
|
||||
import { getEnvVar } from '../src/utils/index.js'
|
||||
|
||||
/**
|
||||
* getEnvVar test suite, tests the getEnvVar function
|
||||
@@ -7,7 +7,7 @@ import { getEnvVar } from '../src/utils'
|
||||
* @param name name of the test suite
|
||||
* @param fn function holding tests to run
|
||||
*/
|
||||
describe('#getEnvVar', () => {
|
||||
describe('Environment Setup', () => {
|
||||
// dummy set of keys
|
||||
const keys = {
|
||||
clientToken: 'CLIENT_TOKEN',
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { clean } from '../src/utils/mentionClean'
|
||||
import { getEnvVar } from '../src/utils'
|
||||
import { clean } from '../src/utils/index.js'
|
||||
|
||||
// Sample UID for testing
|
||||
const sampleId = '123456789'
|
||||
|
||||
/**
|
||||
* MentionClean test suite, tests the clean function
|
||||
@@ -8,10 +10,10 @@ import { getEnvVar } from '../src/utils'
|
||||
* @param name name of the test suite
|
||||
* @param fn function holding tests to run
|
||||
*/
|
||||
describe('#clean', () => {
|
||||
describe('Mentions Cleaned', () => {
|
||||
// test for id removal from message
|
||||
it('removes the mention from a message', () => {
|
||||
const message = `<@${getEnvVar('CLIENT_UID')}> Hello, World!`
|
||||
expect(clean(message)).toBe('Hello, World!')
|
||||
const message = `<@${sampleId}> Hello, World!`
|
||||
expect(clean(message, sampleId)).toBe('Hello, World!')
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { Queue } from '../src/queues/queue'
|
||||
import { Queue } from '../src/queues/queue.js'
|
||||
|
||||
/**
|
||||
* Queue test suite, tests the Queue class
|
||||
@@ -7,7 +7,7 @@ import { Queue } from '../src/queues/queue'
|
||||
* @param name name of the test suite
|
||||
* @param fn function holding tests to run
|
||||
*/
|
||||
describe('#queue', () => {
|
||||
describe('Queue Structure', () => {
|
||||
let queue= new Queue<string>()
|
||||
|
||||
// test for queue creation
|
||||
|
||||
@@ -4,9 +4,10 @@ import { defineConfig, configDefaults } from 'vitest/config'
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true, // <-- reduces test file imports
|
||||
reporters: ['verbose'], // <-- verbose output
|
||||
coverage: {
|
||||
exclude: [...configDefaults.exclude, 'build/*', 'tests/*'], // <-- exclude JS build
|
||||
reporter: ['text', 'html'] // <-- reports in text, html
|
||||
reporter: ['text-summary'] // <-- report in text-summary
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user