diff --git a/.github/workflows/gh-mvn-publish.yml b/.github/workflows/gh-mvn-publish.yml new file mode 100644 index 0000000..3070e3e --- /dev/null +++ b/.github/workflows/gh-mvn-publish.yml @@ -0,0 +1,58 @@ +name: Release Artifacts to GitHub Maven Packages + +on: + release: + types: [ created ] + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + server-id: github + settings-path: ${{ github.workspace }} + + - name: maven-settings-xml-action + uses: whelk-io/maven-settings-xml-action@v22 + with: + servers: '[{ "id": "${repo.id}", "username": "${repo.user}", "password": "${repo.pass}" }]' + + - name: Find and Replace + uses: jacobtomlinson/gha-find-replace@v3 + with: + find: "ollama4j-revision" + replace: ${{ github.ref_name }} + regex: false + + - name: Find and Replace + uses: jacobtomlinson/gha-find-replace@v3 + with: + find: "mvn-repo-id" + replace: github + regex: false + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: List keys + run: gpg -K + + - name: Build with Maven + run: mvn --file pom.xml -U clean package -Punit-tests + + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy -Punit-tests -s $GITHUB_WORKSPACE/settings.xml -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} -Drepo.id=github -Drepo.user=${{ secrets.GH_MVN_USER }} -Drepo.pass=${{ secrets.GH_MVN_PASS }} -DaltDeploymentRepository=github::default::https://maven.pkg.github.com/ollama4j/ollama4j + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index e1ac127..036ccb6 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -1,68 +1,95 @@ # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path -name: Test and Publish Package - -#on: -# release: -# types: [ "created" ] +name: Release Artifacts to Maven Central on: - push: - branches: [ "main" ] - workflow_dispatch: + release: + types: [ created ] + + +#on: +# pull_request: +# types: [ opened, reopened ] +# branches: [ "main" ] + jobs: build: + runs-on: ubuntu-latest + permissions: contents: write packages: write + steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' - distribution: 'adopt-hotspot' + java-version: '17' + distribution: 'temurin' server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file - - name: Build with Maven - run: mvn --file pom.xml -U clean package -Punit-tests - - name: Set up Apache Maven Central (Overwrite settings.xml) - uses: actions/setup-java@v3 - with: # running setup-java again overwrites the settings.xml - java-version: '11' - distribution: 'adopt-hotspot' - cache: 'maven' - server-id: ossrh - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} - gpg-passphrase: MAVEN_GPG_PASSPHRASE - - name: Set up Maven cache - uses: actions/cache@v3 + + - name: maven-settings-xml-action + uses: whelk-io/maven-settings-xml-action@v22 with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -B -ntp clean install - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 + servers: '[{ "id": "${repo.id}", "username": "${repo.user}", "password": "${repo.pass}" }]' + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: List keys + run: gpg -K + + - name: Find and Replace + uses: jacobtomlinson/gha-find-replace@v3 + with: + find: "ollama4j-revision" + replace: ${{ github.ref_name }} + regex: false + + - name: Find and Replace + uses: jacobtomlinson/gha-find-replace@v3 + with: + find: "mvn-repo-id" + replace: central + regex: false + + - name: Publish to Maven Central + run: mvn deploy -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} -Drepo.id=central -Drepo.user=${{ secrets.MVN_USER }} -Drepo.pass=${{ secrets.MVN_PASS }} + + - name: Upload Release Asset - JAR + uses: actions/upload-release-asset@v1 env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - name: Publish to GitHub Packages Apache Maven - # if: > - # github.event_name != 'pull_request' && - # github.ref_name == 'main' && - # contains(github.event.head_commit.message, 'release') - run: | - git config --global user.email "koujalgi.amith@gmail.com" - git config --global user.name "amithkoujalgi" - mvn -B -ntp -DskipTests -Pci-cd -Darguments="-DskipTests -Pci-cd" release:clean release:prepare release:perform + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/ollama4j-${{ github.ref_name }}.jar + asset_name: ollama4j-${{ github.ref_name }}.jar + asset_content_type: application/x-jar + + - name: Upload Release Asset - Javadoc JAR + uses: actions/upload-release-asset@v1 env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/ollama4j-${{ github.ref_name }}-javadoc.jar + asset_name: ollama4j-${{ github.ref_name }}-javadoc.jar + asset_content_type: application/x-jar + + - name: Upload Release Asset - Sources JAR + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/ollama4j-${{ github.ref_name }}-sources.jar + asset_name: ollama4j-${{ github.ref_name }}-sources.jar + asset_content_type: application/x-jar \ No newline at end of file diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index b421c1e..8d63cda 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -2,9 +2,8 @@ name: Deploy Docs to GH Pages on: - # Runs on pushes targeting the default branch - push: - branches: [ "main" ] + release: + types: [ created ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -47,6 +46,13 @@ jobs: - run: cd docs && npm ci - run: cd docs && npm run build + - name: Find and Replace + uses: jacobtomlinson/gha-find-replace@v3 + with: + find: "ollama4j-revision" + replace: ${{ github.ref_name }} + regex: false + - name: Build with Maven run: mvn --file pom.xml -U clean package && cp -r ./target/apidocs/. ./docs/build/apidocs diff --git a/.github/workflows/publish-javadoc.yml b/.github/workflows/publish-javadoc.yml deleted file mode 100644 index a346dbf..0000000 --- a/.github/workflows/publish-javadoc.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy Javadoc content to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: [ "none" ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - packages: write -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - runs-on: ubuntu-latest - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v3 - with: - java-version: '11' - distribution: 'adopt-hotspot' - server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - name: Build with Maven - run: mvn --file pom.xml -U clean package - - name: Setup Pages - uses: actions/configure-pages@v3 - - name: Upload artifact - uses: actions/upload-pages-artifact@v2 - with: - # Upload entire repository - path: './target/apidocs/.' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v2 diff --git a/.gitignore b/.gitignore index f8c9181..788123e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,8 @@ build/ ### Mac OS ### .DS_Store /.idea/ -/src/main/java/io/github/amithkoujalgi/ollama4j/core/localtests/ pom.xml.* -release.properties \ No newline at end of file +release.properties +!.idea/icon.svg + +src/main/java/io/github/ollama4j/localtests \ No newline at end of file diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 0000000..47529e1 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..1739c61 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +koujalgi.amith@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/Makefile b/Makefile index 6ec1612..7c5f2df 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ build: mvn -B clean install -ut: +unit-tests: mvn clean test -Punit-tests -it: +integration-tests: mvn clean verify -Pintegration-tests doxygen: diff --git a/README.md b/README.md index e45b4a3..b937f61 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,53 @@ ### Ollama4j -ollama4j-icon +

+ ollama4j-icon +

+ A Java library (wrapper/binding) for [Ollama](https://ollama.ai/) server. -Find more details on the [website](https://amithkoujalgi.github.io/ollama4j/). +Find more details on the [website](https://ollama4j.github.io/ollama4j/). -![GitHub stars](https://img.shields.io/github/stars/amithkoujalgi/ollama4j) -![GitHub forks](https://img.shields.io/github/forks/amithkoujalgi/ollama4j) -![GitHub watchers](https://img.shields.io/github/watchers/amithkoujalgi/ollama4j) -![GitHub repo size](https://img.shields.io/github/repo-size/amithkoujalgi/ollama4j) -![GitHub language count](https://img.shields.io/github/languages/count/amithkoujalgi/ollama4j) -![GitHub top language](https://img.shields.io/github/languages/top/amithkoujalgi/ollama4j) -![GitHub last commit](https://img.shields.io/github/last-commit/amithkoujalgi/ollama4j?color=green) -![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Famithkoujalgi%2Follama4j&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false) +
-[![codecov](https://codecov.io/gh/amithkoujalgi/ollama4j/graph/badge.svg?token=U0TE7BGP8L)](https://codecov.io/gh/amithkoujalgi/ollama4j) +![GitHub stars](https://img.shields.io/github/stars/ollama4j/ollama4j) +![GitHub forks](https://img.shields.io/github/forks/ollama4j/ollama4j) +![GitHub watchers](https://img.shields.io/github/watchers/ollama4j/ollama4j) +![Contributors](https://img.shields.io/github/contributors/ollama4j/ollama4j?style=social) +![GitHub License](https://img.shields.io/github/license/ollama4j/ollama4j) -![Build Status](https://github.com/amithkoujalgi/ollama4j/actions/workflows/maven-publish.yml/badge.svg) + +[//]: # (![GitHub repo size](https://img.shields.io/github/repo-size/ollama4j/ollama4j)) + +[//]: # (![GitHub top language](https://img.shields.io/github/languages/top/ollama4j/ollama4j)) + + +[//]: # (![JitPack Downloads This Month Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fjitpack.io%2Fapi%2Fdownloads%2Fio.github.ollama4j%2Follama4j&query=%24.month&label=JitPack%20Downloads%20-%20This%20Month)) + +[//]: # (![JitPack Downloads This Week Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fjitpack.io%2Fapi%2Fdownloads%2Fio.github.ollama4j%2Follama4j&query=%24.week&label=JitPack%20Downloads%20-%20This%20Week)) + +[//]: # (![JitPack Downloads Per Month Badge](https://jitpack.io/v/ollama4j/ollama4j/month.svg)) + +[//]: # (![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/ollama4j/ollama4j/total?label=GitHub%20Package%20Downloads)) + +![GitHub last commit](https://img.shields.io/github/last-commit/ollama4j/ollama4j?color=green) +[![codecov](https://codecov.io/gh/ollama4j/ollama4j/graph/badge.svg?token=U0TE7BGP8L)](https://codecov.io/gh/ollama4j/ollama4j) +![Build Status](https://github.com/ollama4j/ollama4j/actions/workflows/maven-publish.yml/badge.svg) + +
+ +[//]: # (![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Follama4j%2Follama4j&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)) + +[//]: # (![GitHub language count](https://img.shields.io/github/languages/count/ollama4j/ollama4j)) ## Table of Contents - [How does it work?](#how-does-it-work) - [Requirements](#requirements) - [Installation](#installation) -- [API Spec](#api-spec) -- [Demo APIs](#try-out-the-apis-with-ollama-server) +- [API Spec](https://ollama4j.github.io/ollama4j/category/apis---model-management) +- [Javadoc](https://ollama4j.github.io/ollama4j/apidocs/) - [Development](#development) - [Contributions](#get-involved) - [References](#references) @@ -46,63 +68,181 @@ Find more details on the [website](https://amithkoujalgi.github.io/ollama4j/). #### Requirements -![Java](https://img.shields.io/badge/Java-11_+-green.svg?style=just-the-message&labelColor=gray) +![Java](https://img.shields.io/badge/Java-11_+-green.svg?style=for-the-badge&labelColor=gray&label=Java&color=orange) -[![][ollama-shield]][ollama] **Or** [![][ollama-docker-shield]][ollama-docker] -[ollama]: https://ollama.ai/ + + + -[ollama-shield]: https://img.shields.io/badge/Ollama-Local_Installation-blue.svg?style=just-the-message&labelColor=gray + + + -#### Installation + + + + + + +
-[ollama-docker]: https://hub.docker.com/r/ollama/ollama +Local Installation -[ollama-docker-shield]: https://img.shields.io/badge/Ollama-Docker-blue.svg?style=just-the-message&labelColor=gray + + +Docker Installation + +
+ +Download for macOS + +Download for Windows + +Install on Linux + +```shell +curl -fsSL https://ollama.com/install.sh | sh +``` + + + + + +CPU only + +```shell +docker run -d -p 11434:11434 \ + -v ollama:/root/.ollama \ + --name ollama \ + ollama/ollama +``` + +NVIDIA GPU + +```shell +docker run -d -p 11434:11434 \ + --gpus=all \ + -v ollama:/root/.ollama \ + --name ollama \ + ollama/ollama +``` + +
+ +## Installation + +> [!NOTE] +> We are now publishing the artifacts to both Maven Central and GitHub package repositories. +> +> Track the releases [here](https://github.com/ollama4j/ollama4j/releases) and update the dependency version +> according to your requirements. + +### For Maven + +#### Using [Maven Central](https://central.sonatype.com/) + +[![][ollama4j-mvn-releases-shield]][ollama4j-mvn-releases-link] + +[ollama4j-mvn-releases-link]: https://central.sonatype.com/artifact/io.github.ollama4j/ollama4j/overview + +[ollama4j-mvn-releases-shield]: https://img.shields.io/maven-central/v/io.github.ollama4j/ollama4j?display_name=release&style=for-the-badge&label=From%20Maven%20Central In your Maven project, add this dependency: ```xml - io.github.amithkoujalgi + io.github.ollama4j ollama4j - 1.0.70 + 1.0.79 ``` -or +#### Using GitHub's Maven Package Repository -In your Gradle project, add the dependency using the Kotlin DSL or the Groovy DSL: +[![][ollama4j-releases-shield]][ollama4j-releases-link] -```kotlin -dependencies { +[ollama4j-releases-link]: https://github.com/ollama4j/ollama4j/releases - val ollama4jVersion = "1.0.70" +[ollama4j-releases-shield]: https://img.shields.io/github/v/release/ollama4j/ollama4j?display_name=release&style=for-the-badge&label=From%20GitHub%20Packages - implementation("io.github.amithkoujalgi:ollama4j:$ollama4jVersion") -} - ``` +1. Add `GitHub Maven Packages` repository to your project's `pom.xml` or your `settings.xml`: + +```xml + + + + github + GitHub Apache Maven Packages + https://maven.pkg.github.com/ollama4j/ollama4j + + true + + + true + + + +``` + +2. Add `GitHub` server to settings.xml. (Usually available at ~/.m2/settings.xml) + +```xml + + + + + github + YOUR-USERNAME + YOUR-TOKEN + + + +``` + +3. In your Maven project, add this dependency: + +```xml + + + io.github.ollama4j + ollama4j + 1.0.79 + +``` + +### For Gradle + +1. Add the dependency ```groovy dependencies { - implementation("io.github.amithkoujalgi:ollama4j:1.0.70") + implementation 'io.github.ollama4j:ollama4j:1.0.79' } ``` -Latest release: +[//]: # (Latest release:) -![Maven Central](https://img.shields.io/maven-central/v/io.github.amithkoujalgi/ollama4j) +[//]: # () -[![][lib-shield]][lib] +[//]: # (![Maven Central](https://img.shields.io/maven-central/v/io.github.ollama4j/ollama4j)) -[lib]: https://central.sonatype.com/artifact/io.github.amithkoujalgi/ollama4j +[//]: # () + +[//]: # ([![][lib-shield]][lib]) + +[lib]: https://central.sonatype.com/artifact/io.github.ollama4j/ollama4j [lib-shield]: https://img.shields.io/badge/ollama4j-get_latest_version-blue.svg?style=just-the-message&labelColor=gray #### API Spec -Find the full API specifications on the [website](https://amithkoujalgi.github.io/ollama4j/). +> [!TIP] +> Find the full API specifications on the [website](https://ollama4j.github.io/ollama4j/). #### Development @@ -115,19 +255,18 @@ make build Run unit tests: ```shell -make ut +make unit-tests ``` Run integration tests: ```shell -make it +make integration-tests ``` #### Releases -Releases (newer artifact versions) are done automatically on pushing the code to the `main` branch through GitHub -Actions CI workflow. +Newer artifacts are published via GitHub Actions CI workflow when a new release is created from `main` branch. #### Who's using Ollama4j? @@ -138,45 +277,60 @@ Actions CI workflow. - `ollama-translator`: Minecraft 1.20.6 spigot plugin allows to easily break language barriers by using ollama on the server to translate all messages into a specfic target language. - https://github.com/liebki/ollama-translator +- `Ollama4j Web UI`: A web UI for Ollama written in Java using Spring Boot and Vaadin framework and + Ollama4j. https://github.com/ollama4j/ollama4j-web-ui #### Traction -[![Star History Chart](https://api.star-history.com/svg?repos=amithkoujalgi/ollama4j&type=Date)](https://star-history.com/#amithkoujalgi/ollama4j&Date) - -### Areas of improvement - -- [x] Use Java-naming conventions for attributes in the request/response models instead of the - snake-case conventions. ( - possibly with Jackson-mapper's `@JsonProperty`) -- [x] Fix deprecated HTTP client code -- [x] Setup logging -- [x] Use lombok -- [x] Update request body creation with Java objects -- [ ] Async APIs for images -- [ ] Add custom headers to requests -- [x] Add additional params for `ask` APIs such as: - - [x] `options`: additional model parameters for the Modelfile such as `temperature` - - Supported [params](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values). - - [x] `system`: system prompt to (overrides what is defined in the Modelfile) - - [x] `template`: the full prompt or prompt template (overrides what is defined in the Modelfile) - - [x] `context`: the context parameter returned from a previous request, which can be used to keep a - short - conversational memory - - [x] `stream`: Add support for streaming responses from the model -- [ ] Add test cases -- [ ] Handle exceptions better (maybe throw more appropriate exceptions) +[![Star History Chart](https://api.star-history.com/svg?repos=ollama4j/ollama4j&type=Date)](https://star-history.com/#ollama4j/ollama4j&Date) ### Get Involved +
+ +![Open Issues](https://img.shields.io/github/issues-raw/ollama4j/ollama4j) +![Closed Issues](https://img.shields.io/github/issues-closed-raw/ollama4j/ollama4j) +![Open PRs](https://img.shields.io/github/issues-pr-raw/ollama4j/ollama4j) +![Closed PRs](https://img.shields.io/github/issues-pr-closed-raw/ollama4j/ollama4j) +![Discussions](https://img.shields.io/github/discussions/ollama4j/ollama4j) + +
+ + +[//]: # (![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-raw/ollama4j/ollama4j)) + +[//]: # (![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-closed-raw/ollama4j/ollama4j)) + +[//]: # (![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr-raw/ollama4j/ollama4j)) + +[//]: # (![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr-closed-raw/ollama4j/ollama4j)) + +[//]: # (![GitHub Discussions](https://img.shields.io/github/discussions/ollama4j/ollama4j)) + + Contributions are most welcome! Whether it's reporting a bug, proposing an enhancement, or helping with code - any sort of contribution is much appreciated. +### References + +- [Ollama REST APIs](https://github.com/jmorganca/ollama/blob/main/docs/api.md) + ### Credits The nomenclature and the icon have been adopted from the incredible [Ollama](https://ollama.ai/) project. -### References +**Thanks to the amazing contributors** -- [Ollama REST APIs](https://github.com/jmorganca/ollama/blob/main/docs/api.md) +

+ + + +

+ +### Appreciate my work? + +

+ Buy Me A Coffee +

diff --git a/docs/blog/2023-12-22-release-post.md b/docs/blog/2023-12-22-release-post.md index 0a0b95d..aba2a53 100644 --- a/docs/blog/2023-12-22-release-post.md +++ b/docs/blog/2023-12-22-release-post.md @@ -11,7 +11,7 @@ Hey there, my fellow Java Developers! 🚀 I am glad to announce the release of Ollama4j, a library that unites Ollama (an LLM manager and runner) and your Java applications! 🌐🚀 -👉 GitHub Repository: Ollama4j on GitHub (https://github.com/amithkoujalgi/ollama4j) +👉 GitHub Repository: Ollama4j on GitHub (https://github.com/ollama4j/ollama4j) 🌟 Key Features: @@ -58,9 +58,9 @@ elevate your projects. I look forward to seeing the incredible applications/projects you'll build with Ollama4j! 🌟 -Find the full API spec here: https://amithkoujalgi.github.io/ollama4j/ +Find the full API spec here: https://ollama4j.github.io/ollama4j/ -Find the Javadoc here: https://amithkoujalgi.github.io/ollama4j/apidocs/ +Find the Javadoc here: https://ollama4j.github.io/ollama4j/apidocs/ Ollama4j Docs is powered by [Docusaurus](https://docusaurus.io). diff --git a/docs/docs/apis-extras/basic-auth.md b/docs/docs/apis-extras/basic-auth.md index 226a18f..15f681c 100644 --- a/docs/docs/apis-extras/basic-auth.md +++ b/docs/docs/apis-extras/basic-auth.md @@ -10,6 +10,8 @@ Ollama server would be setup behind a gateway/reverse proxy with basic auth. After configuring basic authentication, all subsequent requests will include the Basic Auth header. ```java +import io.github.ollama4j.OllamaAPI; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-extras/options-builder.md b/docs/docs/apis-extras/options-builder.md index 7fb7d68..10aeea5 100644 --- a/docs/docs/apis-extras/options-builder.md +++ b/docs/docs/apis-extras/options-builder.md @@ -31,13 +31,14 @@ Link to [source](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md Also, see how to set those Ollama parameters using the `OptionsBuilder` -from [javadoc](https://amithkoujalgi.github.io/ollama4j/apidocs/io/github/amithkoujalgi/ollama4j/core/utils/OptionsBuilder.html). +from [javadoc](https://ollama4j.github.io/ollama4j/apidocs/io/github/ollama4j/ollama4j/core/utils/OptionsBuilder.html). ## Build an empty `Options` object ```java -import io.github.amithkoujalgi.ollama4j.core.utils.Options; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.utils.Options; +import io.github.ollama4j.utils.OptionsBuilder; public class Main { @@ -55,8 +56,8 @@ public class Main { ## Build the `Options` object with values ```java -import io.github.amithkoujalgi.ollama4j.core.utils.Options; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; +import io.github.ollama4j.utils.Options; +import io.github.ollama4j.utils.OptionsBuilder; public class Main { diff --git a/docs/docs/apis-extras/ping.md b/docs/docs/apis-extras/ping.md index cc69f3d..2c9d8d3 100644 --- a/docs/docs/apis-extras/ping.md +++ b/docs/docs/apis-extras/ping.md @@ -7,6 +7,8 @@ sidebar_position: 3 This API lets you check the reachability of Ollama server. ```java +import io.github.ollama4j.OllamaAPI; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-extras/ps.md b/docs/docs/apis-extras/ps.md new file mode 100644 index 0000000..4f37e04 --- /dev/null +++ b/docs/docs/apis-extras/ps.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 4 +--- + +# PS + +This API provides a list of running models and details about each model currently loaded into memory. + +This API corresponds to the [PS](https://github.com/ollama/ollama/blob/main/docs/api.md#list-running-models) API. + +```java +package io.github.ollama4j.localtests; + +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.ps.ModelsProcessResponse; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + + OllamaAPI ollamaAPI = new OllamaAPI("http://localhost:11434"); + + ModelsProcessResponse response = ollamaAPI.ps(); + + System.out.println(response); + } +} +``` \ No newline at end of file diff --git a/docs/docs/apis-extras/request-timeout.md b/docs/docs/apis-extras/request-timeout.md index ff3f40f..f22971a 100644 --- a/docs/docs/apis-extras/request-timeout.md +++ b/docs/docs/apis-extras/request-timeout.md @@ -7,6 +7,8 @@ sidebar_position: 2 This API lets you set the request timeout for the Ollama client. ```java +import io.github.ollama4j.OllamaAPI; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-extras/verbosity.md b/docs/docs/apis-extras/verbosity.md index 35a150e..c8809c9 100644 --- a/docs/docs/apis-extras/verbosity.md +++ b/docs/docs/apis-extras/verbosity.md @@ -9,6 +9,8 @@ This API lets you set the verbosity of the Ollama client. ## Try asking a question about the model. ```java +import io.github.ollama4j.OllamaAPI; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-generate/chat.md b/docs/docs/apis-generate/chat.md index b4d51b1..9ed9e79 100644 --- a/docs/docs/apis-generate/chat.md +++ b/docs/docs/apis-generate/chat.md @@ -10,6 +10,13 @@ information using the history of already asked questions and the respective answ ## Create a new conversation and use chat history to augment follow up questions ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.chat.OllamaChatMessageRole; +import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; +import io.github.ollama4j.models.chat.OllamaChatRequest; +import io.github.ollama4j.models.chat.OllamaChatResult; +import io.github.ollama4j.types.OllamaModelType; + public class Main { public static void main(String[] args) { @@ -20,7 +27,7 @@ public class Main { OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(OllamaModelType.LLAMA2); // create first user question - OllamaChatRequestModel requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?") + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?") .build(); // start conversation with model @@ -75,9 +82,44 @@ You will get a response similar to: ] ``` +## Conversational loop + +```java +public class Main { + + public static void main(String[] args) { + + OllamaAPI ollamaAPI = new OllamaAPI(); + ollamaAPI.setRequestTimeoutSeconds(60); + + OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(""); + + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "").build(); + OllamaChatResult initialChatResult = ollamaAPI.chat(requestModel); + System.out.println(initialChatResult.getResponse()); + + List history = initialChatResult.getChatHistory(); + + while (true) { + OllamaChatResult chatResult = ollamaAPI.chat(builder.withMessages(history).withMessage(OllamaChatMessageRole.USER, " I am LLaMA, an AI assistant developed by Meta AI that can understand and respond to human input in a conversational -> manner. I am trained on a massive dataset of text from the internet and can generate human-like responses to a wide -> range of topics and questions. I can be used to create chatbots, virtual assistants, and other applications that -> require -> natural language understanding and generation capabilities. \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/docs/apis-generate/generate-embeddings.md b/docs/docs/apis-generate/generate-embeddings.md index 1da45e1..586b215 100644 --- a/docs/docs/apis-generate/generate-embeddings.md +++ b/docs/docs/apis-generate/generate-embeddings.md @@ -12,6 +12,10 @@ Parameters: - `prompt`: text to generate embeddings for ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.types.OllamaModelType; +import java.util.List; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-generate/generate-with-image-files.md b/docs/docs/apis-generate/generate-with-image-files.md index 37f4f03..b26f9ba 100644 --- a/docs/docs/apis-generate/generate-with-image-files.md +++ b/docs/docs/apis-generate/generate-with-image-files.md @@ -1,12 +1,12 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- # Generate - With Image Files This API lets you ask questions along with the image files to the LLMs. -These APIs correlate to -the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs. +This API corresponds to +the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) API. :::note @@ -22,6 +22,14 @@ If you have this image downloaded and you pass the path to the downloaded image ![Img](https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg) ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; + +import java.io.File; +import java.util.List; + public class Main { public static void main(String[] args) { @@ -32,7 +40,9 @@ public class Main { OllamaResult result = ollamaAPI.generateWithImageFiles(OllamaModelType.LLAVA, "What's in this image?", List.of( - new File("/path/to/image"))); + new File("/path/to/image")), + new OptionsBuilder().build() + ); System.out.println(result.getResponse()); } } diff --git a/docs/docs/apis-generate/generate-with-image-urls.md b/docs/docs/apis-generate/generate-with-image-urls.md index 19d6cf1..cf9e755 100644 --- a/docs/docs/apis-generate/generate-with-image-urls.md +++ b/docs/docs/apis-generate/generate-with-image-urls.md @@ -1,12 +1,12 @@ --- -sidebar_position: 4 +sidebar_position: 5 --- # Generate - With Image URLs This API lets you ask questions along with the image files to the LLMs. -These APIs correlate to -the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs. +This API corresponds to +the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) API. :::note @@ -22,6 +22,13 @@ Passing the link of this image the following code: ![Img](https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg) ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; + +import java.util.List; + public class Main { public static void main(String[] args) { @@ -32,7 +39,9 @@ public class Main { OllamaResult result = ollamaAPI.generateWithImageURLs(OllamaModelType.LLAVA, "What's in this image?", List.of( - "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg")); + "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"), + new OptionsBuilder().build() + ); System.out.println(result.getResponse()); } } diff --git a/docs/docs/apis-generate/generate-with-tools.md b/docs/docs/apis-generate/generate-with-tools.md new file mode 100644 index 0000000..3a40150 --- /dev/null +++ b/docs/docs/apis-generate/generate-with-tools.md @@ -0,0 +1,372 @@ +--- +sidebar_position: 3 +--- + +# Generate - With Tools + +This API lets you perform [function calling](https://docs.mistral.ai/capabilities/function_calling/) using LLMs in a +synchronous way. +This API corresponds to +the [generate](https://github.com/ollama/ollama/blob/main/docs/api.md#request-raw-mode) API with `raw` mode. + +:::note + +This is an only an experimental implementation and has a very basic design. + +Currently, built and tested for [Mistral's latest model](https://ollama.com/library/mistral) only. We could redesign +this +in the future if tooling is supported for more models with a generic interaction standard from Ollama. + +::: + +### Function Calling/Tools + +Assume you want to call a method in your code based on the response generated from the model. +For instance, let's say that based on a user's question, you'd want to identify a transaction and get the details of the +transaction from your database and respond to the user with the transaction details. + +You could do that with ease with the `function calling` capabilities of the models by registering your `tools`. + +### Create Functions + +We can create static functions as our tools. + +This function takes the arguments `location` and `fuelType` and performs an operation with these arguments and returns +fuel price value. + +```java +public static String getCurrentFuelPrice(Map arguments) { + String location = arguments.get("location").toString(); + String fuelType = arguments.get("fuelType").toString(); + return "Current price of " + fuelType + " in " + location + " is Rs.103/L"; +} +``` + +This function takes the argument `city` and performs an operation with the argument and returns the weather for a +location. + +```java +public static String getCurrentWeather(Map arguments) { + String location = arguments.get("city").toString(); + return "Currently " + location + "'s weather is nice."; +} +``` + +Another way to create our tools is by creating classes by extending `ToolFunction`. + +This function takes the argument `employee-name` and performs an operation with the argument and returns employee +details. + +```java +class DBQueryFunction implements ToolFunction { + @Override + public Object apply(Map arguments) { + // perform DB operations here + return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString()); + } +} +``` + +### Define Tool Specifications + +Lets define a sample tool specification called **Fuel Price Tool** for getting the current fuel price. + +- Specify the function `name`, `description`, and `required` properties (`location` and `fuelType`). +- Associate the `getCurrentFuelPrice` function you defined earlier with `SampleTools::getCurrentFuelPrice`. + +```java +Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder() + .functionName("current-fuel-price") + .functionDescription("Get current fuel price") + .properties( + new Tools.PropsBuilder() + .withProperty("location", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build()) + .withProperty("fuelType", Tools.PromptFuncDefinition.Property.builder().type("string").description("The fuel type.").enumValues(Arrays.asList("petrol", "diesel")).required(true).build()) + .build() + ) + .toolDefinition(SampleTools::getCurrentFuelPrice) + .build(); +``` + +Lets also define a sample tool specification called **Weather Tool** for getting the current weather. + +- Specify the function `name`, `description`, and `required` property (`city`). +- Associate the `getCurrentWeather` function you defined earlier with `SampleTools::getCurrentWeather`. + +```java +Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder() + .functionName("current-weather") + .functionDescription("Get current weather") + .properties( + new Tools.PropsBuilder() + .withProperty("city", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build()) + .build() + ) + .toolDefinition(SampleTools::getCurrentWeather) + .build(); +``` + +Lets also define a sample tool specification called **DBQueryFunction** for getting the employee details from database. + +- Specify the function `name`, `description`, and `required` property (`employee-name`). +- Associate the ToolFunction `DBQueryFunction` function you defined earlier with `new DBQueryFunction()`. + +```java +Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder() + .functionName("get-employee-details") + .functionDescription("Get employee details from the database") + .properties( + new Tools.PropsBuilder() + .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build()) + .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build()) + .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build()) + .build() + ) + .toolDefinition(new DBQueryFunction()) + .build(); +``` + +### Register the Tools + +Register the defined tools (`fuel price` and `weather`) with the OllamaAPI. + +```shell +ollamaAPI.registerTool(fuelPriceToolSpecification); +ollamaAPI.registerTool(weatherToolSpecification); +ollamaAPI.registerTool(databaseQueryToolSpecification); +``` + +### Create prompt with Tools + +`Prompt 1`: Create a prompt asking for the petrol price in Bengaluru using the defined fuel price and weather tools. + +```shell +String prompt1 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withPrompt("What is the petrol price in Bengaluru?") + .build(); +OllamaToolsResult toolsResult = ollamaAPI.generateWithTools(model, prompt1, new OptionsBuilder().build()); +for (OllamaToolsResult.ToolResult r : toolsResult.getToolResults()) { + System.out.printf("[Result of executing tool '%s']: %s%n", r.getFunctionName(), r.getResult().toString()); +} +``` + +Now, fire away your question to the model. + +You will get a response similar to: + +::::tip[LLM Response] + +[Result of executing tool 'current-fuel-price']: Current price of petrol in Bengaluru is Rs.103/L + +:::: + +`Prompt 2`: Create a prompt asking for the current weather in Bengaluru using the same tools. + +```shell +String prompt2 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withPrompt("What is the current weather in Bengaluru?") + .build(); +OllamaToolsResult toolsResult = ollamaAPI.generateWithTools(model, prompt2, new OptionsBuilder().build()); +for (OllamaToolsResult.ToolResult r : toolsResult.getToolResults()) { + System.out.printf("[Result of executing tool '%s']: %s%n", r.getFunctionName(), r.getResult().toString()); +} +``` + +Again, fire away your question to the model. + +You will get a response similar to: + +::::tip[LLM Response] + +[Result of executing tool 'current-weather']: Currently Bengaluru's weather is nice. + +:::: + +`Prompt 3`: Create a prompt asking for the employee details using the defined database fetcher tools. + +```shell +String prompt3 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withToolSpecification(databaseQueryToolSpecification) + .withPrompt("Give me the details of the employee named 'Rahul Kumar'?") + .build(); +OllamaToolsResult toolsResult = ollamaAPI.generateWithTools(model, prompt3, new OptionsBuilder().build()); +for (OllamaToolsResult.ToolResult r : toolsResult.getToolResults()) { + System.out.printf("[Result of executing tool '%s']: %s%n", r.getFunctionName(), r.getResult().toString()); +} +``` + +Again, fire away your question to the model. + +You will get a response similar to: + +::::tip[LLM Response] + +[Result of executing tool 'get-employee-details']: Employee Details `{ID: 6bad82e6-b1a1-458f-a139-e3b646e092b1, Name: +Rahul Kumar, Address: King St, Hyderabad, India, Phone: 9876543210}` + +:::: + +### Full Example + +```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.exceptions.ToolInvocationException; +import io.github.ollama4j.tools.OllamaToolsResult; +import io.github.ollama4j.tools.ToolFunction; +import io.github.ollama4j.tools.Tools; +import io.github.ollama4j.utils.OptionsBuilder; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.UUID; + +public class FunctionCallingWithMistralExample { + public static void main(String[] args) throws Exception { + String host = "http://localhost:11434/"; + OllamaAPI ollamaAPI = new OllamaAPI(host); + ollamaAPI.setRequestTimeoutSeconds(60); + + String model = "mistral"; + + Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder() + .functionName("current-fuel-price") + .functionDescription("Get current fuel price") + .properties( + new Tools.PropsBuilder() + .withProperty("location", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build()) + .withProperty("fuelType", Tools.PromptFuncDefinition.Property.builder().type("string").description("The fuel type.").enumValues(Arrays.asList("petrol", "diesel")).required(true).build()) + .build() + ) + .toolDefinition(SampleTools::getCurrentFuelPrice) + .build(); + + Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder() + .functionName("current-weather") + .functionDescription("Get current weather") + .properties( + new Tools.PropsBuilder() + .withProperty("city", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build()) + .build() + ) + .toolDefinition(SampleTools::getCurrentWeather) + .build(); + + Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder() + .functionName("get-employee-details") + .functionDescription("Get employee details from the database") + .properties( + new Tools.PropsBuilder() + .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build()) + .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build()) + .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build()) + .build() + ) + .toolDefinition(new DBQueryFunction()) + .build(); + + ollamaAPI.registerTool(fuelPriceToolSpecification); + ollamaAPI.registerTool(weatherToolSpecification); + ollamaAPI.registerTool(databaseQueryToolSpecification); + + String prompt1 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withPrompt("What is the petrol price in Bengaluru?") + .build(); + ask(ollamaAPI, model, prompt1); + + String prompt2 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withPrompt("What is the current weather in Bengaluru?") + .build(); + ask(ollamaAPI, model, prompt2); + + String prompt3 = new Tools.PromptBuilder() + .withToolSpecification(fuelPriceToolSpecification) + .withToolSpecification(weatherToolSpecification) + .withToolSpecification(databaseQueryToolSpecification) + .withPrompt("Give me the details of the employee named 'Rahul Kumar'?") + .build(); + ask(ollamaAPI, model, prompt3); + } + + public static void ask(OllamaAPI ollamaAPI, String model, String prompt) throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException { + OllamaToolsResult toolsResult = ollamaAPI.generateWithTools(model, prompt, new OptionsBuilder().build()); + for (OllamaToolsResult.ToolResult r : toolsResult.getToolResults()) { + System.out.printf("[Result of executing tool '%s']: %s%n", r.getFunctionName(), r.getResult().toString()); + } + } +} + + +class SampleTools { + public static String getCurrentFuelPrice(Map arguments) { + // Get details from fuel price API + String location = arguments.get("location").toString(); + String fuelType = arguments.get("fuelType").toString(); + return "Current price of " + fuelType + " in " + location + " is Rs.103/L"; + } + + public static String getCurrentWeather(Map arguments) { + // Get details from weather API + String location = arguments.get("city").toString(); + return "Currently " + location + "'s weather is nice."; + } +} + +class DBQueryFunction implements ToolFunction { + @Override + public Object apply(Map arguments) { + // perform DB operations here + return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString()); + } +} +``` + +Run this full example and you will get a response similar to: + +::::tip[LLM Response] + +[Result of executing tool 'current-fuel-price']: Current price of petrol in Bengaluru is Rs.103/L + +[Result of executing tool 'current-weather']: Currently Bengaluru's weather is nice. + +[Result of executing tool 'get-employee-details']: Employee Details `{ID: 6bad82e6-b1a1-458f-a139-e3b646e092b1, Name: +Rahul Kumar, Address: King St, Hyderabad, India, Phone: 9876543210}` + +:::: + +### Potential Improvements + +Instead of explicitly registering `ollamaAPI.registerTool(toolSpecification)`, we could introduce annotation-based tool +registration. For example: + +```java + +@ToolSpec(name = "current-fuel-price", desc = "Get current fuel price") +public String getCurrentFuelPrice(Map arguments) { + String location = arguments.get("location").toString(); + String fuelType = arguments.get("fuelType").toString(); + return "Current price of " + fuelType + " in " + location + " is Rs.103/L"; +} +``` + +Instead of passing a map of args `Map arguments` to the tool functions, we could support passing +specific args separately with their data types. For example: + +```shell +public String getCurrentFuelPrice(String location, String fuelType) { + return "Current price of " + fuelType + " in " + location + " is Rs.103/L"; +} +``` + +Updating async/chat APIs with support for tool-based generation. \ No newline at end of file diff --git a/docs/docs/apis-generate/generate.md b/docs/docs/apis-generate/generate.md index 6d1cf66..1cd6a47 100644 --- a/docs/docs/apis-generate/generate.md +++ b/docs/docs/apis-generate/generate.md @@ -5,17 +5,22 @@ sidebar_position: 1 # Generate - Sync This API lets you ask questions to the LLMs in a synchronous way. -These APIs correlate to -the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs. +This API corresponds to +the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) API. Use the `OptionBuilder` to build the `Options` object with [extra parameters](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values). Refer -to [this](/docs/apis-extras/options-builder). +to [this](/apis-extras/options-builder). ## Try asking a question about the model. ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; + public class Main { public static void main(String[] args) { @@ -44,6 +49,11 @@ You will get a response similar to: ## Try asking a question, receiving the answer streamed ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.models.generate.OllamaStreamHandler; +import io.github.ollama4j.utils.OptionsBuilder; + public class Main { public static void main(String[] args) { @@ -53,25 +63,26 @@ public class Main { OllamaAPI ollamaAPI = new OllamaAPI(host); // define a stream handler (Consumer) OllamaStreamHandler streamHandler = (s) -> { - System.out.println(s); + System.out.println(s); }; // Should be called using seperate thread to gain non blocking streaming effect. OllamaResult result = ollamaAPI.generate(config.getModel(), - "What is the capital of France? And what's France's connection with Mona Lisa?", - new OptionsBuilder().build(), streamHandler); - - System.out.println("Full response: " +result.getResponse()); + "What is the capital of France? And what's France's connection with Mona Lisa?", + new OptionsBuilder().build(), streamHandler); + + System.out.println("Full response: " + result.getResponse()); } } ``` + You will get a response similar to: > The > The capital > The capital of > The capital of France -> The capital of France is +> The capital of France is > The capital of France is Paris > The capital of France is Paris. > Full response: The capital of France is Paris. @@ -79,6 +90,11 @@ You will get a response similar to: ## Try asking a question from general topics. ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; + public class Main { public static void main(String[] args) { @@ -122,6 +138,12 @@ You'd then get a response from the model: ## Try asking for a Database query for your data schema. ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; +import io.github.ollama4j.utils.SamplePrompts; + public class Main { public static void main(String[] args) { @@ -140,7 +162,7 @@ public class Main { ``` _Note: Here I've used -a [sample prompt](https://github.com/amithkoujalgi/ollama4j/blob/main/src/main/resources/sample-db-prompt-template.txt) +a [sample prompt](https://github.com/ollama4j/ollama4j/blob/main/src/main/resources/sample-db-prompt-template.txt) containing a database schema from within this library for demonstration purposes._ You'd then get a response from the model: diff --git a/docs/docs/apis-generate/prompt-builder.md b/docs/docs/apis-generate/prompt-builder.md index a798808..b947dca 100644 --- a/docs/docs/apis-generate/prompt-builder.md +++ b/docs/docs/apis-generate/prompt-builder.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 --- # Prompt Builder @@ -8,13 +8,13 @@ This is designed for prompt engineering. It allows you to easily build the promp inferences. ```java +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; +import io.github.ollama4j.utils.PromptBuilder; -import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.types.OllamaModelType; -import io.github.amithkoujalgi.ollama4j.core.utils.PromptBuilder; - -public class AskPhi { +public class Main { public static void main(String[] args) throws Exception { String host = "http://localhost:11434/"; @@ -42,7 +42,8 @@ public class AskPhi { .addSeparator() .add("How do I read a file in Go and print its contents to stdout?"); - OllamaResult response = ollamaAPI.generate(model, promptBuilder.build(), new OptionsBuilder().build()); + boolean raw = false; + OllamaResult response = ollamaAPI.generate(model, promptBuilder.build(), raw, new OptionsBuilder().build()); System.out.println(response.getResponse()); } } diff --git a/docs/docs/apis-model-management/create-model.md b/docs/docs/apis-model-management/create-model.md index 437e291..866cf73 100644 --- a/docs/docs/apis-model-management/create-model.md +++ b/docs/docs/apis-model-management/create-model.md @@ -9,6 +9,8 @@ This API lets you create a custom model on the Ollama server. ### Create a model from an existing Modelfile in the Ollama server ```java title="CreateModel.java" +import io.github.ollama4j.OllamaAPI; + public class CreateModel { public static void main(String[] args) { diff --git a/docs/docs/apis-model-management/delete-model.md b/docs/docs/apis-model-management/delete-model.md index 16bca70..edb8197 100644 --- a/docs/docs/apis-model-management/delete-model.md +++ b/docs/docs/apis-model-management/delete-model.md @@ -7,6 +7,8 @@ sidebar_position: 5 This API lets you create a delete a model from the Ollama server. ```java title="DeleteModel.java" +import io.github.ollama4j.OllamaAPI; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-model-management/get-model-details.md b/docs/docs/apis-model-management/get-model-details.md index 184a55a..0162e29 100644 --- a/docs/docs/apis-model-management/get-model-details.md +++ b/docs/docs/apis-model-management/get-model-details.md @@ -7,6 +7,10 @@ sidebar_position: 3 This API lets you get the details of a model on the Ollama server. ```java title="GetModelDetails.java" +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.ModelDetail; +import io.github.ollama4j.types.OllamaModelType; + public class Main { public static void main(String[] args) { diff --git a/docs/docs/apis-model-management/list-models.md b/docs/docs/apis-model-management/list-models.md index 0840470..cb594ef 100644 --- a/docs/docs/apis-model-management/list-models.md +++ b/docs/docs/apis-model-management/list-models.md @@ -7,6 +7,11 @@ sidebar_position: 1 This API lets you list available models on the Ollama server. ```java title="ListModels.java" +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.Model; + +import java.util.List; + public class ListModels { public static void main(String[] args) { diff --git a/docs/docs/apis-model-management/pull-model.md b/docs/docs/apis-model-management/pull-model.md index 1e248ef..bfe2e26 100644 --- a/docs/docs/apis-model-management/pull-model.md +++ b/docs/docs/apis-model-management/pull-model.md @@ -7,10 +7,13 @@ sidebar_position: 2 This API lets you pull a model on the Ollama server. ```java title="PullModel.java" +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.types.OllamaModelType; + public class Main { public static void main(String[] args) { - + String host = "http://localhost:11434/"; OllamaAPI ollamaAPI = new OllamaAPI(host); diff --git a/docs/docs/intro.md b/docs/docs/intro.md index b75cce6..bd8284e 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -78,13 +78,13 @@ Add the dependency to your project's `pom.xml`. ```xml - io.github.amithkoujalgi + io.github.ollama4j ollama4j - 1.0.27 + 1.0.78 ``` -Find the latest version of the library [here](https://central.sonatype.com/artifact/io.github.amithkoujalgi/ollama4j). +Find the latest version of the library [here](https://central.sonatype.com/artifact/io.github.ollama4j/ollama4j). You might want to include an implementation of [SL4J](https://www.slf4j.org/) logger in your `pom.xml` file. For example, @@ -116,6 +116,26 @@ or use other suitable implementations. Create a new Java class in your project and add this code. ```java +import io.github.ollama4j.OllamaAPI; + +public class OllamaAPITest { + + public static void main(String[] args) { + OllamaAPI ollamaAPI = new OllamaAPI(); + + boolean isOllamaServerReachable = ollamaAPI.ping(); + + System.out.println("Is Ollama server running: " + isOllamaServerReachable); + } +} +``` +This uses the default Ollama host as `http://localhost:11434`. + +Specify a different Ollama host that you want to connect to. + +```java +import io.github.ollama4j.OllamaAPI; + public class OllamaAPITest { public static void main(String[] args) { @@ -127,7 +147,7 @@ public class OllamaAPITest { boolean isOllamaServerReachable = ollamaAPI.ping(); - System.out.println("Is Ollama server alive: " + isOllamaServerReachable); + System.out.println("Is Ollama server running: " + isOllamaServerReachable); } } ``` diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index eac9357..f9366c6 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -20,7 +20,7 @@ const config = { // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'amithkoujalgi', // Usually your GitHub org/user name. + organizationName: 'ollama4j', // Usually your GitHub org/user name. projectName: 'ollama4j', // Usually your repo name. onBrokenLinks: 'throw', @@ -40,22 +40,28 @@ const config = { /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { + path: 'docs', + routeBasePath: '', // change this to any URL route you'd want. For example: `home` - if you want /home/intro. sidebarPath: './sidebars.js', // Please change this to your repo. // Remove this to remove the "edit this page" links. editUrl: - 'https://github.com/amithkoujalgi/ollama4j/blob/main/docs', + 'https://github.com/ollama4j/ollama4j/blob/main/docs', }, blog: { showReadingTime: true, // Please change this to your repo. // Remove this to remove the "edit this page" links. editUrl: - 'https://github.com/amithkoujalgi/ollama4j/blob/main/docs', + 'https://github.com/ollama4j/ollama4j/blob/main/docs', }, theme: { customCss: './src/css/custom.css', }, + gtag: { + trackingID: 'G-G7FLH6FNDC', + anonymizeIP: false, + }, }), ], ], @@ -78,11 +84,11 @@ const config = { position: 'left', label: 'Docs', }, - {to: 'https://amithkoujalgi.github.io/ollama4j/apidocs/', label: 'Javadoc', position: 'left'}, - {to: 'https://amithkoujalgi.github.io/ollama4j/doxygen/html/', label: 'Doxygen', position: 'left'}, + {to: 'https://ollama4j.github.io/ollama4j/apidocs/', label: 'Javadoc', position: 'left'}, + {to: 'https://ollama4j.github.io/ollama4j/doxygen/html/', label: 'Doxygen', position: 'left'}, {to: '/blog', label: 'Blog', position: 'left'}, { - href: 'https://github.com/amithkoujalgi/ollama4j', + href: 'https://github.com/ollama4j/ollama4j', label: 'GitHub', position: 'right', }, @@ -96,7 +102,7 @@ const config = { items: [ { label: 'Tutorial', - to: '/docs/intro', + to: '/intro', }, ], }, @@ -122,7 +128,7 @@ const config = { }, { label: 'GitHub', - href: 'https://github.com/amithkoujalgi/ollama4j', + href: 'https://github.com/ollama4j/ollama4j', }, ], }, diff --git a/docs/package-lock.json b/docs/package-lock.json index 6fa0119..7b3b955 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,9 +8,10 @@ "name": "ollama-4-j", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/preset-classic": "3.0.1", - "@docusaurus/theme-mermaid": "^3.0.1", + "@docusaurus/core": "^3.4.0", + "@docusaurus/plugin-google-gtag": "^3.4.0", + "@docusaurus/preset-classic": "^3.4.0", + "@docusaurus/theme-mermaid": "^3.4.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -18,8 +19,8 @@ "react-dom": "^18.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/types": "3.0.1" + "@docusaurus/module-type-aliases": "^3.4.0", + "@docusaurus/types": "^3.4.0" }, "engines": { "node": ">=18.0" @@ -67,74 +68,74 @@ } }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.0.tgz", - "integrity": "sha512-uZ1uZMLDZb4qODLfTSNHxSi4fH9RdrQf7DXEzW01dS8XK7QFtFh29N5NGKa9S+Yudf1vUMIF+/RiL4i/J0pWlQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", "dependencies": { - "@algolia/cache-common": "4.22.0" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.0.tgz", - "integrity": "sha512-TPwUMlIGPN16eW67qamNQUmxNiGHg/WBqWcrOoCddhqNTqGDPVqmgfaM85LPbt24t3r1z0zEz/tdsmuq3Q6oaA==" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" }, "node_modules/@algolia/cache-in-memory": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.0.tgz", - "integrity": "sha512-kf4Cio9NpPjzp1+uXQgL4jsMDeck7MP89BYThSvXSjf2A6qV/0KeqQf90TL2ECS02ovLOBXkk98P7qVarM+zGA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", "dependencies": { - "@algolia/cache-common": "4.22.0" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/client-account": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.0.tgz", - "integrity": "sha512-Bjb5UXpWmJT+yGWiqAJL0prkENyEZTBzdC+N1vBuHjwIJcjLMjPB6j1hNBRbT12Lmwi55uzqeMIKS69w+0aPzA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", "dependencies": { - "@algolia/client-common": "4.22.0", - "@algolia/client-search": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.0.tgz", - "integrity": "sha512-os2K+kHUcwwRa4ArFl5p/3YbF9lN3TLOPkbXXXxOvDpqFh62n9IRZuzfxpHxMPKAQS3Et1s0BkKavnNP02E9Hg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", "dependencies": { - "@algolia/client-common": "4.22.0", - "@algolia/client-search": "4.22.0", - "@algolia/requester-common": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-common": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.0.tgz", - "integrity": "sha512-BlbkF4qXVWuwTmYxVWvqtatCR3lzXwxx628p1wj1Q7QP2+LsTmGt1DiUYRuy9jG7iMsnlExby6kRMOOlbhv2Ag==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", "dependencies": { - "@algolia/requester-common": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.0.tgz", - "integrity": "sha512-pEOftCxeBdG5pL97WngOBi9w5Vxr5KCV2j2D+xMVZH8MuU/JX7CglDSDDb0ffQWYqcUN+40Ry+xtXEYaGXTGow==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", "dependencies": { - "@algolia/client-common": "4.22.0", - "@algolia/requester-common": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-search": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.0.tgz", - "integrity": "sha512-bn4qQiIdRPBGCwsNuuqB8rdHhGKKWIij9OqidM1UkQxnSG8yzxHdb7CujM30pvp5EnV7jTqDZRbxacbjYVW20Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", "dependencies": { - "@algolia/client-common": "4.22.0", - "@algolia/requester-common": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/events": { @@ -143,47 +144,65 @@ "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" }, "node_modules/@algolia/logger-common": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.0.tgz", - "integrity": "sha512-HMUQTID0ucxNCXs5d1eBJ5q/HuKg8rFVE/vOiLaM4Abfeq1YnTtGV3+rFEhOPWhRQxNDd+YHa4q864IMc0zHpQ==" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" }, "node_modules/@algolia/logger-console": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.0.tgz", - "integrity": "sha512-7JKb6hgcY64H7CRm3u6DRAiiEVXMvCJV5gRE672QFOUgDxo4aiDpfU61g6Uzy8NKjlEzHMmgG4e2fklELmPXhQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", "dependencies": { - "@algolia/logger-common": "4.22.0" + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.0.tgz", - "integrity": "sha512-BHfv1h7P9/SyvcDJDaRuIwDu2yrDLlXlYmjvaLZTtPw6Ok/ZVhBR55JqW832XN/Fsl6k3LjdkYHHR7xnsa5Wvg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", "dependencies": { - "@algolia/requester-common": "4.22.0" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/requester-common": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.0.tgz", - "integrity": "sha512-Y9cEH/cKjIIZgzvI1aI0ARdtR/xRrOR13g5psCxkdhpgRN0Vcorx+zePhmAa4jdQNqexpxtkUdcKYugBzMZJgQ==" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" }, "node_modules/@algolia/requester-node-http": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.0.tgz", - "integrity": "sha512-8xHoGpxVhz3u2MYIieHIB6MsnX+vfd5PS4REgglejJ6lPigftRhTdBCToe6zbwq4p0anZXjjPDvNWMlgK2+xYA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", "dependencies": { - "@algolia/requester-common": "4.22.0" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/transporter": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.0.tgz", - "integrity": "sha512-ieO1k8x2o77GNvOoC+vAkFKppydQSVfbjM3YrSjLmgywiBejPTvU1R1nEvG59JIIUvtSLrZsLGPkd6vL14zopA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", "dependencies": { - "@algolia/cache-common": "4.22.0", - "@algolia/logger-common": "4.22.0", - "@algolia/requester-common": "4.22.0" + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" } }, "node_modules/@ampproject/remapping": { @@ -530,9 +549,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "engines": { "node": ">=6.9.0" } @@ -1608,11 +1627,11 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", - "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", + "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2133,18 +2152,18 @@ } }, "node_modules/@docsearch/css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==" + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz", + "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==" }, "node_modules/@docsearch/react": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz", + "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==", "dependencies": { "@algolia/autocomplete-core": "1.9.3", "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.5.2", + "@docsearch/css": "3.6.0", "algoliasearch": "^4.19.1" }, "peerDependencies": { @@ -2169,9 +2188,9 @@ } }, "node_modules/@docusaurus/core": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.0.1.tgz", - "integrity": "sha512-CXrLpOnW+dJdSv8M5FAJ3JBwXtL6mhUWxFA8aS0ozK6jBG/wgxERk5uvH28fCeFxOGbAT9v1e9dOMo1X2IEVhQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.4.0.tgz", + "integrity": "sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==", "dependencies": { "@babel/core": "^7.23.3", "@babel/generator": "^7.23.3", @@ -2183,15 +2202,12 @@ "@babel/runtime": "^7.22.6", "@babel/runtime-corejs3": "^7.22.6", "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.5.1", + "@docusaurus/cssnano-preset": "3.4.0", + "@docusaurus/logger": "3.4.0", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "autoprefixer": "^10.4.14", "babel-loader": "^9.1.3", "babel-plugin-dynamic-import-node": "^2.3.3", @@ -2205,12 +2221,13 @@ "copy-webpack-plugin": "^11.0.0", "core-js": "^3.31.1", "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^4.2.2", - "cssnano": "^5.1.15", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", "del": "^6.1.1", "detect-port": "^1.5.1", "escape-html": "^1.0.3", "eta": "^2.2.0", + "eval": "^0.1.8", "file-loader": "^6.2.0", "fs-extra": "^11.1.1", "html-minifier-terser": "^7.2.0", @@ -2219,12 +2236,13 @@ "leven": "^3.1.0", "lodash": "^4.17.21", "mini-css-extract-plugin": "^2.7.6", + "p-map": "^4.0.0", "postcss": "^8.4.26", "postcss-loader": "^7.3.3", "prompts": "^2.4.2", "react-dev-utils": "^12.0.1", "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", "react-loadable-ssr-addon-v5-slorber": "^1.0.1", "react-router": "^5.3.4", "react-router-config": "^5.1.1", @@ -2255,13 +2273,13 @@ } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.0.1.tgz", - "integrity": "sha512-wjuXzkHMW+ig4BD6Ya1Yevx9UJadO4smNZCEljqBoQfIQrQskTswBs7lZ8InHP7mCt273a/y/rm36EZhqJhknQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.4.0.tgz", + "integrity": "sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==", "dependencies": { - "cssnano-preset-advanced": "^5.3.10", - "postcss": "^8.4.26", - "postcss-sort-media-queries": "^4.4.1", + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", "tslib": "^2.6.0" }, "engines": { @@ -2269,9 +2287,9 @@ } }, "node_modules/@docusaurus/logger": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.0.1.tgz", - "integrity": "sha512-I5L6Nk8OJzkVA91O2uftmo71LBSxe1vmOn9AMR6JRCzYeEBrqneWMH02AqMvjJ2NpMiviO+t0CyPjyYV7nxCWQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.4.0.tgz", + "integrity": "sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==", "dependencies": { "chalk": "^4.1.2", "tslib": "^2.6.0" @@ -2281,15 +2299,13 @@ } }, "node_modules/@docusaurus/mdx-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.0.1.tgz", - "integrity": "sha512-ldnTmvnvlrONUq45oKESrpy+lXtbnTcTsFkOTIDswe5xx5iWJjt6eSa0f99ZaWlnm24mlojcIGoUWNCS53qVlQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.4.0.tgz", + "integrity": "sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==", "dependencies": { - "@babel/parser": "^7.22.7", - "@babel/traverse": "^7.22.8", - "@docusaurus/logger": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/logger": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -2321,18 +2337,17 @@ } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.0.1.tgz", - "integrity": "sha512-DEHpeqUDsLynl3AhQQiO7AbC7/z/lBra34jTcdYuvp9eGm01pfH1wTVq8YqWZq6Jyx0BgcVl/VJqtE9StRd9Ag==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", + "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", "dependencies": { - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "3.0.1", + "@docusaurus/types": "3.4.0", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", "@types/react-router-dom": "*", "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2" + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" }, "peerDependencies": { "react": "*", @@ -2340,17 +2355,17 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.0.1.tgz", - "integrity": "sha512-cLOvtvAyaMQFLI8vm4j26svg3ktxMPSXpuUJ7EERKoGbfpJSsgtowNHcRsaBVmfuCsRSk1HZ/yHBsUkTmHFEsg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.4.0.tgz", + "integrity": "sha512-vv6ZAj78ibR5Jh7XBUT4ndIjmlAxkijM3Sx5MAAzC1gyv0vupDQNhzuFg1USQmQVj3P5I6bquk12etPV3LJ+Xw==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/logger": "3.4.0", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", @@ -2371,17 +2386,18 @@ } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.0.1.tgz", - "integrity": "sha512-dRfAOA5Ivo+sdzzJGXEu33yAtvGg8dlZkvt/NEJ7nwi1F2j4LEdsxtfX2GKeETB2fP6XoGNSQnFXqa2NYGrHFg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.4.0.tgz", + "integrity": "sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/logger": "3.4.0", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/module-type-aliases": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", @@ -2400,15 +2416,15 @@ } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.0.1.tgz", - "integrity": "sha512-oP7PoYizKAXyEttcvVzfX3OoBIXEmXTMzCdfmC4oSwjG4SPcJsRge3mmI6O8jcZBgUPjIzXD21bVGWEE1iu8gg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.4.0.tgz", + "integrity": "sha512-h2+VN/0JjpR8fIkDEAoadNjfR3oLzB+v1qSXbIAKjQ46JAHx3X22n9nqS+BWSQnTnp1AjkjSvZyJMekmcwxzxg==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" @@ -2422,13 +2438,13 @@ } }, "node_modules/@docusaurus/plugin-debug": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.0.1.tgz", - "integrity": "sha512-09dxZMdATky4qdsZGzhzlUvvC+ilQ2hKbYF+wez+cM2mGo4qHbv8+qKXqxq0CQZyimwlAOWQLoSozIXU0g0i7g==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.4.0.tgz", + "integrity": "sha512-uV7FDUNXGyDSD3PwUaf5YijX91T5/H9SX4ErEcshzwgzWwBtK37nUWPU3ZLJfeTavX3fycTOqk9TglpOLaWkCg==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", "fs-extra": "^11.1.1", "react-json-view-lite": "^1.2.0", "tslib": "^2.6.0" @@ -2442,13 +2458,13 @@ } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.0.1.tgz", - "integrity": "sha512-jwseSz1E+g9rXQwDdr0ZdYNjn8leZBnKPjjQhMBEiwDoenL3JYFcNW0+p0sWoVF/f2z5t7HkKA+cYObrUh18gg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.4.0.tgz", + "integrity": "sha512-mCArluxEGi3cmYHqsgpGGt3IyLCrFBxPsxNZ56Mpur0xSlInnIHoeLDH7FvVVcPJRPSQ9/MfRqLsainRw+BojA==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "tslib": "^2.6.0" }, "engines": { @@ -2460,13 +2476,13 @@ } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.0.1.tgz", - "integrity": "sha512-UFTDvXniAWrajsulKUJ1DB6qplui1BlKLQZjX4F7qS/qfJ+qkKqSkhJ/F4VuGQ2JYeZstYb+KaUzUzvaPK1aRQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.4.0.tgz", + "integrity": "sha512-Dsgg6PLAqzZw5wZ4QjUYc8Z2KqJqXxHxq3vIoyoBWiLEEfigIs7wHR+oiWUQy3Zk9MIk6JTYj7tMoQU0Jm3nqA==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "@types/gtag.js": "^0.0.12", "tslib": "^2.6.0" }, @@ -2479,13 +2495,13 @@ } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.0.1.tgz", - "integrity": "sha512-IPFvuz83aFuheZcWpTlAdiiX1RqWIHM+OH8wS66JgwAKOiQMR3+nLywGjkLV4bp52x7nCnwhNk1rE85Cpy/CIw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.4.0.tgz", + "integrity": "sha512-O9tX1BTwxIhgXpOLpFDueYA9DWk69WCbDRrjYoMQtFHSkTyE7RhNgyjSPREUWJb9i+YUg3OrsvrBYRl64FCPCQ==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "tslib": "^2.6.0" }, "engines": { @@ -2497,16 +2513,16 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.0.1.tgz", - "integrity": "sha512-xARiWnjtVvoEniZudlCq5T9ifnhCu/GAZ5nA7XgyLfPcNpHQa241HZdsTlLtVcecEVVdllevBKOp7qknBBaMGw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.4.0.tgz", + "integrity": "sha512-+0VDvx9SmNrFNgwPoeoCha+tRoAjopwT0+pYO1xAbyLcewXSemq+eLxEa46Q1/aoOaJQ0qqHELuQM7iS2gp33Q==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/logger": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "fs-extra": "^11.1.1", "sitemap": "^7.1.1", "tslib": "^2.6.0" @@ -2520,23 +2536,23 @@ } }, "node_modules/@docusaurus/preset-classic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.0.1.tgz", - "integrity": "sha512-il9m9xZKKjoXn6h0cRcdnt6wce0Pv1y5t4xk2Wx7zBGhKG1idu4IFHtikHlD0QPuZ9fizpXspXcTzjL5FXc1Gw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.4.0.tgz", + "integrity": "sha512-Ohj6KB7siKqZaQhNJVMBBUzT3Nnp6eTKqO+FXO3qu/n1hJl3YLwVKTWBg28LF7MWrKu46UuYavwMRxud0VyqHg==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/plugin-content-blog": "3.0.1", - "@docusaurus/plugin-content-docs": "3.0.1", - "@docusaurus/plugin-content-pages": "3.0.1", - "@docusaurus/plugin-debug": "3.0.1", - "@docusaurus/plugin-google-analytics": "3.0.1", - "@docusaurus/plugin-google-gtag": "3.0.1", - "@docusaurus/plugin-google-tag-manager": "3.0.1", - "@docusaurus/plugin-sitemap": "3.0.1", - "@docusaurus/theme-classic": "3.0.1", - "@docusaurus/theme-common": "3.0.1", - "@docusaurus/theme-search-algolia": "3.0.1", - "@docusaurus/types": "3.0.1" + "@docusaurus/core": "3.4.0", + "@docusaurus/plugin-content-blog": "3.4.0", + "@docusaurus/plugin-content-docs": "3.4.0", + "@docusaurus/plugin-content-pages": "3.4.0", + "@docusaurus/plugin-debug": "3.4.0", + "@docusaurus/plugin-google-analytics": "3.4.0", + "@docusaurus/plugin-google-gtag": "3.4.0", + "@docusaurus/plugin-google-tag-manager": "3.4.0", + "@docusaurus/plugin-sitemap": "3.4.0", + "@docusaurus/theme-classic": "3.4.0", + "@docusaurus/theme-common": "3.4.0", + "@docusaurus/theme-search-algolia": "3.4.0", + "@docusaurus/types": "3.4.0" }, "engines": { "node": ">=18.0" @@ -2546,35 +2562,23 @@ "react-dom": "^18.0.0" } }, - "node_modules/@docusaurus/react-loadable": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": "*" - } - }, "node_modules/@docusaurus/theme-classic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.0.1.tgz", - "integrity": "sha512-XD1FRXaJiDlmYaiHHdm27PNhhPboUah9rqIH0lMpBt5kYtsGjJzhqa27KuZvHLzOP2OEpqd2+GZ5b6YPq7Q05Q==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.4.0.tgz", + "integrity": "sha512-0IPtmxsBYv2adr1GnZRdMkEQt1YW6tpzrUPj02YxNpvJ5+ju4E13J5tB4nfdaen/tfR1hmpSPlTFPvTf4kwy8Q==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/plugin-content-blog": "3.0.1", - "@docusaurus/plugin-content-docs": "3.0.1", - "@docusaurus/plugin-content-pages": "3.0.1", - "@docusaurus/theme-common": "3.0.1", - "@docusaurus/theme-translations": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/module-type-aliases": "3.4.0", + "@docusaurus/plugin-content-blog": "3.4.0", + "@docusaurus/plugin-content-docs": "3.4.0", + "@docusaurus/plugin-content-pages": "3.4.0", + "@docusaurus/theme-common": "3.4.0", + "@docusaurus/theme-translations": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "copy-text-to-clipboard": "^3.2.0", @@ -2598,17 +2602,17 @@ } }, "node_modules/@docusaurus/theme-common": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.0.1.tgz", - "integrity": "sha512-cr9TOWXuIOL0PUfuXv6L5lPlTgaphKP+22NdVBOYah5jSq5XAAulJTjfe+IfLsEG4L7lJttLbhW7LXDFSAI7Ag==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.4.0.tgz", + "integrity": "sha512-0A27alXuv7ZdCg28oPE8nH/Iz73/IUejVaCazqu9elS4ypjiLhK3KfzdSQBnL/g7YfHSlymZKdiOHEo8fJ0qMA==", "dependencies": { - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/plugin-content-blog": "3.0.1", - "@docusaurus/plugin-content-docs": "3.0.1", - "@docusaurus/plugin-content-pages": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", + "@docusaurus/mdx-loader": "3.4.0", + "@docusaurus/module-type-aliases": "3.4.0", + "@docusaurus/plugin-content-blog": "3.4.0", + "@docusaurus/plugin-content-docs": "3.4.0", + "@docusaurus/plugin-content-pages": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2627,15 +2631,15 @@ } }, "node_modules/@docusaurus/theme-mermaid": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.0.1.tgz", - "integrity": "sha512-jquSDnZfazABnC5i+02GzRIvufXKruKgvbYkQjKbI7/LWo0XvBs0uKAcCDGgHhth0t/ON5+Sn27joRfpeSk3Lw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.4.0.tgz", + "integrity": "sha512-3w5QW0HEZ2O6x2w6lU3ZvOe1gNXP2HIoKDMJBil1VmLBc9PmpAG17VmfhI/p3L2etNmOiVs5GgniUqvn8AFEGQ==", "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/theme-common": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/module-type-aliases": "3.4.0", + "@docusaurus/theme-common": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "mermaid": "^10.4.0", "tslib": "^2.6.0" }, @@ -2648,18 +2652,18 @@ } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.0.1.tgz", - "integrity": "sha512-DDiPc0/xmKSEdwFkXNf1/vH1SzJPzuJBar8kMcBbDAZk/SAmo/4lf6GU2drou4Ae60lN2waix+jYWTWcJRahSA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.4.0.tgz", + "integrity": "sha512-aiHFx7OCw4Wck1z6IoShVdUWIjntC8FHCw9c5dR8r3q4Ynh+zkS8y2eFFunN/DL6RXPzpnvKCg3vhLQYJDmT9Q==", "dependencies": { "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/plugin-content-docs": "3.0.1", - "@docusaurus/theme-common": "3.0.1", - "@docusaurus/theme-translations": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.4.0", + "@docusaurus/logger": "3.4.0", + "@docusaurus/plugin-content-docs": "3.4.0", + "@docusaurus/theme-common": "3.4.0", + "@docusaurus/theme-translations": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", "algoliasearch": "^4.18.0", "algoliasearch-helper": "^3.13.3", "clsx": "^2.0.0", @@ -2678,9 +2682,9 @@ } }, "node_modules/@docusaurus/theme-translations": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.0.1.tgz", - "integrity": "sha512-6UrbpzCTN6NIJnAtZ6Ne9492vmPVX+7Fsz4kmp+yor3KQwA1+MCzQP7ItDNkP38UmVLnvB/cYk/IvehCUqS3dg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.4.0.tgz", + "integrity": "sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==", "dependencies": { "fs-extra": "^11.1.1", "tslib": "^2.6.0" @@ -2690,10 +2694,11 @@ } }, "node_modules/@docusaurus/types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.0.1.tgz", - "integrity": "sha512-plyX2iU1tcUsF46uQ01pAd4JhexR7n0iiQ5MSnBFX6M6NSJgDYdru/i1/YNPKOnQHBoXGLHv0dNT6OAlDWNjrg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", + "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", "dependencies": { + "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", "@types/react": "*", "commander": "^5.1.0", @@ -2709,12 +2714,13 @@ } }, "node_modules/@docusaurus/utils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.0.1.tgz", - "integrity": "sha512-TwZ33Am0q4IIbvjhUOs+zpjtD/mXNmLmEgeTGuRq01QzulLHuPhaBTTAC/DHu6kFx3wDgmgpAlaRuCHfTcXv8g==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.4.0.tgz", + "integrity": "sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==", "dependencies": { - "@docusaurus/logger": "3.0.1", - "@svgr/webpack": "^6.5.1", + "@docusaurus/logger": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "@svgr/webpack": "^8.1.0", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", "fs-extra": "^11.1.1", @@ -2725,10 +2731,12 @@ "js-yaml": "^4.1.0", "lodash": "^4.17.21", "micromatch": "^4.0.5", + "prompts": "^2.4.2", "resolve-pathname": "^3.0.0", "shelljs": "^0.8.5", "tslib": "^2.6.0", "url-loader": "^4.1.1", + "utility-types": "^3.10.0", "webpack": "^5.88.1" }, "engines": { @@ -2744,9 +2752,9 @@ } }, "node_modules/@docusaurus/utils-common": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.0.1.tgz", - "integrity": "sha512-W0AxD6w6T8g6bNro8nBRWf7PeZ/nn7geEWM335qHU2DDDjHuV4UZjgUGP1AQsdcSikPrlIqTJJbKzer1lRSlIg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.4.0.tgz", + "integrity": "sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==", "dependencies": { "tslib": "^2.6.0" }, @@ -2763,14 +2771,17 @@ } }, "node_modules/@docusaurus/utils-validation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.0.1.tgz", - "integrity": "sha512-ujTnqSfyGQ7/4iZdB4RRuHKY/Nwm58IIb+41s5tCXOv/MBU2wGAjOHq3U+AEyJ8aKQcHbxvTKJaRchNHYUVUQg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.4.0.tgz", + "integrity": "sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==", "dependencies": { - "@docusaurus/logger": "3.0.1", - "@docusaurus/utils": "3.0.1", + "@docusaurus/logger": "3.4.0", + "@docusaurus/utils": "3.4.0", + "@docusaurus/utils-common": "3.4.0", + "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", + "lodash": "^4.17.21", "tslib": "^2.6.0" }, "engines": { @@ -2875,9 +2886,9 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mdx-js/mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", - "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", + "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -2999,9 +3010,9 @@ "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==" }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3042,25 +3053,12 @@ "micromark-util-symbol": "^1.0.1" } }, - "node_modules/@slorber/static-site-generator-webpack-plugin": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", - "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", - "dependencies": { - "eval": "^0.1.8", - "p-map": "^4.0.0", - "webpack-sources": "^3.2.2" - }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", "engines": { "node": ">=14" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", - "engines": { - "node": ">=10" }, "funding": { "type": "github", @@ -3101,11 +3099,11 @@ } }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3116,11 +3114,11 @@ } }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3131,11 +3129,11 @@ } }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3146,11 +3144,11 @@ } }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3161,9 +3159,9 @@ } }, "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", "engines": { "node": ">=12" }, @@ -3176,21 +3174,21 @@ } }, "node_modules/@svgr/babel-preset": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", - "@svgr/babel-plugin-remove-jsx-attribute": "*", - "@svgr/babel-plugin-remove-jsx-empty-expression": "*", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", - "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", - "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", - "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", - "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3201,18 +3199,18 @@ } }, "node_modules/@svgr/core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.1" + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3220,15 +3218,15 @@ } }, "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "dependencies": { - "@babel/types": "^7.20.0", + "@babel/types": "^7.21.3", "entities": "^4.4.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3236,37 +3234,37 @@ } }, "node_modules/@svgr/plugin-jsx": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/hast-util-to-babel-ast": "^6.5.1", + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { - "@svgr/core": "^6.0.0" + "@svgr/core": "*" } }, "node_modules/@svgr/plugin-svgo": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", "dependencies": { - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "svgo": "^2.8.0" + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3277,21 +3275,21 @@ } }, "node_modules/@svgr/webpack": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", "dependencies": { - "@babel/core": "^7.19.6", - "@babel/plugin-transform-react-constant-elements": "^7.18.12", - "@babel/preset-env": "^7.19.4", + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@svgr/core": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "@svgr/plugin-svgo": "^6.5.1" + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3409,9 +3407,9 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", "dependencies": { "@types/estree": "*" } @@ -3444,9 +3442,9 @@ "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" }, "node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dependencies": { "@types/unist": "*" } @@ -3506,9 +3504,9 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "dependencies": { "@types/unist": "*" } @@ -3962,30 +3960,31 @@ } }, "node_modules/algoliasearch": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.0.tgz", - "integrity": "sha512-gfceltjkwh7PxXwtkS8KVvdfK+TSNQAWUeNSxf4dA29qW5tf2EGwa8jkJujlT9jLm17cixMVoGNc+GJFO1Mxhg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", "dependencies": { - "@algolia/cache-browser-local-storage": "4.22.0", - "@algolia/cache-common": "4.22.0", - "@algolia/cache-in-memory": "4.22.0", - "@algolia/client-account": "4.22.0", - "@algolia/client-analytics": "4.22.0", - "@algolia/client-common": "4.22.0", - "@algolia/client-personalization": "4.22.0", - "@algolia/client-search": "4.22.0", - "@algolia/logger-common": "4.22.0", - "@algolia/logger-console": "4.22.0", - "@algolia/requester-browser-xhr": "4.22.0", - "@algolia/requester-common": "4.22.0", - "@algolia/requester-node-http": "4.22.0", - "@algolia/transporter": "4.22.0" + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.1.tgz", - "integrity": "sha512-qxAHVjjmT7USVvrM8q6gZGaJlCK1fl4APfdAA7o8O6iXEc68G0xMNrzRkxoB/HmhhvyHnoteS/iMTiHiTcQQcg==", + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.2.tgz", + "integrity": "sha512-3YQ6eo7uYOCHeQ2ZpD+OoT3aJJwMNKEnwtu8WMzm81XmBOSCwRjQditH9CeSOQ38qhHkuGw23pbq+kULkIJLcw==", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -4104,9 +4103,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "funding": [ { "type": "opencollective", @@ -4122,9 +4121,9 @@ } ], "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -4344,9 +4343,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "funding": [ { "type": "opencollective", @@ -4362,10 +4361,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -4476,9 +4475,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001571", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz", - "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==", + "version": "1.0.30001641", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", + "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", "funding": [ { "type": "opencollective", @@ -5066,18 +5065,28 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cross-spawn": { @@ -5119,11 +5128,11 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", "engines": { - "node": "^10 || ^12 || >=14" + "node": "^14 || ^16 || >=18" }, "peerDependencies": { "postcss": "^8.0.9" @@ -5155,16 +5164,16 @@ } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", - "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", "dependencies": { - "cssnano": "^5.1.8", - "jest-worker": "^29.1.2", - "postcss": "^8.4.17", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" }, "engines": { "node": ">= 14.15.0" @@ -5197,14 +5206,6 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -5221,23 +5222,15 @@ } }, "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, "node_modules/css-what": { @@ -5263,108 +5256,128 @@ } }, "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/cssnano" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-advanced": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", - "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", "dependencies": { - "autoprefixer": "^10.4.12", - "cssnano-preset-default": "^5.2.14", - "postcss-discard-unused": "^5.1.0", - "postcss-merge-idents": "^5.1.1", - "postcss-reduce-idents": "^5.2.0", - "postcss-zindex": "^5.1.0" + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dependencies": { - "css-tree": "^1.1.2" + "css-tree": "~2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -6244,9 +6257,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.616", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", - "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==" + "version": "1.4.827", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz", + "integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==" }, "node_modules/elkjs": { "version": "0.8.2", @@ -6325,9 +6338,9 @@ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "engines": { "node": ">=6" } @@ -6461,15 +6474,11 @@ } }, "node_modules/estree-util-value-to-estree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", + "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", "dependencies": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" + "@types/estree": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/remcohaszing" @@ -7483,9 +7492,9 @@ } }, "node_modules/hast-util-raw": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", - "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -7560,16 +7569,16 @@ } }, "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", + "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" }, "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", + "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", "dependencies": { - "inline-style-parser": "0.2.2" + "inline-style-parser": "0.2.3" } }, "node_modules/hast-util-to-parse5": { @@ -7968,9 +7977,9 @@ } }, "node_modules/image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", "dependencies": { "queue": "6.0.2" }, @@ -7978,7 +7987,7 @@ "image-size": "bin/image-size.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.x" } }, "node_modules/immer": { @@ -8427,13 +8436,13 @@ } }, "node_modules/joi": { - "version": "17.11.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", - "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -8568,11 +8577,14 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -8753,9 +8765,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -8853,9 +8865,9 @@ } }, "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8981,9 +8993,9 @@ } }, "node_modules/mdast-util-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", + "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -9022,9 +9034,9 @@ } }, "node_modules/mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" @@ -9035,9 +9047,9 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", - "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -9046,7 +9058,8 @@ "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", @@ -9085,9 +9098,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/media-typer": { "version": "0.3.0", @@ -9636,9 +9649,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", "funding": [ { "type": "GitHub Sponsors", @@ -9688,9 +9701,9 @@ } }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9759,9 +9772,9 @@ } }, "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9808,9 +9821,9 @@ } }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9861,9 +9874,9 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", @@ -9876,9 +9889,9 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9910,9 +9923,9 @@ ] }, "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", @@ -9948,9 +9961,9 @@ } }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9982,9 +9995,9 @@ ] }, "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -10014,9 +10027,9 @@ ] }, "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -10049,9 +10062,9 @@ } }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10095,9 +10108,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -10130,9 +10143,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10208,9 +10221,9 @@ } }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10282,9 +10295,9 @@ } }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10367,9 +10380,9 @@ } }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10421,9 +10434,9 @@ } }, "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10476,9 +10489,9 @@ } }, "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10535,9 +10548,9 @@ } }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10643,9 +10656,9 @@ } }, "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10717,9 +10730,9 @@ } }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10838,9 +10851,9 @@ } }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10945,9 +10958,9 @@ } }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11120,9 +11133,9 @@ } }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11154,9 +11167,9 @@ ] }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11239,9 +11252,9 @@ } }, "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11495,17 +11508,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -11898,9 +11900,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -11995,9 +11997,9 @@ } }, "node_modules/postcss": { - "version": "8.4.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", - "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "funding": [ { "type": "opencollective", @@ -12014,113 +12016,116 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", "dependencies": { - "postcss-selector-parser": "^6.0.9", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0" }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, "peerDependencies": { "postcss": "^8.2.2" } }, "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "colord": "^2.9.1", + "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-unused": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", - "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-loader": { @@ -12144,136 +12149,111 @@ "webpack": "^5.0.0" } }, - "node_modules/postcss-loader/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/postcss-merge-idents": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", - "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", "dependencies": { - "cssnano-utils": "^3.1.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" + "stylehacks": "^6.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-modules-extract-imports": { @@ -12332,192 +12312,191 @@ } }, "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", "dependencies": { - "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", "dependencies": { - "cssnano-utils": "^3.1.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-idents": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", - "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.14.tgz", - "integrity": "sha512-65xXYsT40i9GyWzlHQ5ShZoK7JZdySeOozi/tz2EezDo6c04q6+ckYMeoY7idaie1qp2dT5KoYQ2yky6JuoHnA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -12527,46 +12506,46 @@ } }, "node_modules/postcss-sort-media-queries": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", - "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", "dependencies": { - "sort-css-media-queries": "2.1.0" + "sort-css-media-queries": "2.2.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "postcss": "^8.4.16" + "postcss": "^8.4.23" } }, "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", "dependencies": { "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" + "svgo": "^3.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >= 18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-value-parser": { @@ -12575,14 +12554,14 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss-zindex": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", - "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/pretty-error": { @@ -12650,9 +12629,9 @@ } }, "node_modules/property-information": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", - "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -12987,9 +12966,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-json-view-lite": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz", - "integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", + "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", "engines": { "node": ">=14" }, @@ -12999,12 +12978,11 @@ }, "node_modules/react-loadable": { "name": "@docusaurus/react-loadable", - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" + "@types/react": "*" }, "peerDependencies": { "react": "*" @@ -13298,9 +13276,9 @@ } }, "node_modules/remark-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", - "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", + "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" @@ -13326,9 +13304,9 @@ } }, "node_modules/remark-rehype": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", - "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -13638,9 +13616,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" }, "node_modules/scheduler": { "version": "0.23.0", @@ -13669,9 +13647,9 @@ } }, "node_modules/search-insights": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", - "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.15.0.tgz", + "integrity": "sha512-ch2sPCUDD4sbPQdknVl9ALSi9H7VyoeVbsxznYz6QV55jJ8CI3EtwpO1i84keN4+hF5IeHWIeGvc08530JkVXQ==", "peer": true }, "node_modules/section-matter": { @@ -14023,9 +14001,9 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", @@ -14064,6 +14042,15 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -14075,9 +14062,9 @@ } }, "node_modules/sort-css-media-queries": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", - "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", "engines": { "node": ">= 6.3.0" } @@ -14091,9 +14078,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -14168,12 +14155,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -14237,9 +14218,9 @@ } }, "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -14309,18 +14290,18 @@ } }, "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/stylis": { @@ -14356,23 +14337,27 @@ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" }, "bin": { "svgo": "bin/svgo" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" } }, "node_modules/svgo/node_modules/commander": { @@ -14383,69 +14368,6 @@ "node": ">= 10" } }, - "node_modules/svgo/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/svgo/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -14646,9 +14568,9 @@ } }, "node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14780,9 +14702,9 @@ } }, "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -14916,9 +14838,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -14934,8 +14856,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -15131,9 +15053,9 @@ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", "engines": { "node": ">= 4" } diff --git a/docs/package.json b/docs/package.json index 21aef7d..1fb6854 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,9 +14,10 @@ "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/preset-classic": "3.0.1", - "@docusaurus/theme-mermaid": "^3.0.1", + "@docusaurus/core": "^3.4.0", + "@docusaurus/plugin-google-gtag": "^3.4.0", + "@docusaurus/preset-classic": "^3.4.0", + "@docusaurus/theme-mermaid": "^3.4.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -24,8 +25,8 @@ "react-dom": "^18.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/types": "3.0.1" + "@docusaurus/module-type-aliases": "^3.4.0", + "@docusaurus/types": "^3.4.0" }, "browserslist": { "production": [ diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index 349602d..bf32e07 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -19,7 +19,7 @@ function HomepageHeader() {
+ to="/intro"> Getting Started
diff --git a/pom.xml b/pom.xml index de40186..71bdf02 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,16 @@ - + 4.0.0 - io.github.amithkoujalgi + io.github.ollama4j ollama4j - 1.0.73-SNAPSHOT + ollama4j-revision Ollama4j Java library for interacting with Ollama API. - https://github.com/amithkoujalgi/ollama4j + https://github.com/ollama4j/ollama4j + jar 11 @@ -31,15 +33,15 @@ MIT License - https://raw.githubusercontent.com/amithkoujalgi/ollama4j/main/LICENSE + https://raw.githubusercontent.com/ollama4j/ollama4j/main/LICENSE - scm:git:git@github.com:amithkoujalgi/ollama4j.git - scm:git:https://github.com/amithkoujalgi/ollama4j.git - https://github.com/amithkoujalgi/ollama4j - v1.0.16 + scm:git:git@github.com:ollama4j/ollama4j.git + scm:git:https://github.com/ollama4j/ollama4j.git + https://github.com/ollama4j/ollama4j + ollama4j-revision @@ -70,27 +72,7 @@ - - - - - - - - - - - - - - - - - - - - - + org.apache.maven.plugins @@ -127,15 +109,23 @@ + + org.apache.maven.plugins - maven-release-plugin - 3.0.1 - - - v@{project.version} - + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + @@ -159,7 +149,7 @@ ch.qos.logback logback-classic - 1.4.12 + 1.5.6 test @@ -188,17 +178,38 @@ - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - ossrh - https://s01.oss.sonatype.org/service/local/staging/deploy/maven2 + mvn-repo-id + + ossrh + + true + + + gpg2 + unit + false + true + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.5.0 + true + + mvn-repo-id + true + + + + + unit-tests @@ -207,7 +218,7 @@ true - true + false diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaStreamHandler.java b/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaStreamHandler.java deleted file mode 100644 index 803f393..0000000 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaStreamHandler.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.core; - -import java.util.function.Consumer; - -public interface OllamaStreamHandler extends Consumer{ - void accept(String message); -} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaAsyncResultCallback.java b/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaAsyncResultCallback.java deleted file mode 100644 index 136f1c6..0000000 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaAsyncResultCallback.java +++ /dev/null @@ -1,143 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.core.models; - -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateResponseModel; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.LinkedList; -import java.util.Queue; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Data -@EqualsAndHashCode(callSuper = true) -@SuppressWarnings("unused") -public class OllamaAsyncResultCallback extends Thread { - private final HttpRequest.Builder requestBuilder; - private final OllamaGenerateRequestModel ollamaRequestModel; - private final Queue queue = new LinkedList<>(); - private String result; - private boolean isDone; - - /** - * -- GETTER -- Returns the status of the request. Indicates if the request was successful or a - * failure. If the request was a failure, the `getResponse()` method will return the error - * message. - */ - @Getter private boolean succeeded; - - private long requestTimeoutSeconds; - - /** - * -- GETTER -- Returns the HTTP response status code for the request that was made to Ollama - * server. - */ - @Getter private int httpStatusCode; - - /** -- GETTER -- Returns the response time in milliseconds. */ - @Getter private long responseTime = 0; - - public OllamaAsyncResultCallback( - HttpRequest.Builder requestBuilder, - OllamaGenerateRequestModel ollamaRequestModel, - long requestTimeoutSeconds) { - this.requestBuilder = requestBuilder; - this.ollamaRequestModel = ollamaRequestModel; - this.isDone = false; - this.result = ""; - this.queue.add(""); - this.requestTimeoutSeconds = requestTimeoutSeconds; - } - - @Override - public void run() { - HttpClient httpClient = HttpClient.newHttpClient(); - try { - long startTime = System.currentTimeMillis(); - HttpRequest request = - requestBuilder - .POST( - HttpRequest.BodyPublishers.ofString( - Utils.getObjectMapper().writeValueAsString(ollamaRequestModel))) - .header("Content-Type", "application/json") - .timeout(Duration.ofSeconds(requestTimeoutSeconds)) - .build(); - HttpResponse response = - httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); - int statusCode = response.statusCode(); - this.httpStatusCode = statusCode; - - InputStream responseBodyStream = response.body(); - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(responseBodyStream, StandardCharsets.UTF_8))) { - String line; - StringBuilder responseBuffer = new StringBuilder(); - while ((line = reader.readLine()) != null) { - if (statusCode == 404) { - OllamaErrorResponseModel ollamaResponseModel = - Utils.getObjectMapper().readValue(line, OllamaErrorResponseModel.class); - queue.add(ollamaResponseModel.getError()); - responseBuffer.append(ollamaResponseModel.getError()); - } else { - OllamaGenerateResponseModel ollamaResponseModel = - Utils.getObjectMapper().readValue(line, OllamaGenerateResponseModel.class); - queue.add(ollamaResponseModel.getResponse()); - if (!ollamaResponseModel.isDone()) { - responseBuffer.append(ollamaResponseModel.getResponse()); - } - } - } - - this.isDone = true; - this.succeeded = true; - this.result = responseBuffer.toString(); - long endTime = System.currentTimeMillis(); - responseTime = endTime - startTime; - } - if (statusCode != 200) { - throw new OllamaBaseException(this.result); - } - } catch (IOException | InterruptedException | OllamaBaseException e) { - this.isDone = true; - this.succeeded = false; - this.result = "[FAILED] " + e.getMessage(); - } - } - - /** - * Returns the status of the thread. This does not indicate that the request was successful or a - * failure, rather it is just a status flag to indicate if the thread is active or ended. - * - * @return boolean - status - */ - public boolean isComplete() { - return isDone; - } - - /** - * Returns the final completion/response when the execution completes. Does not return intermediate results. - * - * @return String completion/response text - */ - public String getResponse() { - return result; - } - - public Queue getStream() { - return queue; - } - - public void setRequestTimeoutSeconds(long requestTimeoutSeconds) { - this.requestTimeoutSeconds = requestTimeoutSeconds; - } -} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestModel.java b/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestModel.java deleted file mode 100644 index b060a4c..0000000 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestModel.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.core.models.generate; - - -import io.github.amithkoujalgi.ollama4j.core.models.OllamaCommonRequestModel; -import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody; - -import java.util.List; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class OllamaGenerateRequestModel extends OllamaCommonRequestModel implements OllamaRequestBody{ - - private String prompt; - private List images; - - private String system; - private String context; - private boolean raw; - - public OllamaGenerateRequestModel() { - } - - public OllamaGenerateRequestModel(String model, String prompt) { - this.model = model; - this.prompt = prompt; - } - - public OllamaGenerateRequestModel(String model, String prompt, List images) { - this.model = model; - this.prompt = prompt; - this.images = images; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof OllamaGenerateRequestModel)) { - return false; - } - - return this.toString().equals(o.toString()); - } - -} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaGenerateEndpointCaller.java b/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaGenerateEndpointCaller.java deleted file mode 100644 index fe7fbec..0000000 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaGenerateEndpointCaller.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; - -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonProcessingException; -import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.BasicAuth; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateResponseModel; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateStreamObserver; -import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; - -public class OllamaGenerateEndpointCaller extends OllamaEndpointCaller{ - - private static final Logger LOG = LoggerFactory.getLogger(OllamaGenerateEndpointCaller.class); - - private OllamaGenerateStreamObserver streamObserver; - - public OllamaGenerateEndpointCaller(String host, BasicAuth basicAuth, long requestTimeoutSeconds, boolean verbose) { - super(host, basicAuth, requestTimeoutSeconds, verbose); - } - - @Override - protected String getEndpointSuffix() { - return "/api/generate"; - } - - @Override - protected boolean parseResponseAndAddToBuffer(String line, StringBuilder responseBuffer) { - try { - OllamaGenerateResponseModel ollamaResponseModel = Utils.getObjectMapper().readValue(line, OllamaGenerateResponseModel.class); - responseBuffer.append(ollamaResponseModel.getResponse()); - if(streamObserver != null) { - streamObserver.notify(ollamaResponseModel); - } - return ollamaResponseModel.isDone(); - } catch (JsonProcessingException e) { - LOG.error("Error parsing the Ollama chat response!",e); - return true; - } - } - - public OllamaResult call(OllamaRequestBody body, OllamaStreamHandler streamHandler) - throws OllamaBaseException, IOException, InterruptedException { - streamObserver = new OllamaGenerateStreamObserver(streamHandler); - return super.callSync(body); - } - - -} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java b/src/main/java/io/github/ollama4j/OllamaAPI.java similarity index 74% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java rename to src/main/java/io/github/ollama4j/OllamaAPI.java index 1f22210..d3c68a2 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java +++ b/src/main/java/io/github/ollama4j/OllamaAPI.java @@ -1,17 +1,23 @@ -package io.github.amithkoujalgi.ollama4j.core; +package io.github.ollama4j; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.*; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessage; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatResult; -import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingResponseModel; -import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.request.*; -import io.github.amithkoujalgi.ollama4j.core.utils.Options; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.exceptions.ToolInvocationException; +import io.github.ollama4j.exceptions.ToolNotFoundException; +import io.github.ollama4j.models.chat.OllamaChatMessage; +import io.github.ollama4j.models.chat.OllamaChatRequest; +import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; +import io.github.ollama4j.models.chat.OllamaChatResult; +import io.github.ollama4j.models.embeddings.OllamaEmbeddingResponseModel; +import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel; +import io.github.ollama4j.models.generate.OllamaGenerateRequest; +import io.github.ollama4j.models.generate.OllamaStreamHandler; +import io.github.ollama4j.models.ps.ModelsProcessResponse; +import io.github.ollama4j.models.request.*; +import io.github.ollama4j.models.response.*; +import io.github.ollama4j.tools.*; +import io.github.ollama4j.utils.Options; +import io.github.ollama4j.utils.Utils; +import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,9 +31,7 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.time.Duration; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; +import java.util.*; /** * The base Ollama API class. @@ -37,12 +41,31 @@ public class OllamaAPI { private static final Logger logger = LoggerFactory.getLogger(OllamaAPI.class); private final String host; + /** + * -- SETTER -- + * Set request timeout in seconds. Default is 3 seconds. + */ + @Setter private long requestTimeoutSeconds = 10; + /** + * -- SETTER -- + * Set/unset logging of responses + */ + @Setter private boolean verbose = true; private BasicAuth basicAuth; + private final ToolRegistry toolRegistry = new ToolRegistry(); + /** - * Instantiates the Ollama API. + * Instantiates the Ollama API with default Ollama host: http://localhost:11434 + **/ + public OllamaAPI() { + this.host = "http://localhost:11434"; + } + + /** + * Instantiates the Ollama API with specified Ollama host address. * * @param host the host address of Ollama server */ @@ -54,24 +77,6 @@ public class OllamaAPI { } } - /** - * Set request timeout in seconds. Default is 3 seconds. - * - * @param requestTimeoutSeconds the request timeout in seconds - */ - public void setRequestTimeoutSeconds(long requestTimeoutSeconds) { - this.requestTimeoutSeconds = requestTimeoutSeconds; - } - - /** - * Set/unset logging of responses - * - * @param verbose true/false - */ - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - /** * Set basic authentication for accessing Ollama server that's behind a reverse-proxy/gateway. * @@ -113,6 +118,37 @@ public class OllamaAPI { return statusCode == 200; } + /** + * Provides a list of running models and details about each model currently loaded into memory. + * + * @return ModelsProcessResponse + */ + public ModelsProcessResponse ps() throws IOException, InterruptedException, OllamaBaseException { + String url = this.host + "/api/ps"; + HttpClient httpClient = HttpClient.newHttpClient(); + HttpRequest httpRequest = null; + try { + httpRequest = + getRequestBuilderDefault(new URI(url)) + .header("Accept", "application/json") + .header("Content-type", "application/json") + .GET() + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + HttpResponse response = null; + response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + int statusCode = response.statusCode(); + String responseString = response.body(); + if (statusCode == 200) { + return Utils.getObjectMapper() + .readValue(responseString, ModelsProcessResponse.class); + } else { + throw new OllamaBaseException(statusCode + " - " + responseString); + } + } + /** * List available models from Ollama server. * @@ -339,6 +375,7 @@ public class OllamaAPI { } } + /** * Generate response for a question to a model running on Ollama server. This is a sync/blocking * call. @@ -351,23 +388,67 @@ public class OllamaAPI { * @param streamHandler optional callback consumer that will be applied every time a streamed response is received. If not set, the stream parameter of the request is set to false. * @return OllamaResult that includes response text and time taken for response */ - public OllamaResult generate(String model, String prompt, Options options, OllamaStreamHandler streamHandler) + public OllamaResult generate(String model, String prompt, boolean raw, Options options, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException { - OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt); + OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt); + ollamaRequestModel.setRaw(raw); ollamaRequestModel.setOptions(options.getOptionsMap()); return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler); } /** - * Convenience method to call Ollama API without streaming responses. + * Generates response using the specified AI model and prompt (in blocking mode). *

- * Uses {@link #generate(String, String, Options, OllamaStreamHandler)} + * Uses {@link #generate(String, String, boolean, Options, OllamaStreamHandler)} + * + * @param model The name or identifier of the AI model to use for generating the response. + * @param prompt The input text or prompt to provide to the AI model. + * @param raw In some cases, you may wish to bypass the templating system and provide a full prompt. In this case, you can use the raw parameter to disable templating. Also note that raw mode will not return a context. + * @param options Additional options or configurations to use when generating the response. + * @return {@link OllamaResult} */ - public OllamaResult generate(String model, String prompt, Options options) + public OllamaResult generate(String model, String prompt, boolean raw, Options options) throws OllamaBaseException, IOException, InterruptedException { - return generate(model, prompt, options, null); + return generate(model, prompt, raw, options, null); } + + /** + * Generates response using the specified AI model and prompt (in blocking mode), and then invokes a set of tools + * on the generated response. + * + * @param model The name or identifier of the AI model to use for generating the response. + * @param prompt The input text or prompt to provide to the AI model. + * @param options Additional options or configurations to use when generating the response. + * @return {@link OllamaToolsResult} An OllamaToolsResult object containing the response from the AI model and the results of invoking the tools on that output. + * @throws OllamaBaseException If there is an error related to the Ollama API or service. + * @throws IOException If there is an error related to input/output operations. + * @throws InterruptedException If the method is interrupted while waiting for the AI model + * to generate the response or for the tools to be invoked. + */ + public OllamaToolsResult generateWithTools(String model, String prompt, Options options) + throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException { + boolean raw = true; + OllamaToolsResult toolResult = new OllamaToolsResult(); + Map toolResults = new HashMap<>(); + + OllamaResult result = generate(model, prompt, raw, options, null); + toolResult.setModelResult(result); + + String toolsResponse = result.getResponse(); + if (toolsResponse.contains("[TOOL_CALLS]")) { + toolsResponse = toolsResponse.replace("[TOOL_CALLS]", ""); + } + + List toolFunctionCallSpecs = Utils.getObjectMapper().readValue(toolsResponse, Utils.getObjectMapper().getTypeFactory().constructCollectionType(List.class, ToolFunctionCallSpec.class)); + for (ToolFunctionCallSpec toolFunctionCallSpec : toolFunctionCallSpecs) { + toolResults.put(toolFunctionCallSpec, invokeTool(toolFunctionCallSpec)); + } + toolResult.setToolResults(toolResults); + return toolResult; + } + + /** * Generate response for a question to a model running on Ollama server and get a callback handle * that can be used to check for status and get the response from the model later. This would be @@ -377,15 +458,15 @@ public class OllamaAPI { * @param prompt the prompt/question text * @return the ollama async result callback handle */ - public OllamaAsyncResultCallback generateAsync(String model, String prompt) { - OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt); - + public OllamaAsyncResultStreamer generateAsync(String model, String prompt, boolean raw) { + OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt); + ollamaRequestModel.setRaw(raw); URI uri = URI.create(this.host + "/api/generate"); - OllamaAsyncResultCallback ollamaAsyncResultCallback = - new OllamaAsyncResultCallback( + OllamaAsyncResultStreamer ollamaAsyncResultStreamer = + new OllamaAsyncResultStreamer( getRequestBuilderDefault(uri), ollamaRequestModel, requestTimeoutSeconds); - ollamaAsyncResultCallback.start(); - return ollamaAsyncResultCallback; + ollamaAsyncResultStreamer.start(); + return ollamaAsyncResultStreamer; } /** @@ -408,7 +489,7 @@ public class OllamaAPI { for (File imageFile : imageFiles) { images.add(encodeFileToBase64(imageFile)); } - OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt, images); + OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt, images); ollamaRequestModel.setOptions(options.getOptionsMap()); return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler); } @@ -444,7 +525,7 @@ public class OllamaAPI { for (String imageURL : imageURLs) { images.add(encodeByteArrayToBase64(Utils.loadImageBytesFromUrl(imageURL))); } - OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt, images); + OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt, images); ollamaRequestModel.setOptions(options.getOptionsMap()); return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler); } @@ -478,33 +559,33 @@ public class OllamaAPI { } /** - * Ask a question to a model using an {@link OllamaChatRequestModel}. This can be constructed using an {@link OllamaChatRequestBuilder}. + * Ask a question to a model using an {@link OllamaChatRequest}. This can be constructed using an {@link OllamaChatRequestBuilder}. *

* Hint: the OllamaChatRequestModel#getStream() property is not implemented. * * @param request request object to be sent to the server - * @return + * @return {@link OllamaChatResult} * @throws OllamaBaseException any response code than 200 has been returned * @throws IOException in case the responseStream can not be read * @throws InterruptedException in case the server is not reachable or network issues happen */ - public OllamaChatResult chat(OllamaChatRequestModel request) throws OllamaBaseException, IOException, InterruptedException { + public OllamaChatResult chat(OllamaChatRequest request) throws OllamaBaseException, IOException, InterruptedException { return chat(request, null); } /** - * Ask a question to a model using an {@link OllamaChatRequestModel}. This can be constructed using an {@link OllamaChatRequestBuilder}. + * Ask a question to a model using an {@link OllamaChatRequest}. This can be constructed using an {@link OllamaChatRequestBuilder}. *

* Hint: the OllamaChatRequestModel#getStream() property is not implemented. * * @param request request object to be sent to the server * @param streamHandler callback handler to handle the last message from stream (caution: all previous messages from stream will be concatenated) - * @return + * @return {@link OllamaChatResult} * @throws OllamaBaseException any response code than 200 has been returned * @throws IOException in case the responseStream can not be read * @throws InterruptedException in case the server is not reachable or network issues happen */ - public OllamaChatResult chat(OllamaChatRequestModel request, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException { + public OllamaChatResult chat(OllamaChatRequest request, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException { OllamaChatEndpointCaller requestCaller = new OllamaChatEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose); OllamaResult result; if (streamHandler != null) { @@ -516,6 +597,10 @@ public class OllamaAPI { return new OllamaChatResult(result.getResponse(), result.getResponseTime(), result.getHttpStatusCode(), request.getMessages()); } + public void registerTool(Tools.ToolSpecification toolSpecification) { + toolRegistry.addFunction(toolSpecification.getFunctionName(), toolSpecification.getToolDefinition()); + } + // technical private methods // private static String encodeFileToBase64(File file) throws IOException { @@ -527,7 +612,7 @@ public class OllamaAPI { } private OllamaResult generateSyncForOllamaRequestModel( - OllamaGenerateRequestModel ollamaRequestModel, OllamaStreamHandler streamHandler) + OllamaGenerateRequest ollamaRequestModel, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException { OllamaGenerateEndpointCaller requestCaller = new OllamaGenerateEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose); @@ -576,4 +661,22 @@ public class OllamaAPI { private boolean isBasicAuthCredentialsSet() { return basicAuth != null; } + + + private Object invokeTool(ToolFunctionCallSpec toolFunctionCallSpec) throws ToolInvocationException { + try { + String methodName = toolFunctionCallSpec.getName(); + Map arguments = toolFunctionCallSpec.getArguments(); + ToolFunction function = toolRegistry.getFunction(methodName); + if (verbose) { + logger.debug("Invoking function {} with arguments {}", methodName, arguments); + } + if (function == null) { + throw new ToolNotFoundException("No such tool: " + methodName); + } + return function.apply(arguments); + } catch (Exception e) { + throw new ToolInvocationException("Failed to invoke tool: " + toolFunctionCallSpec.getName(), e); + } + } } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/exceptions/OllamaBaseException.java b/src/main/java/io/github/ollama4j/exceptions/OllamaBaseException.java similarity index 68% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/exceptions/OllamaBaseException.java rename to src/main/java/io/github/ollama4j/exceptions/OllamaBaseException.java index 7c8612f..9474d72 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/exceptions/OllamaBaseException.java +++ b/src/main/java/io/github/ollama4j/exceptions/OllamaBaseException.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.exceptions; +package io.github.ollama4j.exceptions; public class OllamaBaseException extends Exception { diff --git a/src/main/java/io/github/ollama4j/exceptions/ToolInvocationException.java b/src/main/java/io/github/ollama4j/exceptions/ToolInvocationException.java new file mode 100644 index 0000000..ea81bb9 --- /dev/null +++ b/src/main/java/io/github/ollama4j/exceptions/ToolInvocationException.java @@ -0,0 +1,8 @@ +package io.github.ollama4j.exceptions; + +public class ToolInvocationException extends Exception { + + public ToolInvocationException(String s, Exception e) { + super(s, e); + } +} diff --git a/src/main/java/io/github/ollama4j/exceptions/ToolNotFoundException.java b/src/main/java/io/github/ollama4j/exceptions/ToolNotFoundException.java new file mode 100644 index 0000000..bd3e007 --- /dev/null +++ b/src/main/java/io/github/ollama4j/exceptions/ToolNotFoundException.java @@ -0,0 +1,8 @@ +package io.github.ollama4j.exceptions; + +public class ToolNotFoundException extends Exception { + + public ToolNotFoundException(String s) { + super(s); + } +} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/impl/ConsoleOutputStreamHandler.java b/src/main/java/io/github/ollama4j/impl/ConsoleOutputStreamHandler.java similarity index 73% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/impl/ConsoleOutputStreamHandler.java rename to src/main/java/io/github/ollama4j/impl/ConsoleOutputStreamHandler.java index 6807019..c9f8e36 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/impl/ConsoleOutputStreamHandler.java +++ b/src/main/java/io/github/ollama4j/impl/ConsoleOutputStreamHandler.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.impl; +package io.github.ollama4j.impl; -import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler; +import io.github.ollama4j.models.generate.OllamaStreamHandler; public class ConsoleOutputStreamHandler implements OllamaStreamHandler { private final StringBuffer response = new StringBuffer(); diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessage.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatMessage.java similarity index 83% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessage.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatMessage.java index 0b14315..d4fe195 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessage.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatMessage.java @@ -1,11 +1,11 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.github.amithkoujalgi.ollama4j.core.utils.FileToBase64Serializer; +import io.github.ollama4j.utils.FileToBase64Serializer; import java.util.List; import lombok.AllArgsConstructor; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessageRole.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatMessageRole.java similarity index 85% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessageRole.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatMessageRole.java index cbecb00..3986135 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatMessageRole.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatMessageRole.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestModel.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatRequest.java similarity index 53% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestModel.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatRequest.java index e55bf6a..e6e528d 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestModel.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatRequest.java @@ -1,8 +1,9 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; import java.util.List; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaCommonRequestModel; -import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody; + +import io.github.ollama4j.models.request.OllamaCommonRequest; +import io.github.ollama4j.utils.OllamaRequestBody; import lombok.Getter; import lombok.Setter; @@ -16,20 +17,20 @@ import lombok.Setter; */ @Getter @Setter -public class OllamaChatRequestModel extends OllamaCommonRequestModel implements OllamaRequestBody { +public class OllamaChatRequest extends OllamaCommonRequest implements OllamaRequestBody { private List messages; - public OllamaChatRequestModel() {} + public OllamaChatRequest() {} - public OllamaChatRequestModel(String model, List messages) { + public OllamaChatRequest(String model, List messages) { this.model = model; this.messages = messages; } @Override public boolean equals(Object o) { - if (!(o instanceof OllamaChatRequestModel)) { + if (!(o instanceof OllamaChatRequest)) { return false; } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestBuilder.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatRequestBuilder.java similarity index 61% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestBuilder.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatRequestBuilder.java index e07722f..7cdf879 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatRequestBuilder.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatRequestBuilder.java @@ -1,4 +1,9 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; + +import io.github.ollama4j.utils.Options; +import io.github.ollama4j.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -8,101 +13,92 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.github.amithkoujalgi.ollama4j.core.utils.Options; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; - /** - * Helper class for creating {@link OllamaChatRequestModel} objects using the builder-pattern. + * Helper class for creating {@link OllamaChatRequest} objects using the builder-pattern. */ public class OllamaChatRequestBuilder { private static final Logger LOG = LoggerFactory.getLogger(OllamaChatRequestBuilder.class); - private OllamaChatRequestBuilder(String model, List messages){ - request = new OllamaChatRequestModel(model, messages); + private OllamaChatRequestBuilder(String model, List messages) { + request = new OllamaChatRequest(model, messages); } - private OllamaChatRequestModel request; + private OllamaChatRequest request; - public static OllamaChatRequestBuilder getInstance(String model){ + public static OllamaChatRequestBuilder getInstance(String model) { return new OllamaChatRequestBuilder(model, new ArrayList<>()); } - public OllamaChatRequestModel build(){ + public OllamaChatRequest build() { return request; } - public void reset(){ - request = new OllamaChatRequestModel(request.getModel(), new ArrayList<>()); + public void reset() { + request = new OllamaChatRequest(request.getModel(), new ArrayList<>()); } - public OllamaChatRequestBuilder withMessage(OllamaChatMessageRole role, String content, List images){ + public OllamaChatRequestBuilder withMessage(OllamaChatMessageRole role, String content, List images) { List messages = this.request.getMessages(); List binaryImages = images.stream().map(file -> { try { return Files.readAllBytes(file.toPath()); } catch (IOException e) { - LOG.warn(String.format("File '%s' could not be accessed, will not add to message!",file.toPath()), e); + LOG.warn(String.format("File '%s' could not be accessed, will not add to message!", file.toPath()), e); return new byte[0]; } }).collect(Collectors.toList()); - messages.add(new OllamaChatMessage(role,content,binaryImages)); + messages.add(new OllamaChatMessage(role, content, binaryImages)); return this; } - public OllamaChatRequestBuilder withMessage(OllamaChatMessageRole role, String content, String... imageUrls){ + public OllamaChatRequestBuilder withMessage(OllamaChatMessageRole role, String content, String... imageUrls) { List messages = this.request.getMessages(); List binaryImages = null; - if(imageUrls.length>0){ + if (imageUrls.length > 0) { binaryImages = new ArrayList<>(); for (String imageUrl : imageUrls) { - try{ + try { binaryImages.add(Utils.loadImageBytesFromUrl(imageUrl)); - } - catch (URISyntaxException e){ - LOG.warn(String.format("URL '%s' could not be accessed, will not add to message!",imageUrl), e); - } - catch (IOException e){ - LOG.warn(String.format("Content of URL '%s' could not be read, will not add to message!",imageUrl), e); + } catch (URISyntaxException e) { + LOG.warn(String.format("URL '%s' could not be accessed, will not add to message!", imageUrl), e); + } catch (IOException e) { + LOG.warn(String.format("Content of URL '%s' could not be read, will not add to message!", imageUrl), e); } } } - - messages.add(new OllamaChatMessage(role,content,binaryImages)); + + messages.add(new OllamaChatMessage(role, content, binaryImages)); return this; } - public OllamaChatRequestBuilder withMessages(List messages){ - this.request.getMessages().addAll(messages); - return this; + public OllamaChatRequestBuilder withMessages(List messages) { + return new OllamaChatRequestBuilder(request.getModel(), messages); } - public OllamaChatRequestBuilder withOptions(Options options){ + public OllamaChatRequestBuilder withOptions(Options options) { this.request.setOptions(options.getOptionsMap()); return this; } - public OllamaChatRequestBuilder withGetJsonResponse(){ + public OllamaChatRequestBuilder withGetJsonResponse() { this.request.setReturnFormatJson(true); return this; } - public OllamaChatRequestBuilder withTemplate(String template){ + public OllamaChatRequestBuilder withTemplate(String template) { this.request.setTemplate(template); return this; } - public OllamaChatRequestBuilder withStreaming(){ + public OllamaChatRequestBuilder withStreaming() { this.request.setStream(true); return this; } - public OllamaChatRequestBuilder withKeepAlive(String keepAlive){ + public OllamaChatRequestBuilder withKeepAlive(String keepAlive) { this.request.setKeepAlive(keepAlive); return this; } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResponseModel.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatResponseModel.java similarity index 93% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResponseModel.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatResponseModel.java index 418338f..2ccc731 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResponseModel.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatResponseModel.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResult.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatResult.java similarity index 88% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResult.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatResult.java index 6ac6578..b105e81 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatResult.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatResult.java @@ -1,8 +1,8 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; import java.util.List; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; +import io.github.ollama4j.models.response.OllamaResult; /** * Specific chat-API result that contains the chat history sent to the model and appends the answer as {@link OllamaChatResult} given by the diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatStreamObserver.java b/src/main/java/io/github/ollama4j/models/chat/OllamaChatStreamObserver.java similarity index 82% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatStreamObserver.java rename to src/main/java/io/github/ollama4j/models/chat/OllamaChatStreamObserver.java index ea4b4d8..9f1bf7f 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/chat/OllamaChatStreamObserver.java +++ b/src/main/java/io/github/ollama4j/models/chat/OllamaChatStreamObserver.java @@ -1,10 +1,10 @@ -package io.github.amithkoujalgi.ollama4j.core.models.chat; +package io.github.ollama4j.models.chat; + +import io.github.ollama4j.models.generate.OllamaStreamHandler; import java.util.ArrayList; import java.util.List; -import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler; - public class OllamaChatStreamObserver { private OllamaStreamHandler streamHandler; @@ -17,12 +17,12 @@ public class OllamaChatStreamObserver { this.streamHandler = streamHandler; } - public void notify(OllamaChatResponseModel currentResponsePart){ + public void notify(OllamaChatResponseModel currentResponsePart) { responseParts.add(currentResponsePart); handleCurrentResponsePart(currentResponsePart); } - - protected void handleCurrentResponsePart(OllamaChatResponseModel currentResponsePart){ + + protected void handleCurrentResponsePart(OllamaChatResponseModel currentResponsePart) { message = message + currentResponsePart.getMessage().getContent(); streamHandler.accept(message); } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingResponseModel.java b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingResponseModel.java similarity index 79% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingResponseModel.java rename to src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingResponseModel.java index 85dba31..24d95bc 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingResponseModel.java +++ b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingResponseModel.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models.embeddings; +package io.github.ollama4j.models.embeddings; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestBuilder.java b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestBuilder.java similarity index 86% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestBuilder.java rename to src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestBuilder.java index ef7a84e..b542931 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestBuilder.java +++ b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestBuilder.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models.embeddings; +package io.github.ollama4j.models.embeddings; -import io.github.amithkoujalgi.ollama4j.core.utils.Options; +import io.github.ollama4j.utils.Options; public class OllamaEmbeddingsRequestBuilder { diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestModel.java b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestModel.java similarity index 83% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestModel.java rename to src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestModel.java index a369124..d700b91 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/embeddings/OllamaEmbeddingsRequestModel.java +++ b/src/main/java/io/github/ollama4j/models/embeddings/OllamaEmbeddingsRequestModel.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models.embeddings; +package io.github.ollama4j.models.embeddings; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import java.util.Map; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequest.java b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequest.java new file mode 100644 index 0000000..de767dc --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequest.java @@ -0,0 +1,46 @@ +package io.github.ollama4j.models.generate; + + +import io.github.ollama4j.models.request.OllamaCommonRequest; +import io.github.ollama4j.utils.OllamaRequestBody; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class OllamaGenerateRequest extends OllamaCommonRequest implements OllamaRequestBody{ + + private String prompt; + private List images; + + private String system; + private String context; + private boolean raw; + + public OllamaGenerateRequest() { + } + + public OllamaGenerateRequest(String model, String prompt) { + this.model = model; + this.prompt = prompt; + } + + public OllamaGenerateRequest(String model, String prompt, List images) { + this.model = model; + this.prompt = prompt; + this.images = images; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof OllamaGenerateRequest)) { + return false; + } + + return this.toString().equals(o.toString()); + } + +} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestBuilder.java b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequestBuilder.java similarity index 74% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestBuilder.java rename to src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequestBuilder.java index 48b4d18..f802094 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateRequestBuilder.java +++ b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateRequestBuilder.java @@ -1,24 +1,24 @@ -package io.github.amithkoujalgi.ollama4j.core.models.generate; +package io.github.ollama4j.models.generate; -import io.github.amithkoujalgi.ollama4j.core.utils.Options; +import io.github.ollama4j.utils.Options; /** - * Helper class for creating {@link io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel} + * Helper class for creating {@link OllamaGenerateRequest} * objects using the builder-pattern. */ public class OllamaGenerateRequestBuilder { private OllamaGenerateRequestBuilder(String model, String prompt){ - request = new OllamaGenerateRequestModel(model, prompt); + request = new OllamaGenerateRequest(model, prompt); } - private OllamaGenerateRequestModel request; + private OllamaGenerateRequest request; public static OllamaGenerateRequestBuilder getInstance(String model){ return new OllamaGenerateRequestBuilder(model,""); } - public OllamaGenerateRequestModel build(){ + public OllamaGenerateRequest build(){ return request; } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateResponseModel.java b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateResponseModel.java similarity index 92% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateResponseModel.java rename to src/main/java/io/github/ollama4j/models/generate/OllamaGenerateResponseModel.java index a575a7a..9fb975e 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateResponseModel.java +++ b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateResponseModel.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models.generate; +package io.github.ollama4j.models.generate; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateStreamObserver.java b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateStreamObserver.java similarity index 80% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateStreamObserver.java rename to src/main/java/io/github/ollama4j/models/generate/OllamaGenerateStreamObserver.java index a166bac..bc47fa0 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/generate/OllamaGenerateStreamObserver.java +++ b/src/main/java/io/github/ollama4j/models/generate/OllamaGenerateStreamObserver.java @@ -1,10 +1,8 @@ -package io.github.amithkoujalgi.ollama4j.core.models.generate; +package io.github.ollama4j.models.generate; import java.util.ArrayList; import java.util.List; -import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler; - public class OllamaGenerateStreamObserver { private OllamaStreamHandler streamHandler; @@ -17,12 +15,12 @@ public class OllamaGenerateStreamObserver { this.streamHandler = streamHandler; } - public void notify(OllamaGenerateResponseModel currentResponsePart){ + public void notify(OllamaGenerateResponseModel currentResponsePart) { responseParts.add(currentResponsePart); handleCurrentResponsePart(currentResponsePart); } - - protected void handleCurrentResponsePart(OllamaGenerateResponseModel currentResponsePart){ + + protected void handleCurrentResponsePart(OllamaGenerateResponseModel currentResponsePart) { message = message + currentResponsePart.getResponse(); streamHandler.accept(message); } diff --git a/src/main/java/io/github/ollama4j/models/generate/OllamaStreamHandler.java b/src/main/java/io/github/ollama4j/models/generate/OllamaStreamHandler.java new file mode 100644 index 0000000..e2da640 --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/generate/OllamaStreamHandler.java @@ -0,0 +1,7 @@ +package io.github.ollama4j.models.generate; + +import java.util.function.Consumer; + +public interface OllamaStreamHandler extends Consumer { + void accept(String message); +} diff --git a/src/main/java/io/github/ollama4j/models/ps/ModelsProcessResponse.java b/src/main/java/io/github/ollama4j/models/ps/ModelsProcessResponse.java new file mode 100644 index 0000000..490d362 --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/ps/ModelsProcessResponse.java @@ -0,0 +1,63 @@ +package io.github.ollama4j.models.ps; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ModelsProcessResponse { + @JsonProperty("models") + private List models; + + @Data + @NoArgsConstructor + public static class ModelProcess { + @JsonProperty("name") + private String name; + + @JsonProperty("model") + private String model; + + @JsonProperty("size") + private long size; + + @JsonProperty("digest") + private String digest; + + @JsonProperty("details") + private ModelDetails details; + + @JsonProperty("expires_at") + private String expiresAt; // Consider using LocalDateTime if you need to process date/time + + @JsonProperty("size_vram") + private long sizeVram; + } + + @Data + @NoArgsConstructor + public static class ModelDetails { + @JsonProperty("parent_model") + private String parentModel; + + @JsonProperty("format") + private String format; + + @JsonProperty("family") + private String family; + + @JsonProperty("families") + private List families; + + @JsonProperty("parameter_size") + private String parameterSize; + + @JsonProperty("quantization_level") + private String quantizationLevel; + } +} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/BasicAuth.java b/src/main/java/io/github/ollama4j/models/request/BasicAuth.java similarity index 79% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/BasicAuth.java rename to src/main/java/io/github/ollama4j/models/request/BasicAuth.java index dbcf8a7..f3372a9 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/BasicAuth.java +++ b/src/main/java/io/github/ollama4j/models/request/BasicAuth.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.request; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFileContentsRequest.java b/src/main/java/io/github/ollama4j/models/request/CustomModelFileContentsRequest.java similarity index 76% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFileContentsRequest.java rename to src/main/java/io/github/ollama4j/models/request/CustomModelFileContentsRequest.java index 9e606d3..6841476 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFileContentsRequest.java +++ b/src/main/java/io/github/ollama4j/models/request/CustomModelFileContentsRequest.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; +package io.github.ollama4j.models.request; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.AllArgsConstructor; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFilePathRequest.java b/src/main/java/io/github/ollama4j/models/request/CustomModelFilePathRequest.java similarity index 76% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFilePathRequest.java rename to src/main/java/io/github/ollama4j/models/request/CustomModelFilePathRequest.java index ea08dbf..2fcda43 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/CustomModelFilePathRequest.java +++ b/src/main/java/io/github/ollama4j/models/request/CustomModelFilePathRequest.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; +package io.github.ollama4j.models.request; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.AllArgsConstructor; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/ModelRequest.java b/src/main/java/io/github/ollama4j/models/request/ModelRequest.java similarity index 74% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/ModelRequest.java rename to src/main/java/io/github/ollama4j/models/request/ModelRequest.java index d3fdec4..923cd87 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/ModelRequest.java +++ b/src/main/java/io/github/ollama4j/models/request/ModelRequest.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; +package io.github.ollama4j.models.request; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.AllArgsConstructor; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaChatEndpointCaller.java b/src/main/java/io/github/ollama4j/models/request/OllamaChatEndpointCaller.java similarity index 72% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaChatEndpointCaller.java rename to src/main/java/io/github/ollama4j/models/request/OllamaChatEndpointCaller.java index cc6c7f8..b875bf8 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaChatEndpointCaller.java +++ b/src/main/java/io/github/ollama4j/models/request/OllamaChatEndpointCaller.java @@ -1,14 +1,13 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; +package io.github.ollama4j.models.request; import com.fasterxml.jackson.core.JsonProcessingException; -import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.BasicAuth; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatResponseModel; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatStreamObserver; -import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.models.chat.OllamaChatResponseModel; +import io.github.ollama4j.models.chat.OllamaChatStreamObserver; +import io.github.ollama4j.models.generate.OllamaStreamHandler; +import io.github.ollama4j.utils.OllamaRequestBody; +import io.github.ollama4j.utils.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaCommonRequestModel.java b/src/main/java/io/github/ollama4j/models/request/OllamaCommonRequest.java similarity index 78% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaCommonRequestModel.java rename to src/main/java/io/github/ollama4j/models/request/OllamaCommonRequest.java index 6f985ab..2e6ed7e 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaCommonRequestModel.java +++ b/src/main/java/io/github/ollama4j/models/request/OllamaCommonRequest.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.request; import java.util.Map; import com.fasterxml.jackson.annotation.JsonInclude; @@ -6,13 +6,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.github.amithkoujalgi.ollama4j.core.utils.BooleanToJsonFormatFlagSerializer; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.utils.BooleanToJsonFormatFlagSerializer; +import io.github.ollama4j.utils.Utils; import lombok.Data; @Data @JsonInclude(JsonInclude.Include.NON_NULL) -public abstract class OllamaCommonRequestModel { +public abstract class OllamaCommonRequest { protected String model; @JsonSerialize(using = BooleanToJsonFormatFlagSerializer.class) diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaEndpointCaller.java b/src/main/java/io/github/ollama4j/models/request/OllamaEndpointCaller.java similarity index 85% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaEndpointCaller.java rename to src/main/java/io/github/ollama4j/models/request/OllamaEndpointCaller.java index 350200a..8529c18 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/request/OllamaEndpointCaller.java +++ b/src/main/java/io/github/ollama4j/models/request/OllamaEndpointCaller.java @@ -1,12 +1,11 @@ -package io.github.amithkoujalgi.ollama4j.core.models.request; +package io.github.ollama4j.models.request; -import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.BasicAuth; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaErrorResponseModel; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.response.OllamaErrorResponse; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.utils.OllamaRequestBody; +import io.github.ollama4j.utils.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,19 +77,19 @@ public abstract class OllamaEndpointCaller { while ((line = reader.readLine()) != null) { if (statusCode == 404) { LOG.warn("Status code: 404 (Not Found)"); - OllamaErrorResponseModel ollamaResponseModel = - Utils.getObjectMapper().readValue(line, OllamaErrorResponseModel.class); + OllamaErrorResponse ollamaResponseModel = + Utils.getObjectMapper().readValue(line, OllamaErrorResponse.class); responseBuffer.append(ollamaResponseModel.getError()); } else if (statusCode == 401) { LOG.warn("Status code: 401 (Unauthorized)"); - OllamaErrorResponseModel ollamaResponseModel = + OllamaErrorResponse ollamaResponseModel = Utils.getObjectMapper() - .readValue("{\"error\":\"Unauthorized\"}", OllamaErrorResponseModel.class); + .readValue("{\"error\":\"Unauthorized\"}", OllamaErrorResponse.class); responseBuffer.append(ollamaResponseModel.getError()); } else if (statusCode == 400) { LOG.warn("Status code: 400 (Bad Request)"); - OllamaErrorResponseModel ollamaResponseModel = Utils.getObjectMapper().readValue(line, - OllamaErrorResponseModel.class); + OllamaErrorResponse ollamaResponseModel = Utils.getObjectMapper().readValue(line, + OllamaErrorResponse.class); responseBuffer.append(ollamaResponseModel.getError()); } else { boolean finished = parseResponseAndAddToBuffer(line, responseBuffer); diff --git a/src/main/java/io/github/ollama4j/models/request/OllamaGenerateEndpointCaller.java b/src/main/java/io/github/ollama4j/models/request/OllamaGenerateEndpointCaller.java new file mode 100644 index 0000000..f4afb2c --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/request/OllamaGenerateEndpointCaller.java @@ -0,0 +1,51 @@ +package io.github.ollama4j.models.request; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.models.generate.OllamaGenerateResponseModel; +import io.github.ollama4j.models.generate.OllamaGenerateStreamObserver; +import io.github.ollama4j.models.generate.OllamaStreamHandler; +import io.github.ollama4j.utils.OllamaRequestBody; +import io.github.ollama4j.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class OllamaGenerateEndpointCaller extends OllamaEndpointCaller { + + private static final Logger LOG = LoggerFactory.getLogger(OllamaGenerateEndpointCaller.class); + + private OllamaGenerateStreamObserver streamObserver; + + public OllamaGenerateEndpointCaller(String host, BasicAuth basicAuth, long requestTimeoutSeconds, boolean verbose) { + super(host, basicAuth, requestTimeoutSeconds, verbose); + } + + @Override + protected String getEndpointSuffix() { + return "/api/generate"; + } + + @Override + protected boolean parseResponseAndAddToBuffer(String line, StringBuilder responseBuffer) { + try { + OllamaGenerateResponseModel ollamaResponseModel = Utils.getObjectMapper().readValue(line, OllamaGenerateResponseModel.class); + responseBuffer.append(ollamaResponseModel.getResponse()); + if (streamObserver != null) { + streamObserver.notify(ollamaResponseModel); + } + return ollamaResponseModel.isDone(); + } catch (JsonProcessingException e) { + LOG.error("Error parsing the Ollama chat response!", e); + return true; + } + } + + public OllamaResult call(OllamaRequestBody body, OllamaStreamHandler streamHandler) + throws OllamaBaseException, IOException, InterruptedException { + streamObserver = new OllamaGenerateStreamObserver(streamHandler); + return super.callSync(body); + } +} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ListModelsResponse.java b/src/main/java/io/github/ollama4j/models/response/ListModelsResponse.java similarity index 68% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ListModelsResponse.java rename to src/main/java/io/github/ollama4j/models/response/ListModelsResponse.java index db6f413..62f151b 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ListModelsResponse.java +++ b/src/main/java/io/github/ollama4j/models/response/ListModelsResponse.java @@ -1,6 +1,7 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; import java.util.List; + import lombok.Data; @Data diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/Model.java b/src/main/java/io/github/ollama4j/models/response/Model.java similarity index 87% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/Model.java rename to src/main/java/io/github/ollama4j/models/response/Model.java index 15efd70..e03049e 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/Model.java +++ b/src/main/java/io/github/ollama4j/models/response/Model.java @@ -1,11 +1,10 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; -import java.time.LocalDateTime; import java.time.OffsetDateTime; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.utils.Utils; import lombok.Data; @Data diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelDetail.java b/src/main/java/io/github/ollama4j/models/response/ModelDetail.java similarity index 86% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelDetail.java rename to src/main/java/io/github/ollama4j/models/response/ModelDetail.java index e81a20e..cf7e6bb 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelDetail.java +++ b/src/main/java/io/github/ollama4j/models/response/ModelDetail.java @@ -1,9 +1,9 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.utils.Utils; import lombok.Data; @Data diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelMeta.java b/src/main/java/io/github/ollama4j/models/response/ModelMeta.java similarity index 87% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelMeta.java rename to src/main/java/io/github/ollama4j/models/response/ModelMeta.java index e534832..eb7f176 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelMeta.java +++ b/src/main/java/io/github/ollama4j/models/response/ModelMeta.java @@ -1,9 +1,9 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.utils.Utils; import lombok.Data; @Data diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelPullResponse.java b/src/main/java/io/github/ollama4j/models/response/ModelPullResponse.java similarity index 83% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelPullResponse.java rename to src/main/java/io/github/ollama4j/models/response/ModelPullResponse.java index d9db5c1..dc8349e 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/ModelPullResponse.java +++ b/src/main/java/io/github/ollama4j/models/response/ModelPullResponse.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; diff --git a/src/main/java/io/github/ollama4j/models/response/OllamaAsyncResultStreamer.java b/src/main/java/io/github/ollama4j/models/response/OllamaAsyncResultStreamer.java new file mode 100644 index 0000000..11c726c --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/response/OllamaAsyncResultStreamer.java @@ -0,0 +1,123 @@ +package io.github.ollama4j.models.response; + +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.generate.OllamaGenerateRequest; +import io.github.ollama4j.models.generate.OllamaGenerateResponseModel; +import io.github.ollama4j.utils.Utils; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; + +@Data +@EqualsAndHashCode(callSuper = true) +@SuppressWarnings("unused") +public class OllamaAsyncResultStreamer extends Thread { + private final HttpRequest.Builder requestBuilder; + private final OllamaGenerateRequest ollamaRequestModel; + private final OllamaResultStream stream = new OllamaResultStream(); + private String completeResponse; + + + /** + * -- GETTER -- Returns the status of the request. Indicates if the request was successful or a + * failure. If the request was a failure, the `getResponse()` method will return the error + * message. + */ + @Getter + private boolean succeeded; + + @Setter + private long requestTimeoutSeconds; + + /** + * -- GETTER -- Returns the HTTP response status code for the request that was made to Ollama + * server. + */ + @Getter + private int httpStatusCode; + + /** + * -- GETTER -- Returns the response time in milliseconds. + */ + @Getter + private long responseTime = 0; + + public OllamaAsyncResultStreamer( + HttpRequest.Builder requestBuilder, + OllamaGenerateRequest ollamaRequestModel, + long requestTimeoutSeconds) { + this.requestBuilder = requestBuilder; + this.ollamaRequestModel = ollamaRequestModel; + this.completeResponse = ""; + this.stream.add(""); + this.requestTimeoutSeconds = requestTimeoutSeconds; + } + + @Override + public void run() { + ollamaRequestModel.setStream(true); + HttpClient httpClient = HttpClient.newHttpClient(); + try { + long startTime = System.currentTimeMillis(); + HttpRequest request = + requestBuilder + .POST( + HttpRequest.BodyPublishers.ofString( + Utils.getObjectMapper().writeValueAsString(ollamaRequestModel))) + .header("Content-Type", "application/json") + .timeout(Duration.ofSeconds(requestTimeoutSeconds)) + .build(); + HttpResponse response = + httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); + int statusCode = response.statusCode(); + this.httpStatusCode = statusCode; + + InputStream responseBodyStream = response.body(); + try (BufferedReader reader = + new BufferedReader(new InputStreamReader(responseBodyStream, StandardCharsets.UTF_8))) { + String line; + StringBuilder responseBuffer = new StringBuilder(); + while ((line = reader.readLine()) != null) { + if (statusCode == 404) { + OllamaErrorResponse ollamaResponseModel = + Utils.getObjectMapper().readValue(line, OllamaErrorResponse.class); + stream.add(ollamaResponseModel.getError()); + responseBuffer.append(ollamaResponseModel.getError()); + } else { + OllamaGenerateResponseModel ollamaResponseModel = + Utils.getObjectMapper().readValue(line, OllamaGenerateResponseModel.class); + String res = ollamaResponseModel.getResponse(); + stream.add(res); + if (!ollamaResponseModel.isDone()) { + responseBuffer.append(res); + } + } + } + + this.succeeded = true; + this.completeResponse = responseBuffer.toString(); + long endTime = System.currentTimeMillis(); + responseTime = endTime - startTime; + } + if (statusCode != 200) { + throw new OllamaBaseException(this.completeResponse); + } + } catch (IOException | InterruptedException | OllamaBaseException e) { + this.succeeded = false; + this.completeResponse = "[FAILED] " + e.getMessage(); + } + } + +} + diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaErrorResponseModel.java b/src/main/java/io/github/ollama4j/models/response/OllamaErrorResponse.java similarity index 63% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaErrorResponseModel.java rename to src/main/java/io/github/ollama4j/models/response/OllamaErrorResponse.java index be3d8e4..bbc78c1 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaErrorResponseModel.java +++ b/src/main/java/io/github/ollama4j/models/response/OllamaErrorResponse.java @@ -1,11 +1,11 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @Data @JsonIgnoreProperties(ignoreUnknown = true) -public class OllamaErrorResponseModel { +public class OllamaErrorResponse { private String error; } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaResult.java b/src/main/java/io/github/ollama4j/models/response/OllamaResult.java similarity index 88% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaResult.java rename to src/main/java/io/github/ollama4j/models/response/OllamaResult.java index 1276f5f..beb01ec 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/models/OllamaResult.java +++ b/src/main/java/io/github/ollama4j/models/response/OllamaResult.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.models; +package io.github.ollama4j.models.response; -import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper; +import static io.github.ollama4j.utils.Utils.getObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; diff --git a/src/main/java/io/github/ollama4j/models/response/OllamaResultStream.java b/src/main/java/io/github/ollama4j/models/response/OllamaResultStream.java new file mode 100644 index 0000000..de44d63 --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/response/OllamaResultStream.java @@ -0,0 +1,18 @@ +package io.github.ollama4j.models.response; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Queue; + +public class OllamaResultStream extends LinkedList implements Queue { + @Override + public String poll() { + StringBuilder tokens = new StringBuilder(); + Iterator iterator = this.listIterator(); + while (iterator.hasNext()) { + tokens.append(iterator.next()); + iterator.remove(); + } + return tokens.toString(); + } +} diff --git a/src/main/java/io/github/ollama4j/tools/OllamaToolsResult.java b/src/main/java/io/github/ollama4j/tools/OllamaToolsResult.java new file mode 100644 index 0000000..c855bd2 --- /dev/null +++ b/src/main/java/io/github/ollama4j/tools/OllamaToolsResult.java @@ -0,0 +1,35 @@ +package io.github.ollama4j.tools; + +import io.github.ollama4j.models.response.OllamaResult; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OllamaToolsResult { + private OllamaResult modelResult; + private Map toolResults; + + public List getToolResults() { + List results = new ArrayList<>(); + for (Map.Entry r : this.toolResults.entrySet()) { + results.add(new ToolResult(r.getKey().getName(), r.getKey().getArguments(), r.getValue())); + } + return results; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class ToolResult { + private String functionName; + private Map functionArguments; + private Object result; + } +} diff --git a/src/main/java/io/github/ollama4j/tools/ToolFunction.java b/src/main/java/io/github/ollama4j/tools/ToolFunction.java new file mode 100644 index 0000000..51ab8c5 --- /dev/null +++ b/src/main/java/io/github/ollama4j/tools/ToolFunction.java @@ -0,0 +1,8 @@ +package io.github.ollama4j.tools; + +import java.util.Map; + +@FunctionalInterface +public interface ToolFunction { + Object apply(Map arguments); +} diff --git a/src/main/java/io/github/ollama4j/tools/ToolFunctionCallSpec.java b/src/main/java/io/github/ollama4j/tools/ToolFunctionCallSpec.java new file mode 100644 index 0000000..7a4f7fd --- /dev/null +++ b/src/main/java/io/github/ollama4j/tools/ToolFunctionCallSpec.java @@ -0,0 +1,16 @@ +package io.github.ollama4j.tools; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ToolFunctionCallSpec { + private String name; + private Map arguments; +} + diff --git a/src/main/java/io/github/ollama4j/tools/ToolRegistry.java b/src/main/java/io/github/ollama4j/tools/ToolRegistry.java new file mode 100644 index 0000000..2ead13a --- /dev/null +++ b/src/main/java/io/github/ollama4j/tools/ToolRegistry.java @@ -0,0 +1,16 @@ +package io.github.ollama4j.tools; + +import java.util.HashMap; +import java.util.Map; + +public class ToolRegistry { + private final Map functionMap = new HashMap<>(); + + public ToolFunction getFunction(String name) { + return functionMap.get(name); + } + + public void addFunction(String name, ToolFunction function) { + functionMap.put(name, function); + } +} diff --git a/src/main/java/io/github/ollama4j/tools/Tools.java b/src/main/java/io/github/ollama4j/tools/Tools.java new file mode 100644 index 0000000..986302f --- /dev/null +++ b/src/main/java/io/github/ollama4j/tools/Tools.java @@ -0,0 +1,113 @@ +package io.github.ollama4j.tools; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import io.github.ollama4j.utils.Utils; +import lombok.Builder; +import lombok.Data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Tools { + @Data + @Builder + public static class ToolSpecification { + private String functionName; + private String functionDescription; + private Map properties; + private ToolFunction toolDefinition; + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + public static class PromptFuncDefinition { + private String type; + private PromptFuncSpec function; + + @Data + public static class PromptFuncSpec { + private String name; + private String description; + private Parameters parameters; + } + + @Data + public static class Parameters { + private String type; + private Map properties; + private List required; + } + + @Data + @Builder + public static class Property { + private String type; + private String description; + @JsonProperty("enum") + @JsonInclude(JsonInclude.Include.NON_NULL) + private List enumValues; + @JsonIgnore + private boolean required; + } + } + + public static class PropsBuilder { + private final Map props = new HashMap<>(); + + public PropsBuilder withProperty(String key, PromptFuncDefinition.Property property) { + props.put(key, property); + return this; + } + + public Map build() { + return props; + } + } + + public static class PromptBuilder { + private final List tools = new ArrayList<>(); + + private String promptText; + + public String build() throws JsonProcessingException { + return "[AVAILABLE_TOOLS] " + Utils.getObjectMapper().writeValueAsString(tools) + "[/AVAILABLE_TOOLS][INST] " + promptText + " [/INST]"; + } + + public PromptBuilder withPrompt(String prompt) throws JsonProcessingException { + promptText = prompt; + return this; + } + + public PromptBuilder withToolSpecification(ToolSpecification spec) { + PromptFuncDefinition def = new PromptFuncDefinition(); + def.setType("function"); + + PromptFuncDefinition.PromptFuncSpec functionDetail = new PromptFuncDefinition.PromptFuncSpec(); + functionDetail.setName(spec.getFunctionName()); + functionDetail.setDescription(spec.getFunctionDescription()); + + PromptFuncDefinition.Parameters parameters = new PromptFuncDefinition.Parameters(); + parameters.setType("object"); + parameters.setProperties(spec.getProperties()); + + List requiredValues = new ArrayList<>(); + for (Map.Entry p : spec.getProperties().entrySet()) { + if (p.getValue().isRequired()) { + requiredValues.add(p.getKey()); + } + } + parameters.setRequired(requiredValues); + functionDetail.setParameters(parameters); + def.setFunction(functionDetail); + + tools.add(def); + return this; + } + } +} diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/types/OllamaModelType.java b/src/main/java/io/github/ollama4j/types/OllamaModelType.java similarity index 95% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/types/OllamaModelType.java rename to src/main/java/io/github/ollama4j/types/OllamaModelType.java index d7984d0..dc7b447 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/types/OllamaModelType.java +++ b/src/main/java/io/github/ollama4j/types/OllamaModelType.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.types; +package io.github.ollama4j.types; /** * A class to provide constants for all the supported models by Ollama. @@ -9,6 +9,9 @@ package io.github.amithkoujalgi.ollama4j.core.types; @SuppressWarnings("ALL") public class OllamaModelType { public static final String GEMMA = "gemma"; + public static final String GEMMA2 = "gemma2"; + + public static final String LLAMA2 = "llama2"; public static final String LLAMA3 = "llama3"; public static final String MISTRAL = "mistral"; @@ -30,6 +33,8 @@ public class OllamaModelType { public static final String ZEPHYR = "zephyr"; public static final String OPENHERMES = "openhermes"; public static final String QWEN = "qwen"; + + public static final String QWEN2 = "qwen2"; public static final String WIZARDCODER = "wizardcoder"; public static final String LLAMA2_CHINESE = "llama2-chinese"; public static final String TINYLLAMA = "tinyllama"; @@ -79,4 +84,5 @@ public class OllamaModelType { public static final String NOTUS = "notus"; public static final String DUCKDB_NSQL = "duckdb-nsql"; public static final String ALL_MINILM = "all-minilm"; + public static final String CODESTRAL = "codestral"; } diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/BooleanToJsonFormatFlagSerializer.java b/src/main/java/io/github/ollama4j/utils/BooleanToJsonFormatFlagSerializer.java similarity index 91% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/BooleanToJsonFormatFlagSerializer.java rename to src/main/java/io/github/ollama4j/utils/BooleanToJsonFormatFlagSerializer.java index f4d4ab3..a94e4d1 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/BooleanToJsonFormatFlagSerializer.java +++ b/src/main/java/io/github/ollama4j/utils/BooleanToJsonFormatFlagSerializer.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.io.IOException; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/FileToBase64Serializer.java b/src/main/java/io/github/ollama4j/utils/FileToBase64Serializer.java similarity index 92% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/FileToBase64Serializer.java rename to src/main/java/io/github/ollama4j/utils/FileToBase64Serializer.java index 8e862ab..235ebde 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/FileToBase64Serializer.java +++ b/src/main/java/io/github/ollama4j/utils/FileToBase64Serializer.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.io.IOException; import java.util.Base64; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OllamaRequestBody.java b/src/main/java/io/github/ollama4j/utils/OllamaRequestBody.java similarity index 94% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OllamaRequestBody.java rename to src/main/java/io/github/ollama4j/utils/OllamaRequestBody.java index f787cee..5a2dfab 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OllamaRequestBody.java +++ b/src/main/java/io/github/ollama4j/utils/OllamaRequestBody.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpRequest.BodyPublishers; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Options.java b/src/main/java/io/github/ollama4j/utils/Options.java similarity index 75% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Options.java rename to src/main/java/io/github/ollama4j/utils/Options.java index 2339969..c6e5e53 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Options.java +++ b/src/main/java/io/github/ollama4j/utils/Options.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.util.Map; import lombok.Data; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OptionsBuilder.java b/src/main/java/io/github/ollama4j/utils/OptionsBuilder.java similarity index 99% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OptionsBuilder.java rename to src/main/java/io/github/ollama4j/utils/OptionsBuilder.java index d605f81..c71818a 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/OptionsBuilder.java +++ b/src/main/java/io/github/ollama4j/utils/OptionsBuilder.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.util.HashMap; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/PromptBuilder.java b/src/main/java/io/github/ollama4j/utils/PromptBuilder.java similarity index 97% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/PromptBuilder.java rename to src/main/java/io/github/ollama4j/utils/PromptBuilder.java index be487d9..bb24ef8 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/PromptBuilder.java +++ b/src/main/java/io/github/ollama4j/utils/PromptBuilder.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; /** * The {@code PromptBuilder} class is used to construct prompt texts for language models (LLMs). It diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/SamplePrompts.java b/src/main/java/io/github/ollama4j/utils/SamplePrompts.java similarity index 88% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/SamplePrompts.java rename to src/main/java/io/github/ollama4j/utils/SamplePrompts.java index 1e5dfdc..89a7f83 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/SamplePrompts.java +++ b/src/main/java/io/github/ollama4j/utils/SamplePrompts.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; -import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; +import io.github.ollama4j.OllamaAPI; import java.io.InputStream; import java.util.Scanner; diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Utils.java b/src/main/java/io/github/ollama4j/utils/Utils.java similarity index 95% rename from src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Utils.java rename to src/main/java/io/github/ollama4j/utils/Utils.java index 96b07ae..d854df1 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/utils/Utils.java +++ b/src/main/java/io/github/ollama4j/utils/Utils.java @@ -1,4 +1,4 @@ -package io.github.amithkoujalgi.ollama4j.core.utils; +package io.github.ollama4j.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java b/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java deleted file mode 100644 index d822077..0000000 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java +++ /dev/null @@ -1,393 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.integrationtests; - -import static org.junit.jupiter.api.Assertions.*; - -import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.ModelDetail; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessageRole; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatResult; -import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestModel; -import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestBuilder; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.ConnectException; -import java.net.URISyntaxException; -import java.net.http.HttpConnectTimeoutException; -import java.util.List; -import java.util.Objects; -import java.util.Properties; -import lombok.Data; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class TestRealAPIs { - - private static final Logger LOG = LoggerFactory.getLogger(TestRealAPIs.class); - - OllamaAPI ollamaAPI; - Config config; - - private File getImageFileFromClasspath(String fileName) { - ClassLoader classLoader = getClass().getClassLoader(); - return new File(Objects.requireNonNull(classLoader.getResource(fileName)).getFile()); - } - - @BeforeEach - void setUp() { - config = new Config(); - ollamaAPI = new OllamaAPI(config.getOllamaURL()); - ollamaAPI.setRequestTimeoutSeconds(config.getRequestTimeoutSeconds()); - } - - @Test - @Order(1) - void testWrongEndpoint() { - OllamaAPI ollamaAPI = new OllamaAPI("http://wrong-host:11434"); - assertThrows(ConnectException.class, ollamaAPI::listModels); - } - - @Test - @Order(1) - void testEndpointReachability() { - try { - assertNotNull(ollamaAPI.listModels()); - } catch (HttpConnectTimeoutException e) { - fail(e.getMessage()); - } catch (Exception e) { - fail(e); - } - } - - @Test - @Order(2) - void testListModels() { - testEndpointReachability(); - try { - assertNotNull(ollamaAPI.listModels()); - ollamaAPI.listModels().forEach(System.out::println); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - fail(e); - } - } - - @Test - @Order(2) - void testPullModel() { - testEndpointReachability(); - try { - ollamaAPI.pullModel(config.getModel()); - boolean found = - ollamaAPI.listModels().stream() - .anyMatch(model -> model.getModel().equalsIgnoreCase(config.getModel())); - assertTrue(found); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - fail(e); - } - } - - @Test - @Order(3) - void testListDtails() { - testEndpointReachability(); - try { - ModelDetail modelDetails = ollamaAPI.getModelDetails(config.getModel()); - assertNotNull(modelDetails); - System.out.println(modelDetails); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithDefaultOptions() { - testEndpointReachability(); - try { - OllamaResult result = - ollamaAPI.generate( - config.getModel(), - "What is the capital of France? And what's France's connection with Mona Lisa?", - new OptionsBuilder().build()); - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithDefaultOptionsStreamed() { - testEndpointReachability(); - try { - - StringBuffer sb = new StringBuffer(""); - - OllamaResult result = ollamaAPI.generate(config.getModel(), - "What is the capital of France? And what's France's connection with Mona Lisa?", - new OptionsBuilder().build(), (s) -> { - LOG.info(s); - String substring = s.substring(sb.toString().length(), s.length()); - LOG.info(substring); - sb.append(substring); - }); - - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - assertEquals(sb.toString().trim(), result.getResponse().trim()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithOptions() { - testEndpointReachability(); - try { - OllamaResult result = - ollamaAPI.generate( - config.getModel(), - "What is the capital of France? And what's France's connection with Mona Lisa?", - new OptionsBuilder().setTemperature(0.9f).build()); - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testChat() { - testEndpointReachability(); - try { - OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); - OllamaChatRequestModel requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?") - .withMessage(OllamaChatMessageRole.ASSISTANT, "Should be Paris!") - .withMessage(OllamaChatMessageRole.USER,"And what is the second larges city?") - .build(); - - OllamaChatResult chatResult = ollamaAPI.chat(requestModel); - assertNotNull(chatResult); - assertFalse(chatResult.getResponse().isBlank()); - assertEquals(4,chatResult.getChatHistory().size()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testChatWithSystemPrompt() { - testEndpointReachability(); - try { - OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); - OllamaChatRequestModel requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM, - "You are a silent bot that only says 'NI'. Do not say anything else under any circumstances!") - .withMessage(OllamaChatMessageRole.USER, - "What is the capital of France? And what's France's connection with Mona Lisa?") - .build(); - - OllamaChatResult chatResult = ollamaAPI.chat(requestModel); - assertNotNull(chatResult); - assertFalse(chatResult.getResponse().isBlank()); - assertTrue(chatResult.getResponse().startsWith("NI")); - assertEquals(3, chatResult.getChatHistory().size()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testChatWithStream() { - testEndpointReachability(); - try { - OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); - OllamaChatRequestModel requestModel = builder.withMessage(OllamaChatMessageRole.USER, - "What is the capital of France? And what's France's connection with Mona Lisa?") - .build(); - - StringBuffer sb = new StringBuffer(""); - - OllamaChatResult chatResult = ollamaAPI.chat(requestModel,(s) -> { - LOG.info(s); - String substring = s.substring(sb.toString().length(), s.length()); - LOG.info(substring); - sb.append(substring); - }); - assertNotNull(chatResult); - assertEquals(sb.toString().trim(), chatResult.getResponse().trim()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testChatWithImageFromFileWithHistoryRecognition() { - testEndpointReachability(); - try { - OllamaChatRequestBuilder builder = - OllamaChatRequestBuilder.getInstance(config.getImageModel()); - OllamaChatRequestModel requestModel = - builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?", - List.of(getImageFileFromClasspath("dog-on-a-boat.jpg"))).build(); - - OllamaChatResult chatResult = ollamaAPI.chat(requestModel); - assertNotNull(chatResult); - assertNotNull(chatResult.getResponse()); - - builder.reset(); - - requestModel = - builder.withMessages(chatResult.getChatHistory()) - .withMessage(OllamaChatMessageRole.USER, "What's the dogs breed?").build(); - - chatResult = ollamaAPI.chat(requestModel); - assertNotNull(chatResult); - assertNotNull(chatResult.getResponse()); - - - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testChatWithImageFromURL() { - testEndpointReachability(); - try { - OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getImageModel()); - OllamaChatRequestModel requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?", - "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg") - .build(); - - OllamaChatResult chatResult = ollamaAPI.chat(requestModel); - assertNotNull(chatResult); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithOptionsAndImageFiles() { - testEndpointReachability(); - File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg"); - try { - OllamaResult result = - ollamaAPI.generateWithImageFiles( - config.getImageModel(), - "What is in this image?", - List.of(imageFile), - new OptionsBuilder().build()); - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithOptionsAndImageFilesStreamed() { - testEndpointReachability(); - File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg"); - try { - StringBuffer sb = new StringBuffer(""); - - OllamaResult result = ollamaAPI.generateWithImageFiles(config.getImageModel(), - "What is in this image?", List.of(imageFile), new OptionsBuilder().build(), (s) -> { - LOG.info(s); - String substring = s.substring(sb.toString().length(), s.length()); - LOG.info(substring); - sb.append(substring); - }); - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - assertEquals(sb.toString().trim(), result.getResponse().trim()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } - - @Test - @Order(3) - void testAskModelWithOptionsAndImageURLs() { - testEndpointReachability(); - try { - OllamaResult result = - ollamaAPI.generateWithImageURLs( - config.getImageModel(), - "What is in this image?", - List.of( - "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"), - new OptionsBuilder().build()); - assertNotNull(result); - assertNotNull(result.getResponse()); - assertFalse(result.getResponse().isEmpty()); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - fail(e); - } - } - - @Test - @Order(3) - public void testEmbedding() { - testEndpointReachability(); - try { - OllamaEmbeddingsRequestModel request = OllamaEmbeddingsRequestBuilder - .getInstance(config.getModel(), "What is the capital of France?").build(); - - List embeddings = ollamaAPI.generateEmbeddings(request); - - assertNotNull(embeddings); - assertFalse(embeddings.isEmpty()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - fail(e); - } - } -} - -@Data -class Config { - private String ollamaURL; - private String model; - private String imageModel; - private int requestTimeoutSeconds; - - public Config() { - Properties properties = new Properties(); - try (InputStream input = - getClass().getClassLoader().getResourceAsStream("test-config.properties")) { - if (input == null) { - throw new RuntimeException("Sorry, unable to find test-config.properties"); - } - properties.load(input); - this.ollamaURL = properties.getProperty("ollama.url"); - this.model = properties.getProperty("ollama.model"); - this.imageModel = properties.getProperty("ollama.model.image"); - this.requestTimeoutSeconds = - Integer.parseInt(properties.getProperty("ollama.request-timeout-seconds")); - } catch (IOException e) { - throw new RuntimeException("Error loading properties", e); - } - } -} diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java b/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java deleted file mode 100644 index 879c67c..0000000 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java +++ /dev/null @@ -1,163 +0,0 @@ -package io.github.amithkoujalgi.ollama4j.unittests; - -import static org.mockito.Mockito.*; - -import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; -import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; -import io.github.amithkoujalgi.ollama4j.core.models.ModelDetail; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaAsyncResultCallback; -import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; -import io.github.amithkoujalgi.ollama4j.core.types.OllamaModelType; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class TestMockedAPIs { - @Test - void testPullModel() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - try { - doNothing().when(ollamaAPI).pullModel(model); - ollamaAPI.pullModel(model); - verify(ollamaAPI, times(1)).pullModel(model); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testListModels() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - try { - when(ollamaAPI.listModels()).thenReturn(new ArrayList<>()); - ollamaAPI.listModels(); - verify(ollamaAPI, times(1)).listModels(); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testCreateModel() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String modelFilePath = "FROM llama2\nSYSTEM You are mario from Super Mario Bros."; - try { - doNothing().when(ollamaAPI).createModelWithModelFileContents(model, modelFilePath); - ollamaAPI.createModelWithModelFileContents(model, modelFilePath); - verify(ollamaAPI, times(1)).createModelWithModelFileContents(model, modelFilePath); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testDeleteModel() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - try { - doNothing().when(ollamaAPI).deleteModel(model, true); - ollamaAPI.deleteModel(model, true); - verify(ollamaAPI, times(1)).deleteModel(model, true); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testGetModelDetails() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - try { - when(ollamaAPI.getModelDetails(model)).thenReturn(new ModelDetail()); - ollamaAPI.getModelDetails(model); - verify(ollamaAPI, times(1)).getModelDetails(model); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testGenerateEmbeddings() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String prompt = "some prompt text"; - try { - when(ollamaAPI.generateEmbeddings(model, prompt)).thenReturn(new ArrayList<>()); - ollamaAPI.generateEmbeddings(model, prompt); - verify(ollamaAPI, times(1)).generateEmbeddings(model, prompt); - } catch (IOException | OllamaBaseException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @Test - void testAsk() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String prompt = "some prompt text"; - OptionsBuilder optionsBuilder = new OptionsBuilder(); - try { - when(ollamaAPI.generate(model, prompt, optionsBuilder.build())) - .thenReturn(new OllamaResult("", 0, 200)); - ollamaAPI.generate(model, prompt, optionsBuilder.build()); - verify(ollamaAPI, times(1)).generate(model, prompt, optionsBuilder.build()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @Test - void testAskWithImageFiles() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String prompt = "some prompt text"; - try { - when(ollamaAPI.generateWithImageFiles( - model, prompt, Collections.emptyList(), new OptionsBuilder().build())) - .thenReturn(new OllamaResult("", 0, 200)); - ollamaAPI.generateWithImageFiles( - model, prompt, Collections.emptyList(), new OptionsBuilder().build()); - verify(ollamaAPI, times(1)) - .generateWithImageFiles( - model, prompt, Collections.emptyList(), new OptionsBuilder().build()); - } catch (IOException | OllamaBaseException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @Test - void testAskWithImageURLs() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String prompt = "some prompt text"; - try { - when(ollamaAPI.generateWithImageURLs( - model, prompt, Collections.emptyList(), new OptionsBuilder().build())) - .thenReturn(new OllamaResult("", 0, 200)); - ollamaAPI.generateWithImageURLs( - model, prompt, Collections.emptyList(), new OptionsBuilder().build()); - verify(ollamaAPI, times(1)) - .generateWithImageURLs( - model, prompt, Collections.emptyList(), new OptionsBuilder().build()); - } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - - @Test - void testAskAsync() { - OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); - String model = OllamaModelType.LLAMA2; - String prompt = "some prompt text"; - when(ollamaAPI.generateAsync(model, prompt)) - .thenReturn(new OllamaAsyncResultCallback(null, null, 3)); - ollamaAPI.generateAsync(model, prompt); - verify(ollamaAPI, times(1)).generateAsync(model, prompt); - } -} diff --git a/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java b/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java new file mode 100644 index 0000000..d584747 --- /dev/null +++ b/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java @@ -0,0 +1,395 @@ +package io.github.ollama4j.integrationtests; + +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.response.ModelDetail; +import io.github.ollama4j.models.chat.OllamaChatRequest; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.models.chat.OllamaChatMessageRole; +import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; +import io.github.ollama4j.models.chat.OllamaChatResult; +import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestBuilder; +import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel; +import io.github.ollama4j.utils.OptionsBuilder; +import lombok.Data; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.ConnectException; +import java.net.URISyntaxException; +import java.net.http.HttpConnectTimeoutException; +import java.util.List; +import java.util.Objects; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.*; + +class TestRealAPIs { + + private static final Logger LOG = LoggerFactory.getLogger(TestRealAPIs.class); + + OllamaAPI ollamaAPI; + Config config; + + private File getImageFileFromClasspath(String fileName) { + ClassLoader classLoader = getClass().getClassLoader(); + return new File(Objects.requireNonNull(classLoader.getResource(fileName)).getFile()); + } + + @BeforeEach + void setUp() { + config = new Config(); + ollamaAPI = new OllamaAPI(config.getOllamaURL()); + ollamaAPI.setRequestTimeoutSeconds(config.getRequestTimeoutSeconds()); + } + + @Test + @Order(1) + void testWrongEndpoint() { + OllamaAPI ollamaAPI = new OllamaAPI("http://wrong-host:11434"); + assertThrows(ConnectException.class, ollamaAPI::listModels); + } + + @Test + @Order(1) + void testEndpointReachability() { + try { + assertNotNull(ollamaAPI.listModels()); + } catch (HttpConnectTimeoutException e) { + fail(e.getMessage()); + } catch (Exception e) { + fail(e); + } + } + + @Test + @Order(2) + void testListModels() { + testEndpointReachability(); + try { + assertNotNull(ollamaAPI.listModels()); + ollamaAPI.listModels().forEach(System.out::println); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + fail(e); + } + } + + @Test + @Order(2) + void testPullModel() { + testEndpointReachability(); + try { + ollamaAPI.pullModel(config.getModel()); + boolean found = + ollamaAPI.listModels().stream() + .anyMatch(model -> model.getModel().equalsIgnoreCase(config.getModel())); + assertTrue(found); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + fail(e); + } + } + + @Test + @Order(3) + void testListDtails() { + testEndpointReachability(); + try { + ModelDetail modelDetails = ollamaAPI.getModelDetails(config.getModel()); + assertNotNull(modelDetails); + System.out.println(modelDetails); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithDefaultOptions() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.generate( + config.getModel(), + "What is the capital of France? And what's France's connection with Mona Lisa?", + false, + new OptionsBuilder().build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithDefaultOptionsStreamed() { + testEndpointReachability(); + try { + StringBuffer sb = new StringBuffer(""); + OllamaResult result = ollamaAPI.generate(config.getModel(), + "What is the capital of France? And what's France's connection with Mona Lisa?", + false, + new OptionsBuilder().build(), (s) -> { + LOG.info(s); + String substring = s.substring(sb.toString().length(), s.length()); + LOG.info(substring); + sb.append(substring); + }); + + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + assertEquals(sb.toString().trim(), result.getResponse().trim()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptions() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.generate( + config.getModel(), + "What is the capital of France? And what's France's connection with Mona Lisa?", + true, + new OptionsBuilder().setTemperature(0.9f).build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testChat() { + testEndpointReachability(); + try { + OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?") + .withMessage(OllamaChatMessageRole.ASSISTANT, "Should be Paris!") + .withMessage(OllamaChatMessageRole.USER, "And what is the second larges city?") + .build(); + + OllamaChatResult chatResult = ollamaAPI.chat(requestModel); + assertNotNull(chatResult); + assertFalse(chatResult.getResponse().isBlank()); + assertEquals(4, chatResult.getChatHistory().size()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testChatWithSystemPrompt() { + testEndpointReachability(); + try { + OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM, + "You are a silent bot that only says 'NI'. Do not say anything else under any circumstances!") + .withMessage(OllamaChatMessageRole.USER, + "What is the capital of France? And what's France's connection with Mona Lisa?") + .build(); + + OllamaChatResult chatResult = ollamaAPI.chat(requestModel); + assertNotNull(chatResult); + assertFalse(chatResult.getResponse().isBlank()); + assertTrue(chatResult.getResponse().startsWith("NI")); + assertEquals(3, chatResult.getChatHistory().size()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testChatWithStream() { + testEndpointReachability(); + try { + OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel()); + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, + "What is the capital of France? And what's France's connection with Mona Lisa?") + .build(); + + StringBuffer sb = new StringBuffer(""); + + OllamaChatResult chatResult = ollamaAPI.chat(requestModel, (s) -> { + LOG.info(s); + String substring = s.substring(sb.toString().length(), s.length()); + LOG.info(substring); + sb.append(substring); + }); + assertNotNull(chatResult); + assertEquals(sb.toString().trim(), chatResult.getResponse().trim()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testChatWithImageFromFileWithHistoryRecognition() { + testEndpointReachability(); + try { + OllamaChatRequestBuilder builder = + OllamaChatRequestBuilder.getInstance(config.getImageModel()); + OllamaChatRequest requestModel = + builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?", + List.of(getImageFileFromClasspath("dog-on-a-boat.jpg"))).build(); + + OllamaChatResult chatResult = ollamaAPI.chat(requestModel); + assertNotNull(chatResult); + assertNotNull(chatResult.getResponse()); + + builder.reset(); + + requestModel = + builder.withMessages(chatResult.getChatHistory()) + .withMessage(OllamaChatMessageRole.USER, "What's the dogs breed?").build(); + + chatResult = ollamaAPI.chat(requestModel); + assertNotNull(chatResult); + assertNotNull(chatResult.getResponse()); + + + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testChatWithImageFromURL() { + testEndpointReachability(); + try { + OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getImageModel()); + OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?", + "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg") + .build(); + + OllamaChatResult chatResult = ollamaAPI.chat(requestModel); + assertNotNull(chatResult); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptionsAndImageFiles() { + testEndpointReachability(); + File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg"); + try { + OllamaResult result = + ollamaAPI.generateWithImageFiles( + config.getImageModel(), + "What is in this image?", + List.of(imageFile), + new OptionsBuilder().build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptionsAndImageFilesStreamed() { + testEndpointReachability(); + File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg"); + try { + StringBuffer sb = new StringBuffer(""); + + OllamaResult result = ollamaAPI.generateWithImageFiles(config.getImageModel(), + "What is in this image?", List.of(imageFile), new OptionsBuilder().build(), (s) -> { + LOG.info(s); + String substring = s.substring(sb.toString().length(), s.length()); + LOG.info(substring); + sb.append(substring); + }); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + assertEquals(sb.toString().trim(), result.getResponse().trim()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptionsAndImageURLs() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.generateWithImageURLs( + config.getImageModel(), + "What is in this image?", + List.of( + "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"), + new OptionsBuilder().build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + fail(e); + } + } + + @Test + @Order(3) + public void testEmbedding() { + testEndpointReachability(); + try { + OllamaEmbeddingsRequestModel request = OllamaEmbeddingsRequestBuilder + .getInstance(config.getModel(), "What is the capital of France?").build(); + + List embeddings = ollamaAPI.generateEmbeddings(request); + + assertNotNull(embeddings); + assertFalse(embeddings.isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + fail(e); + } + } +} + +@Data +class Config { + private String ollamaURL; + private String model; + private String imageModel; + private int requestTimeoutSeconds; + + public Config() { + Properties properties = new Properties(); + try (InputStream input = + getClass().getClassLoader().getResourceAsStream("test-config.properties")) { + if (input == null) { + throw new RuntimeException("Sorry, unable to find test-config.properties"); + } + properties.load(input); + this.ollamaURL = properties.getProperty("ollama.url"); + this.model = properties.getProperty("ollama.model"); + this.imageModel = properties.getProperty("ollama.model.image"); + this.requestTimeoutSeconds = + Integer.parseInt(properties.getProperty("ollama.request-timeout-seconds")); + } catch (IOException e) { + throw new RuntimeException("Error loading properties", e); + } + } +} diff --git a/src/test/java/io/github/ollama4j/unittests/TestMockedAPIs.java b/src/test/java/io/github/ollama4j/unittests/TestMockedAPIs.java new file mode 100644 index 0000000..921ccf7 --- /dev/null +++ b/src/test/java/io/github/ollama4j/unittests/TestMockedAPIs.java @@ -0,0 +1,164 @@ +package io.github.ollama4j.unittests; + +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.exceptions.OllamaBaseException; +import io.github.ollama4j.models.response.ModelDetail; +import io.github.ollama4j.models.response.OllamaAsyncResultStreamer; +import io.github.ollama4j.models.response.OllamaResult; +import io.github.ollama4j.types.OllamaModelType; +import io.github.ollama4j.utils.OptionsBuilder; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; + +import static org.mockito.Mockito.*; + +class TestMockedAPIs { + @Test + void testPullModel() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + try { + doNothing().when(ollamaAPI).pullModel(model); + ollamaAPI.pullModel(model); + verify(ollamaAPI, times(1)).pullModel(model); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testListModels() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + try { + when(ollamaAPI.listModels()).thenReturn(new ArrayList<>()); + ollamaAPI.listModels(); + verify(ollamaAPI, times(1)).listModels(); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testCreateModel() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String modelFilePath = "FROM llama2\nSYSTEM You are mario from Super Mario Bros."; + try { + doNothing().when(ollamaAPI).createModelWithModelFileContents(model, modelFilePath); + ollamaAPI.createModelWithModelFileContents(model, modelFilePath); + verify(ollamaAPI, times(1)).createModelWithModelFileContents(model, modelFilePath); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testDeleteModel() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + try { + doNothing().when(ollamaAPI).deleteModel(model, true); + ollamaAPI.deleteModel(model, true); + verify(ollamaAPI, times(1)).deleteModel(model, true); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testGetModelDetails() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + try { + when(ollamaAPI.getModelDetails(model)).thenReturn(new ModelDetail()); + ollamaAPI.getModelDetails(model); + verify(ollamaAPI, times(1)).getModelDetails(model); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testGenerateEmbeddings() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String prompt = "some prompt text"; + try { + when(ollamaAPI.generateEmbeddings(model, prompt)).thenReturn(new ArrayList<>()); + ollamaAPI.generateEmbeddings(model, prompt); + verify(ollamaAPI, times(1)).generateEmbeddings(model, prompt); + } catch (IOException | OllamaBaseException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + void testAsk() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String prompt = "some prompt text"; + OptionsBuilder optionsBuilder = new OptionsBuilder(); + try { + when(ollamaAPI.generate(model, prompt, false, optionsBuilder.build())) + .thenReturn(new OllamaResult("", 0, 200)); + ollamaAPI.generate(model, prompt, false, optionsBuilder.build()); + verify(ollamaAPI, times(1)).generate(model, prompt, false, optionsBuilder.build()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + void testAskWithImageFiles() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String prompt = "some prompt text"; + try { + when(ollamaAPI.generateWithImageFiles( + model, prompt, Collections.emptyList(), new OptionsBuilder().build())) + .thenReturn(new OllamaResult("", 0, 200)); + ollamaAPI.generateWithImageFiles( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + verify(ollamaAPI, times(1)) + .generateWithImageFiles( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + void testAskWithImageURLs() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String prompt = "some prompt text"; + try { + when(ollamaAPI.generateWithImageURLs( + model, prompt, Collections.emptyList(), new OptionsBuilder().build())) + .thenReturn(new OllamaResult("", 0, 200)); + ollamaAPI.generateWithImageURLs( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + verify(ollamaAPI, times(1)) + .generateWithImageURLs( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Test + void testAskAsync() { + OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class); + String model = OllamaModelType.LLAMA2; + String prompt = "some prompt text"; + when(ollamaAPI.generateAsync(model, prompt, false)) + .thenReturn(new OllamaAsyncResultStreamer(null, null, 3)); + ollamaAPI.generateAsync(model, prompt, false); + verify(ollamaAPI, times(1)).generateAsync(model, prompt, false); + } +} diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/AbstractSerializationTest.java b/src/test/java/io/github/ollama4j/unittests/jackson/AbstractSerializationTest.java similarity index 89% rename from src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/AbstractSerializationTest.java rename to src/test/java/io/github/ollama4j/unittests/jackson/AbstractSerializationTest.java index d0ffc2c..6e03566 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/AbstractSerializationTest.java +++ b/src/test/java/io/github/ollama4j/unittests/jackson/AbstractSerializationTest.java @@ -1,10 +1,10 @@ -package io.github.amithkoujalgi.ollama4j.unittests.jackson; +package io.github.ollama4j.unittests.jackson; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.github.amithkoujalgi.ollama4j.core.utils.Utils; +import io.github.ollama4j.utils.Utils; public abstract class AbstractSerializationTest { diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestChatRequestSerialization.java b/src/test/java/io/github/ollama4j/unittests/jackson/TestChatRequestSerialization.java similarity index 63% rename from src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestChatRequestSerialization.java rename to src/test/java/io/github/ollama4j/unittests/jackson/TestChatRequestSerialization.java index 3ad049c..2391a94 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestChatRequestSerialization.java +++ b/src/test/java/io/github/ollama4j/unittests/jackson/TestChatRequestSerialization.java @@ -1,20 +1,20 @@ -package io.github.amithkoujalgi.ollama4j.unittests.jackson; +package io.github.ollama4j.unittests.jackson; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; import java.util.List; +import io.github.ollama4j.models.chat.OllamaChatRequest; import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessageRole; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder; -import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; +import io.github.ollama4j.models.chat.OllamaChatMessageRole; +import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; +import io.github.ollama4j.utils.OptionsBuilder; -public class TestChatRequestSerialization extends AbstractSerializationTest { +public class TestChatRequestSerialization extends AbstractSerializationTest { private OllamaChatRequestBuilder builder; @@ -25,32 +25,32 @@ public class TestChatRequestSerialization extends AbstractSerializationTest { diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java b/src/test/java/io/github/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java similarity index 68% rename from src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java rename to src/test/java/io/github/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java index 8e95288..4ca0672 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java +++ b/src/test/java/io/github/ollama4j/unittests/jackson/TestGenerateRequestSerialization.java @@ -1,17 +1,17 @@ -package io.github.amithkoujalgi.ollama4j.unittests.jackson; +package io.github.ollama4j.unittests.jackson; import static org.junit.jupiter.api.Assertions.assertEquals; +import io.github.ollama4j.models.generate.OllamaGenerateRequest; import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestBuilder; -import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel; -import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; +import io.github.ollama4j.models.generate.OllamaGenerateRequestBuilder; +import io.github.ollama4j.utils.OptionsBuilder; -public class TestGenerateRequestSerialization extends AbstractSerializationTest { +public class TestGenerateRequestSerialization extends AbstractSerializationTest { private OllamaGenerateRequestBuilder builder; @@ -22,27 +22,27 @@ public class TestGenerateRequestSerialization extends AbstractSerializationTest< @Test public void testRequestOnlyMandatoryFields() { - OllamaGenerateRequestModel req = builder.withPrompt("Some prompt").build(); + OllamaGenerateRequest req = builder.withPrompt("Some prompt").build(); String jsonRequest = serialize(req); - assertEqualsAfterUnmarshalling(deserialize(jsonRequest, OllamaGenerateRequestModel.class), req); + assertEqualsAfterUnmarshalling(deserialize(jsonRequest, OllamaGenerateRequest.class), req); } @Test public void testRequestWithOptions() { OptionsBuilder b = new OptionsBuilder(); - OllamaGenerateRequestModel req = + OllamaGenerateRequest req = builder.withPrompt("Some prompt").withOptions(b.setMirostat(1).build()).build(); String jsonRequest = serialize(req); - OllamaGenerateRequestModel deserializeRequest = deserialize(jsonRequest, OllamaGenerateRequestModel.class); + OllamaGenerateRequest deserializeRequest = deserialize(jsonRequest, OllamaGenerateRequest.class); assertEqualsAfterUnmarshalling(deserializeRequest, req); assertEquals(1, deserializeRequest.getOptions().get("mirostat")); } @Test public void testWithJsonFormat() { - OllamaGenerateRequestModel req = + OllamaGenerateRequest req = builder.withPrompt("Some prompt").withGetJsonResponse().build(); String jsonRequest = serialize(req); diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestModelRequestSerialization.java b/src/test/java/io/github/ollama4j/unittests/jackson/TestModelRequestSerialization.java similarity index 93% rename from src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestModelRequestSerialization.java rename to src/test/java/io/github/ollama4j/unittests/jackson/TestModelRequestSerialization.java index 712e507..5bc44f3 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/jackson/TestModelRequestSerialization.java +++ b/src/test/java/io/github/ollama4j/unittests/jackson/TestModelRequestSerialization.java @@ -1,6 +1,6 @@ -package io.github.amithkoujalgi.ollama4j.unittests.jackson; +package io.github.ollama4j.unittests.jackson; -import io.github.amithkoujalgi.ollama4j.core.models.Model; +import io.github.ollama4j.models.response.Model; import org.junit.jupiter.api.Test; public class TestModelRequestSerialization extends AbstractSerializationTest {