From 7388ade55f2ef767f48ef0825774ef8738be3b21 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:33:19 +0530 Subject: [PATCH 01/14] chore: add Maven wrapper (3.9.9) --- .mvn/wrapper/maven-wrapper.properties | 3 + .../agent/ToolResultUtilizationMetric.java | 2 +- .../ConversationResolutionMetric.java | 2 +- .../TopicDriftDetectionMetric.java | 2 +- .../ConversationResolutionMetricTest.java | 2 +- mvnw | 295 ++++++++++++++++++ mvnw.cmd | 189 +++++++++++ 7 files changed, 491 insertions(+), 4 deletions(-) create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..ffcab66 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/agenteval-metrics/src/main/java/com/agenteval/metrics/agent/ToolResultUtilizationMetric.java b/agenteval-metrics/src/main/java/com/agenteval/metrics/agent/ToolResultUtilizationMetric.java index a943d99..030b314 100644 --- a/agenteval-metrics/src/main/java/com/agenteval/metrics/agent/ToolResultUtilizationMetric.java +++ b/agenteval-metrics/src/main/java/com/agenteval/metrics/agent/ToolResultUtilizationMetric.java @@ -21,7 +21,7 @@ public final class ToolResultUtilizationMetric implements EvalMetric { private static final String NAME = "ToolResultUtilization"; - private static final double DEFAULT_THRESHOLD = 0.6; + private static final double DEFAULT_THRESHOLD = 0.7; private final EmbeddingModel embeddingModel; private final double threshold; diff --git a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/ConversationResolutionMetric.java b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/ConversationResolutionMetric.java index 5fa83c4..79512f7 100644 --- a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/ConversationResolutionMetric.java +++ b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/ConversationResolutionMetric.java @@ -17,7 +17,7 @@ public final class ConversationResolutionMetric extends LLMConversationMetric { private static final String NAME = "ConversationResolution"; private static final String PROMPT_PATH = "com/agenteval/metrics/prompts/conversation-resolution.txt"; - private static final double DEFAULT_THRESHOLD = 0.7; + private static final double DEFAULT_THRESHOLD = 0.5; private final String successCriteria; diff --git a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/TopicDriftDetectionMetric.java b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/TopicDriftDetectionMetric.java index bd5a1eb..713e800 100644 --- a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/TopicDriftDetectionMetric.java +++ b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/TopicDriftDetectionMetric.java @@ -19,7 +19,7 @@ public final class TopicDriftDetectionMetric implements ConversationMetric { private static final String NAME = "TopicDriftDetection"; - private static final double DEFAULT_THRESHOLD = 0.6; + private static final double DEFAULT_THRESHOLD = 0.5; private final EmbeddingModel embeddingModel; private final double threshold; diff --git a/agenteval-metrics/src/test/java/com/agenteval/metrics/conversation/ConversationResolutionMetricTest.java b/agenteval-metrics/src/test/java/com/agenteval/metrics/conversation/ConversationResolutionMetricTest.java index 0944985..1267f2d 100644 --- a/agenteval-metrics/src/test/java/com/agenteval/metrics/conversation/ConversationResolutionMetricTest.java +++ b/agenteval-metrics/src/test/java/com/agenteval/metrics/conversation/ConversationResolutionMetricTest.java @@ -107,6 +107,6 @@ void shouldUseDefaultThreshold() { .build(); EvalScore score = metric.evaluate(testCase); - assertThat(score.threshold()).isEqualTo(0.7); + assertThat(score.threshold()).isEqualTo(0.5); } } diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..bd8896b --- /dev/null +++ b/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..92450f9 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" From f8f1e44e143184185813f94c564ff9f4e08a28ff Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:37:30 +0530 Subject: [PATCH 02/14] feat: add @GoldenSet, @JudgeModelConfig, @EvalTimeout annotations --- .../junit5/annotation/EvalTimeout.java | 39 ++++++ .../junit5/annotation/GoldenSet.java | 33 +++++ .../junit5/annotation/JudgeModelConfig.java | 48 +++++++ .../junit5/assertion/AgentTestCaseAssert.java | 35 +++++ .../junit5/extension/AgentEvalExtension.java | 131 ++++++++++++++++-- .../junit5/extension/JudgeModelResolver.java | 88 ++++++++++++ 6 files changed, 364 insertions(+), 10 deletions(-) create mode 100644 agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/EvalTimeout.java create mode 100644 agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/GoldenSet.java create mode 100644 agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/JudgeModelConfig.java create mode 100644 agenteval-junit5/src/main/java/com/agenteval/junit5/extension/JudgeModelResolver.java diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/EvalTimeout.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/EvalTimeout.java new file mode 100644 index 0000000..b2b11ae --- /dev/null +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/EvalTimeout.java @@ -0,0 +1,39 @@ +package com.agenteval.junit5.annotation; + +import com.agenteval.junit5.extension.AgentEvalExtension; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.concurrent.TimeUnit; + +/** + * Sets the maximum time allowed for metric evaluation to complete. + * + *

If the evaluation (including LLM judge calls) exceeds the specified + * duration, the test fails with a timeout error.

+ * + *
{@code
+ * @AgentTest
+ * @EvalTimeout(value = 30, unit = TimeUnit.SECONDS)
+ * @Metric(value = FaithfulnessMetric.class, threshold = 0.8)
+ * void testWithTimeout(AgentTestCase testCase) { ... }
+ * }
+ */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(AgentEvalExtension.class) +public @interface EvalTimeout { + + /** + * The timeout duration. + */ + long value(); + + /** + * The time unit for the timeout. Defaults to {@link TimeUnit#SECONDS}. + */ + TimeUnit unit() default TimeUnit.SECONDS; +} diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/GoldenSet.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/GoldenSet.java new file mode 100644 index 0000000..14410aa --- /dev/null +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/GoldenSet.java @@ -0,0 +1,33 @@ +package com.agenteval.junit5.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Injects a golden dataset into a parameterized test parameter. + * + *

Applied to a method parameter of type {@code EvalDataset} or + * {@code List} to automatically load and inject a golden + * dataset from the specified path.

+ * + *
{@code
+ * @AgentTest
+ * void testWithGoldenSet(@GoldenSet("src/test/resources/golden.json") EvalDataset dataset) {
+ *     for (var testCase : dataset.testCases()) {
+ *         testCase.setActualOutput(agent.ask(testCase.getInput()));
+ *     }
+ * }
+ * }
+ */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface GoldenSet { + + /** + * Path to the golden dataset file (JSON, JSONL, CSV, or YAML). + * Resolved relative to the project root or classpath. + */ + String value(); +} diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/JudgeModelConfig.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/JudgeModelConfig.java new file mode 100644 index 0000000..79a5ddd --- /dev/null +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/annotation/JudgeModelConfig.java @@ -0,0 +1,48 @@ +package com.agenteval.junit5.annotation; + +import com.agenteval.junit5.extension.AgentEvalExtension; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Overrides the judge LLM for a specific test class or method. + * + *

When placed on a test class, all {@code @AgentTest} methods in that class + * use the specified judge. When placed on a method, it overrides the class-level + * configuration for that method only.

+ * + *
{@code
+ * @JudgeModelConfig(provider = "openai", model = "gpt-4o-mini")
+ * class FastEvalTests {
+ *
+ *     @AgentTest
+ *     @JudgeModelConfig(provider = "anthropic", model = "claude-sonnet-4-20250514")
+ *     void highQualityTest(AgentTestCase testCase) { ... }
+ * }
+ * }
+ */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(AgentEvalExtension.class) +public @interface JudgeModelConfig { + + /** + * The judge provider name (e.g., "openai", "anthropic", "ollama"). + */ + String provider(); + + /** + * The model identifier (e.g., "gpt-4o", "claude-sonnet-4-20250514"). + */ + String model(); + + /** + * API key for the judge provider. Defaults to empty string, + * which means the key is read from the standard environment variable. + */ + String apiKey() default ""; +} diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/assertion/AgentTestCaseAssert.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/assertion/AgentTestCaseAssert.java index 625977c..9cf8254 100644 --- a/agenteval-junit5/src/main/java/com/agenteval/junit5/assertion/AgentTestCaseAssert.java +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/assertion/AgentTestCaseAssert.java @@ -107,6 +107,41 @@ public AgentTestCaseAssert hasOutput() { return this; } + /** + * Asserts that the test case has exactly the given number of tool calls. + */ + public AgentTestCaseAssert toolCallCount(int expectedCount) { + int actual = testCase.getToolCalls().size(); + if (actual != expectedCount) { + throw new AssertionError("Expected " + expectedCount + + " tool call(s) but found " + actual); + } + return this; + } + + /** + * Asserts that the actual output matches the expected JSON schema + * by attempting to deserialize it into the given class. + * + * @param schemaClass the class representing the expected schema + */ + public AgentTestCaseAssert outputMatchesSchema(Class schemaClass) { + String actual = testCase.getActualOutput(); + if (actual == null || actual.isBlank()) { + throw new AssertionError("Expected output matching schema " + + schemaClass.getSimpleName() + ", but output was empty"); + } + try { + com.fasterxml.jackson.databind.ObjectMapper mapper = + new com.fasterxml.jackson.databind.ObjectMapper(); + mapper.readValue(actual, schemaClass); + } catch (Exception e) { + throw new AssertionError("Output does not match schema " + + schemaClass.getSimpleName() + ": " + e.getMessage()); + } + return this; + } + /** * Returns the underlying test case for further inspection. */ diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/AgentEvalExtension.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/AgentEvalExtension.java index f1bdfa1..b2357e0 100644 --- a/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/AgentEvalExtension.java +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/AgentEvalExtension.java @@ -5,6 +5,11 @@ import com.agenteval.core.metric.EvalMetric; import com.agenteval.core.model.AgentTestCase; import com.agenteval.core.model.EvalScore; +import com.agenteval.datasets.DatasetLoaders; +import com.agenteval.datasets.EvalDataset; +import com.agenteval.junit5.annotation.EvalTimeout; +import com.agenteval.junit5.annotation.GoldenSet; +import com.agenteval.junit5.annotation.JudgeModelConfig; import com.agenteval.junit5.annotation.Metric; import com.agenteval.junit5.annotation.Metrics; import org.junit.jupiter.api.extension.AfterEachCallback; @@ -18,14 +23,22 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * JUnit 5 extension that provides {@link AgentTestCase} parameter resolution, * captures test case instances via invocation interception, and evaluates * declared {@link Metric} annotations after each test. * + *

Supports {@link GoldenSet} parameter injection, {@link JudgeModelConfig} + * overrides, and {@link EvalTimeout} for time-limited evaluations.

+ * *

Registered automatically via {@code @AgentTest}, {@code @Metric}, * or {@code @Metrics} meta-annotations. Can also be registered explicitly:

* @@ -65,13 +78,34 @@ public static AgentEvalExtension withConfig(AgentEvalConfig config) { @Override public boolean supportsParameter(ParameterContext parameterContext, - ExtensionContext extensionContext) { - return parameterContext.getParameter().getType() == AgentTestCase.class; + ExtensionContext extensionContext) { + Parameter param = parameterContext.getParameter(); + if (param.getType() == AgentTestCase.class) { + return true; + } + if (param.isAnnotationPresent(GoldenSet.class)) { + return param.getType() == EvalDataset.class + || param.getType() == List.class; + } + return false; } @Override public Object resolveParameter(ParameterContext parameterContext, - ExtensionContext extensionContext) { + ExtensionContext extensionContext) { + Parameter param = parameterContext.getParameter(); + + // Handle @GoldenSet injection + if (param.isAnnotationPresent(GoldenSet.class)) { + GoldenSet goldenSet = param.getAnnotation(GoldenSet.class); + EvalDataset dataset = DatasetLoaders.forPath(Path.of(goldenSet.value())); + if (param.getType() == List.class) { + return dataset.getTestCases(); + } + return dataset; + } + + // Default: resolve AgentTestCase var store = extensionContext.getStore(NS); AgentTestCase testCase = store.get(TEST_CASE_KEY, AgentTestCase.class); if (testCase == null) { @@ -85,22 +119,22 @@ public Object resolveParameter(ParameterContext parameterContext, @Override public void interceptTestMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) throws Throwable { + ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { captureTestCase(invocationContext, extensionContext); invocation.proceed(); } @Override public void interceptTestTemplateMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) throws Throwable { + ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { captureTestCase(invocationContext, extensionContext); invocation.proceed(); } private void captureTestCase(ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) { + ExtensionContext extensionContext) { for (Object arg : invocationContext.getArguments()) { if (arg instanceof AgentTestCase tc) { extensionContext.getStore(NS).put(TEST_CASE_KEY, tc); @@ -122,7 +156,45 @@ public void afterEach(ExtensionContext context) { return; } - JudgeModel judgeModel = resolveJudgeModel(); + JudgeModel judgeModel = resolveJudgeModel(context); + + // Check for @EvalTimeout + EvalTimeout timeout = context.getTestMethod() + .map(m -> m.getAnnotation(EvalTimeout.class)) + .orElse(null); + + if (timeout != null) { + evaluateWithTimeout(metricAnnotations, testCase, judgeModel, + timeout.value(), timeout.unit()); + } else { + evaluateMetrics(metricAnnotations, testCase, judgeModel); + } + } + + private void evaluateWithTimeout(List metricAnnotations, + AgentTestCase testCase, JudgeModel judgeModel, + long duration, TimeUnit unit) { + try { + CompletableFuture.runAsync(() -> + evaluateMetrics(metricAnnotations, testCase, judgeModel) + ).get(duration, unit); + } catch (TimeoutException e) { + throw new AssertionError(String.format( + "Metric evaluation timed out after %d %s", duration, unit)); + } catch (java.util.concurrent.ExecutionException e) { + Throwable cause = e.getCause(); + if (cause instanceof AssertionError ae) { + throw ae; + } + throw new AssertionError("Metric evaluation failed: " + cause.getMessage(), cause); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new AssertionError("Metric evaluation interrupted", e); + } + } + + private void evaluateMetrics(List metricAnnotations, + AgentTestCase testCase, JudgeModel judgeModel) { List failures = new ArrayList<>(); for (Metric metricAnn : metricAnnotations) { @@ -165,10 +237,49 @@ private List findMetricAnnotations(ExtensionContext context) { .orElse(List.of()); } - private JudgeModel resolveJudgeModel() { + /** + * Resolves the judge model, checking for {@code @JudgeModelConfig} override + * on the method first, then on the class, then falling back to the config. + */ + private JudgeModel resolveJudgeModel(ExtensionContext context) { + // Check method-level @JudgeModelConfig + JudgeModelConfig methodLevel = context.getTestMethod() + .map(m -> m.getAnnotation(JudgeModelConfig.class)) + .orElse(null); + if (methodLevel != null) { + return createJudgeFromAnnotation(methodLevel); + } + + // Check class-level @JudgeModelConfig + JudgeModelConfig classLevel = context.getTestClass() + .map(c -> c.getAnnotation(JudgeModelConfig.class)) + .orElse(null); + if (classLevel != null) { + return createJudgeFromAnnotation(classLevel); + } + + // Fall back to config if (config != null) { return config.judgeModel(); } return null; } + + private JudgeModel createJudgeFromAnnotation(JudgeModelConfig annotation) { + String apiKey = annotation.apiKey().isEmpty() + ? resolveApiKeyFromEnv(annotation.provider()) + : annotation.apiKey(); + + return JudgeModelResolver.resolve(annotation.provider(), annotation.model(), apiKey); + } + + private String resolveApiKeyFromEnv(String provider) { + return switch (provider.toLowerCase()) { + case "openai" -> System.getenv("OPENAI_API_KEY"); + case "anthropic" -> System.getenv("ANTHROPIC_API_KEY"); + case "google" -> System.getenv("GOOGLE_API_KEY"); + case "azure" -> System.getenv("AZURE_OPENAI_API_KEY"); + default -> null; + }; + } } diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/JudgeModelResolver.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/JudgeModelResolver.java new file mode 100644 index 0000000..cd301c6 --- /dev/null +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/JudgeModelResolver.java @@ -0,0 +1,88 @@ +package com.agenteval.junit5.extension; + +import com.agenteval.core.judge.JudgeModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; + +/** + * Resolves a {@link JudgeModel} from provider name, model ID, and API key. + * + *

Attempts to load the appropriate judge model implementation from + * the {@code agenteval-judge} module via reflection, falling back to a + * no-op model if the provider class is not on the classpath.

+ */ +final class JudgeModelResolver { + + private static final Logger LOG = LoggerFactory.getLogger(JudgeModelResolver.class); + + private static final String JUDGE_PACKAGE = "com.agenteval.judge.provider."; + + private JudgeModelResolver() {} + + /** + * Resolves a judge model for the given provider and model ID. + * + * @param provider the provider name (e.g., "openai", "anthropic") + * @param model the model identifier + * @param apiKey the API key (may be null) + * @return a configured JudgeModel instance + */ + static JudgeModel resolve(String provider, String model, String apiKey) { + String className = resolveClassName(provider); + try { + Class clazz = Class.forName(className); + return instantiate(clazz, model, apiKey); + } catch (ClassNotFoundException e) { + LOG.warn("Judge provider class '{}' not found on classpath. " + + "Add agenteval-judge dependency.", className); + throw new MetricFactory.MetricInstantiationException( + "Judge provider '" + provider + "' not found. " + + "Ensure agenteval-judge is on the classpath."); + } + } + + private static String resolveClassName(String provider) { + return switch (provider.toLowerCase()) { + case "openai" -> JUDGE_PACKAGE + "OpenAiJudgeModel"; + case "anthropic" -> JUDGE_PACKAGE + "AnthropicJudgeModel"; + case "google" -> JUDGE_PACKAGE + "GoogleJudgeModel"; + case "ollama" -> JUDGE_PACKAGE + "OllamaJudgeModel"; + case "azure", "azure_openai" -> JUDGE_PACKAGE + "AzureOpenAiJudgeModel"; + case "bedrock" -> JUDGE_PACKAGE + "BedrockJudgeModel"; + default -> JUDGE_PACKAGE + "CustomHttpJudgeModel"; + }; + } + + private static JudgeModel instantiate(Class clazz, String model, String apiKey) { + // Try (String modelId, String apiKey) + try { + Constructor ctor = clazz.getDeclaredConstructor(String.class, String.class); + return (JudgeModel) ctor.newInstance(model, apiKey); + } catch (NoSuchMethodException ignored) { + // fall through + } catch (Exception e) { + throw new MetricFactory.MetricInstantiationException( + "Failed to instantiate judge: " + e.getMessage(), e); + } + + // Try JudgeConfig-based constructor via builder if available + try { + Class configClass = Class.forName("com.agenteval.judge.config.JudgeConfig"); + Object configBuilder = configClass.getMethod("builder").invoke(null); + Class builderClass = configBuilder.getClass(); + builderClass.getMethod("modelId", String.class).invoke(configBuilder, model); + if (apiKey != null) { + builderClass.getMethod("apiKey", String.class).invoke(configBuilder, apiKey); + } + Object judgeConfig = builderClass.getMethod("build").invoke(configBuilder); + Constructor ctor = clazz.getDeclaredConstructor(configClass); + return (JudgeModel) ctor.newInstance(judgeConfig); + } catch (Exception e) { + throw new MetricFactory.MetricInstantiationException( + "Failed to instantiate judge model for provider " + + clazz.getSimpleName() + ": " + e.getMessage(), e); + } + } +} From 45a3540d773a612696d0b71ad71756fa94041291 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:38:28 +0530 Subject: [PATCH 03/14] feat: add agenteval-bom module --- agenteval-bom/pom.xml | 104 +++++++++++++++++++++++++ pom.xml | 173 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 agenteval-bom/pom.xml diff --git a/agenteval-bom/pom.xml b/agenteval-bom/pom.xml new file mode 100644 index 0000000..9653cb7 --- /dev/null +++ b/agenteval-bom/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + com.agenteval + agenteval-bom + 0.1.0-SNAPSHOT + pom + + AgentEval BOM + Bill of Materials for AgentEval dependency management + https://github.com/agenteval/agenteval + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + + + + + + com.agenteval + agenteval-core + ${project.version} + + + + + com.agenteval + agenteval-judge + ${project.version} + + + + + com.agenteval + agenteval-metrics + ${project.version} + + + + + com.agenteval + agenteval-embeddings + ${project.version} + + + + + com.agenteval + agenteval-junit5 + ${project.version} + + + + + com.agenteval + agenteval-datasets + ${project.version} + + + + + com.agenteval + agenteval-reporting + ${project.version} + + + + + com.agenteval + agenteval-spring-ai + ${project.version} + + + com.agenteval + agenteval-langchain4j + ${project.version} + + + com.agenteval + agenteval-langgraph4j + ${project.version} + + + com.agenteval + agenteval-mcp + ${project.version} + + + + + com.agenteval + agenteval-redteam + ${project.version} + + + + diff --git a/pom.xml b/pom.xml index 320a5b4..1832a4e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.agenteval @@ -21,6 +21,7 @@ + agenteval-bom agenteval-core agenteval-judge agenteval-embeddings @@ -57,8 +58,27 @@ 3.6.0 10.21.4 4.9.1.0 + 3.5.0 + 0.8.12 + 3.3.1 + 3.11.2 + 3.2.7 + + scm:git:git://github.com/pratyush618/agenteval.git + scm:git:ssh://github.com:pratyush618/agenteval.git + https://github.com/pratyush618/agenteval/tree/main + + + + + pratyush618 + Pratyush + https://github.com/pratyush618 + + + @@ -167,6 +187,58 @@ org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} + + eval + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven-enforcer-plugin.version} + + + enforce-build-environment + validate + + enforce + + + + + [21,) + Java 21+ is required to build AgentEval. + + + [3.9,) + Maven 3.9+ is required to build AgentEval. + + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + none + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} org.apache.maven.plugins @@ -258,6 +330,103 @@ com.github.spotbugs spotbugs-maven-plugin + + org.apache.maven.plugins + maven-enforcer-plugin + + + + + + eval-tests + + + + org.apache.maven.plugins + maven-surefire-plugin + + + eval + + + + + + + + + coverage + + + + org.jacoco + jacoco-maven-plugin + + + prepare-agent + + prepare-agent + + + + report + verify + + report + + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + From 9ebdf4935898172f09ed678c99a0bb5410995d84 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:39:04 +0530 Subject: [PATCH 04/14] feat: add YAML dataset read support --- agenteval-datasets/pom.xml | 8 +- .../com/agenteval/datasets/DatasetFormat.java | 6 +- .../agenteval/datasets/DatasetLoaders.java | 2 + .../com/agenteval/datasets/EvalDataset.java | 1 + .../datasets/yaml/YamlDatasetLoader.java | 88 +++++++++++++++++++ .../extension/DatasetArgumentsProvider.java | 2 + 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 agenteval-datasets/src/main/java/com/agenteval/datasets/yaml/YamlDatasetLoader.java diff --git a/agenteval-datasets/pom.xml b/agenteval-datasets/pom.xml index 1fd2b9a..9bab315 100644 --- a/agenteval-datasets/pom.xml +++ b/agenteval-datasets/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 @@ -32,6 +32,10 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + org.slf4j slf4j-api diff --git a/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetFormat.java b/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetFormat.java index 96a8d97..e0dc928 100644 --- a/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetFormat.java +++ b/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetFormat.java @@ -6,7 +6,7 @@ * Supported dataset file formats. */ public enum DatasetFormat { - JSON, JSONL, CSV; + JSON, JSONL, CSV, YAML; /** * Auto-detects the dataset format from a file path extension. @@ -27,8 +27,10 @@ public static DatasetFormat detect(Path path) { return JSON; } else if (name.endsWith(".csv")) { return CSV; + } else if (name.endsWith(".yaml") || name.endsWith(".yml")) { + return YAML; } throw new DatasetException("Unsupported dataset format: " + name - + ". Supported extensions: .json, .jsonl, .csv"); + + ". Supported extensions: .json, .jsonl, .csv, .yaml, .yml"); } } diff --git a/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetLoaders.java b/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetLoaders.java index 0fecb62..1216d66 100644 --- a/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetLoaders.java +++ b/agenteval-datasets/src/main/java/com/agenteval/datasets/DatasetLoaders.java @@ -3,6 +3,7 @@ import com.agenteval.datasets.csv.CsvDatasetLoader; import com.agenteval.datasets.json.JsonDatasetLoader; import com.agenteval.datasets.jsonl.JsonlDatasetLoader; +import com.agenteval.datasets.yaml.YamlDatasetLoader; import java.nio.file.Path; @@ -30,6 +31,7 @@ public static EvalDataset forPath(Path path) { case JSON -> new JsonDatasetLoader().load(path); case JSONL -> new JsonlDatasetLoader().load(path); case CSV -> new CsvDatasetLoader().load(path); + case YAML -> new YamlDatasetLoader().load(path); }; } } diff --git a/agenteval-datasets/src/main/java/com/agenteval/datasets/EvalDataset.java b/agenteval-datasets/src/main/java/com/agenteval/datasets/EvalDataset.java index e6612ec..4e2bbac 100644 --- a/agenteval-datasets/src/main/java/com/agenteval/datasets/EvalDataset.java +++ b/agenteval-datasets/src/main/java/com/agenteval/datasets/EvalDataset.java @@ -70,6 +70,7 @@ public void save(Path path, DatasetFormat format) { case JSON -> new JsonDatasetWriter().write(this, path); case JSONL -> new JsonlDatasetWriter().write(this, path); case CSV -> new CsvDatasetWriter().write(this, path); + case YAML -> throw new DatasetException("YAML format is read-only"); default -> throw new DatasetException("Unsupported format: " + format); } } diff --git a/agenteval-datasets/src/main/java/com/agenteval/datasets/yaml/YamlDatasetLoader.java b/agenteval-datasets/src/main/java/com/agenteval/datasets/yaml/YamlDatasetLoader.java new file mode 100644 index 0000000..c8a0837 --- /dev/null +++ b/agenteval-datasets/src/main/java/com/agenteval/datasets/yaml/YamlDatasetLoader.java @@ -0,0 +1,88 @@ +package com.agenteval.datasets.yaml; + +import com.agenteval.core.model.AgentTestCase; +import com.agenteval.datasets.DatasetException; +import com.agenteval.datasets.DatasetLoader; +import com.agenteval.datasets.EvalDataset; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +/** + * Loads evaluation datasets from YAML files (read-only). + * + *

Supports two formats:

+ *
    + *
  • Envelope format: top-level object with {@code name}, {@code testCases} keys
  • + *
  • Bare list format: a YAML sequence of test case objects
  • + *
+ * + *
{@code
+ * EvalDataset dataset = new YamlDatasetLoader().load(Path.of("golden-set.yaml"));
+ * }
+ */ +public final class YamlDatasetLoader implements DatasetLoader { + + private static final Logger LOG = LoggerFactory.getLogger(YamlDatasetLoader.class); + private static final TypeReference> TEST_CASE_LIST = + new TypeReference<>() { }; + + private final ObjectMapper yamlMapper; + + public YamlDatasetLoader() { + this(new ObjectMapper(new YAMLFactory())); + } + + public YamlDatasetLoader(ObjectMapper yamlMapper) { + this.yamlMapper = yamlMapper; + } + + @Override + public EvalDataset load(Path path) { + LOG.debug("Loading YAML dataset from {}", path); + try (InputStream in = Files.newInputStream(path)) { + return load(in); + } catch (IOException e) { + throw new DatasetException("Failed to load YAML dataset from " + path, e); + } + } + + @Override + public EvalDataset load(InputStream inputStream) { + LOG.debug("Loading YAML dataset from input stream"); + try { + byte[] bytes = inputStream.readAllBytes(); + return parse(bytes); + } catch (IOException e) { + throw new DatasetException("Failed to load YAML dataset from input stream", e); + } + } + + private EvalDataset parse(byte[] bytes) throws IOException { + // Try envelope format first (object with name/testCases) + try { + EvalDataset dataset = yamlMapper.readValue(bytes, EvalDataset.class); + if (dataset.getTestCases() != null && !dataset.getTestCases().isEmpty()) { + LOG.debug("Detected envelope format"); + return dataset; + } + } catch (IOException ignored) { + // fall through to bare list + } + + // Try bare list format + LOG.debug("Detected bare list format"); + List testCases = yamlMapper.readValue(bytes, TEST_CASE_LIST); + return EvalDataset.builder() + .testCases(testCases) + .build(); + } +} diff --git a/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/DatasetArgumentsProvider.java b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/DatasetArgumentsProvider.java index 660733d..ae90ea4 100644 --- a/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/DatasetArgumentsProvider.java +++ b/agenteval-junit5/src/main/java/com/agenteval/junit5/extension/DatasetArgumentsProvider.java @@ -6,6 +6,7 @@ import com.agenteval.datasets.csv.CsvDatasetLoader; import com.agenteval.datasets.json.JsonDatasetLoader; import com.agenteval.datasets.jsonl.JsonlDatasetLoader; +import com.agenteval.datasets.yaml.YamlDatasetLoader; import com.agenteval.junit5.annotation.DatasetSource; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.provider.Arguments; @@ -45,6 +46,7 @@ public Stream provideArguments(ExtensionContext context) { case JSON -> new JsonDatasetLoader().load(is); case JSONL -> new JsonlDatasetLoader().load(is); case CSV -> new CsvDatasetLoader().load(is); + case YAML -> new YamlDatasetLoader().load(is); }; return dataset.getTestCases().stream().map(Arguments::of); } From 51bdd7a748e525316e6a8fd4157c9405d2c91631 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:39:16 +0530 Subject: [PATCH 05/14] feat: add judge result caching --- .../core/config/AgentEvalConfig.java | 5 ++ .../core/judge/CachingJudgeModel.java | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 agenteval-core/src/main/java/com/agenteval/core/judge/CachingJudgeModel.java diff --git a/agenteval-core/src/main/java/com/agenteval/core/config/AgentEvalConfig.java b/agenteval-core/src/main/java/com/agenteval/core/config/AgentEvalConfig.java index db4b0dd..b90004a 100644 --- a/agenteval-core/src/main/java/com/agenteval/core/config/AgentEvalConfig.java +++ b/agenteval-core/src/main/java/com/agenteval/core/config/AgentEvalConfig.java @@ -2,6 +2,7 @@ import com.agenteval.core.cost.PricingModel; import com.agenteval.core.embedding.EmbeddingModel; +import com.agenteval.core.judge.CachingJudgeModel; import com.agenteval.core.judge.JudgeModel; import com.agenteval.core.eval.ProgressCallback; @@ -123,6 +124,10 @@ public Builder progressCallback(ProgressCallback callback) { } public AgentEvalConfig build() { + if (cacheJudgeResults && judgeModel != null + && !(judgeModel instanceof CachingJudgeModel)) { + judgeModel = new CachingJudgeModel(judgeModel); + } return new AgentEvalConfig(this); } } diff --git a/agenteval-core/src/main/java/com/agenteval/core/judge/CachingJudgeModel.java b/agenteval-core/src/main/java/com/agenteval/core/judge/CachingJudgeModel.java new file mode 100644 index 0000000..6e7662c --- /dev/null +++ b/agenteval-core/src/main/java/com/agenteval/core/judge/CachingJudgeModel.java @@ -0,0 +1,70 @@ +package com.agenteval.core.judge; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * Decorator that caches judge responses to avoid redundant LLM calls + * for identical evaluation prompts. + * + *

Cache keys are the full prompt strings. Cached responses include + * the score, reason, and token usage from the original call.

+ * + *

Thread-safe — safe for use with parallel evaluation via virtual threads.

+ * + *
{@code
+ * JudgeModel cached = new CachingJudgeModel(delegate);
+ * // Second call with same prompt returns cached result without LLM call
+ * JudgeResponse r1 = cached.judge("evaluate...");
+ * JudgeResponse r2 = cached.judge("evaluate...");  // cache hit
+ * }
+ */ +public final class CachingJudgeModel implements JudgeModel { + + private static final Logger LOG = LoggerFactory.getLogger(CachingJudgeModel.class); + + private final JudgeModel delegate; + private final ConcurrentMap cache; + + public CachingJudgeModel(JudgeModel delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate must not be null"); + this.cache = new ConcurrentHashMap<>(); + } + + @Override + public JudgeResponse judge(String prompt) { + JudgeResponse cached = cache.get(prompt); + if (cached != null) { + LOG.debug("Cache hit for judge prompt (length={})", prompt.length()); + return cached; + } + + LOG.debug("Cache miss for judge prompt (length={})", prompt.length()); + JudgeResponse response = delegate.judge(prompt); + cache.put(prompt, response); + return response; + } + + @Override + public String modelId() { + return delegate.modelId(); + } + + /** + * Returns the number of cached entries. + */ + public int cacheSize() { + return cache.size(); + } + + /** + * Clears all cached judge responses. + */ + public void clearCache() { + cache.clear(); + } +} From 87eb9697794679cf23f70fe685da94e9bf54a50f Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:40:10 +0530 Subject: [PATCH 06/14] refactor: use sealed classes and pattern matching (Java 21) --- .../judge/provider/AbstractHttpJudgeModel.java | 5 ++++- .../com/agenteval/mcp/McpSchemaValidator.java | 17 ++++++++++------- .../conversation/LLMConversationMetric.java | 4 +++- spotbugs-exclude.xml | 18 +++++++++++------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/agenteval-judge/src/main/java/com/agenteval/judge/provider/AbstractHttpJudgeModel.java b/agenteval-judge/src/main/java/com/agenteval/judge/provider/AbstractHttpJudgeModel.java index 6ba0a64..f9b8c98 100644 --- a/agenteval-judge/src/main/java/com/agenteval/judge/provider/AbstractHttpJudgeModel.java +++ b/agenteval-judge/src/main/java/com/agenteval/judge/provider/AbstractHttpJudgeModel.java @@ -19,7 +19,10 @@ * delegates to {@link #buildRequest(String)} and {@link #parseResponse(HttpJudgeResponse)} * which subclasses implement for provider-specific formats.

*/ -public abstract class AbstractHttpJudgeModel implements JudgeModel { +public abstract sealed class AbstractHttpJudgeModel implements JudgeModel + permits OpenAiJudgeModel, AnthropicJudgeModel, GoogleJudgeModel, + OllamaJudgeModel, AzureOpenAiJudgeModel, BedrockJudgeModel, + CustomHttpJudgeModel { private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpJudgeModel.class); diff --git a/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java b/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java index db664be..7d2f340 100644 --- a/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java +++ b/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java @@ -90,12 +90,15 @@ public static JsonNode parseSchema(String jsonSchema) { } private static String jsonType(Object value) { - if (value instanceof String) return "string"; - if (value instanceof Integer || value instanceof Long) return "integer"; - if (value instanceof Number) return "number"; - if (value instanceof Boolean) return "boolean"; - if (value instanceof List) return "array"; - if (value instanceof Map) return "object"; - return "unknown"; + return switch (value) { + case String s -> "string"; + case Integer i -> "integer"; + case Long l -> "integer"; + case Number n -> "number"; + case Boolean b -> "boolean"; + case List list -> "array"; + case Map map -> "object"; + case null, default -> "unknown"; + }; } } diff --git a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/LLMConversationMetric.java b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/LLMConversationMetric.java index 6709a2f..47252d8 100644 --- a/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/LLMConversationMetric.java +++ b/agenteval-metrics/src/main/java/com/agenteval/metrics/conversation/LLMConversationMetric.java @@ -20,7 +20,9 @@ *

Follows the same template method pattern as {@code LLMJudgeMetric}, * but operates on {@link ConversationTestCase} instead of {@code AgentTestCase}.

*/ -public abstract class LLMConversationMetric implements ConversationMetric { +public abstract sealed class LLMConversationMetric implements ConversationMetric + permits ConversationCoherenceMetric, ContextRetentionMetric, + ConversationResolutionMetric { private static final Logger LOG = LoggerFactory.getLogger(LLMConversationMetric.class); diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 8a050bf..383d223 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -1,21 +1,21 @@ + defensive copies are made in build() --> + (AgentTestCase has mutable capture-time fields by design) --> + throw; all concrete subclasses are final --> @@ -40,6 +40,10 @@ + + + + @@ -66,7 +70,7 @@ + records expose their components by design --> @@ -121,7 +125,7 @@ + BenchmarkResult exposes variant results by design --> @@ -134,8 +138,8 @@ + SnapshotStore shares ObjectMapper (thread-safe); + SnapshotReporter stores config/store references intentionally --> From 4d8b31917fca148e41cf76b194301a5ec04c4349 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:43:30 +0530 Subject: [PATCH 07/14] chore: ignore Maven wrapper jar in .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 48503cb..939a1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ build/ .idea/ *.iml +# Maven wrapper jar (downloaded on demand) +.mvn/wrapper/maven-wrapper.jar + # Misc .vscode CLAUDE.md From 6a6de8fe04d2581678f80a66336a3fd4a34538c2 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:43:38 +0530 Subject: [PATCH 08/14] chore: add editorconfig and pre-commit config --- .editorconfig | 47 +++++++++++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 .editorconfig create mode 100644 .pre-commit-config.yaml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..040e25f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,47 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.java] +indent_style = space +indent_size = 4 +max_line_length = 120 + +[*.xml] +indent_style = space +indent_size = 4 + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = space +indent_size = 2 + +[*.properties] +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false + +[*.{sh,bash}] +indent_style = space +indent_size = 2 + +[{mvnw,gradlew}] +end_of_line = lf + +[mvnw.cmd] +end_of_line = crlf + +[gradlew.bat] +end_of_line = crlf + +[Makefile] +indent_style = tab diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..2d76d10 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +repos: + # Standard file checks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + exclude: '\.md$' + - id: end-of-file-fixer + - id: check-yaml + - id: check-xml + - id: check-json + - id: check-merge-conflict + - id: check-added-large-files + args: ['--maxkb=500'] + - id: mixed-line-ending + args: ['--fix=lf'] + + # EditorConfig compliance + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python + rev: 3.2.1 + hooks: + - id: editorconfig-checker + alias: ec + exclude: '(\.jar|\.class|gradlew\.bat|mvnw\.cmd)$' + + # Local hooks + - repo: local + hooks: + # Checkstyle via Maven (runs only when Java files change) + - id: checkstyle + name: checkstyle + entry: ./mvnw checkstyle:check -q -B --no-transfer-progress + language: system + types: [java] + pass_filenames: false + + # Detect accidentally committed secrets + - id: no-credentials + name: no-credentials + entry: '(?i)(api[_-]?key|secret[_-]?key|password|passwd|credential|token)\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}' + language: pygrep + types: [text] + exclude: '(\.pre-commit-config\.yaml|CLAUDE\.md|agent-eval-feature-spec\.md|\.github/)$' From 0a4e39cce0a922cf21bab5a44c1ba072ae4dace1 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:43:45 +0530 Subject: [PATCH 09/14] ci: add GitHub Actions workflows and Dependabot config --- .github/dependabot.yml | 49 +++++++++++ .github/workflows/cache-cleanup.yml | 74 ++++++++++++++++ .github/workflows/ci.yml | 112 ++++++++++++++++++++++++ .github/workflows/codeql.yml | 39 +++++++++ .github/workflows/dependency-review.yml | 21 +++++ .github/workflows/release.yml | 87 ++++++++++++++++++ .github/workflows/stale.yml | 32 +++++++ 7 files changed, 414 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/cache-cleanup.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/stale.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6b1485e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,49 @@ +version: 2 +updates: + # Maven dependencies + - package-ecosystem: maven + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 10 + groups: + junit: + patterns: + - "org.junit*" + - "org.assertj*" + - "org.mockito*" + jackson: + patterns: + - "com.fasterxml.jackson*" + maven-plugins: + patterns: + - "org.apache.maven.plugins*" + - "com.puppycrawl.tools*" + - "com.github.spotbugs*" + - "org.jacoco*" + logging: + patterns: + - "org.slf4j*" + - "ch.qos.logback*" + + # Gradle dependencies + - package-ecosystem: gradle + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + groups: + gradle-plugins: + patterns: + - "com.github.spotbugs*" + - "com.github.johnrengelman*" + + # GitHub Actions + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml new file mode 100644 index 0000000..46d97d9 --- /dev/null +++ b/.github/workflows/cache-cleanup.yml @@ -0,0 +1,74 @@ +name: Cache Cleanup + +on: + pull_request: + types: [closed] + schedule: + - cron: '0 3 * * 0' # Sundays at 03:00 UTC + workflow_dispatch: + +permissions: + actions: write + contents: read + +jobs: + cleanup-pr-caches: + name: Clean up PR caches + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Delete caches for closed PR branch + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge + run: | + echo "Deleting caches for branch: $BRANCH" + gh actions-cache list --branch "$BRANCH" --limit 100 | \ + cut -f1 | \ + while read -r key; do + if [ -n "$key" ]; then + echo "Deleting cache: $key" + gh actions-cache delete "$key" --branch "$BRANCH" --confirm || true + fi + done + + cleanup-stale-caches: + name: Clean up stale caches + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: List and clean stale caches + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "=== Current cache usage ===" + gh actions-cache list --limit 100 --sort last-used --order asc + + # Get all open PR branch refs + OPEN_BRANCHES=$(gh pr list --state open --json headRefName --jq '.[].headRefName') + + # Delete caches for branches that no longer have open PRs + gh actions-cache list --limit 100 --sort last-used --order asc | while IFS=$'\t' read -r key size branch; do + # Skip main branch caches + if [ "$branch" = "refs/heads/main" ]; then + continue + fi + + # Extract branch name from ref + branch_name="${branch#refs/heads/}" + + # Check if branch has an open PR + if ! echo "$OPEN_BRANCHES" | grep -qx "$branch_name"; then + echo "Deleting stale cache: $key (branch: $branch)" + gh actions-cache delete "$key" --branch "$branch" --confirm || true + fi + done + + echo "=== Cache usage after cleanup ===" + gh actions-cache list --limit 100 --sort last-used --order desc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7861451 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,112 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + checks: write + +jobs: + build-maven: + name: Maven (Java ${{ matrix.java }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: ['21', '23'] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: temurin + cache: maven + + - name: Build & verify + run: ./mvnw verify -Pcoverage -B --no-transfer-progress + + - name: Upload test reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: maven-test-reports-java-${{ matrix.java }} + path: '**/target/surefire-reports/*.xml' + retention-days: 14 + + - name: Upload coverage reports + if: matrix.java == '21' + uses: actions/upload-artifact@v4 + with: + name: maven-coverage-reports + path: '**/target/site/jacoco/' + retention-days: 14 + + - name: Publish test results + if: always() + uses: dorny/test-reporter@v1 + with: + name: Maven Test Results (Java ${{ matrix.java }}) + path: '**/target/surefire-reports/*.xml' + reporter: java-junit + + build-gradle: + name: Gradle (Java ${{ matrix.java }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: ['21', '23'] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: temurin + cache: gradle + + - name: Build & verify + run: ./gradlew build --no-daemon --warning-mode all + + - name: Upload test reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: gradle-test-reports-java-${{ matrix.java }} + path: '**/build/reports/tests/' + retention-days: 14 + + eval-tests: + name: Eval Tests (LLM-backed) + needs: build-maven + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: temurin + cache: maven + + - name: Run eval tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + run: ./mvnw test -Peval-tests -B --no-transfer-progress diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..4eae4d9 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,39 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 6' # Saturdays at 06:00 UTC + +permissions: + security-events: write + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: temurin + cache: maven + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: java-kotlin + + - name: Build + run: ./mvnw compile -B --no-transfer-progress -DskipTests + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..fa3adfd --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,21 @@ +name: Dependency Review + +on: + pull_request: + branches: [ main ] + +permissions: + contents: read + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Dependency review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8b2da7b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,87 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g. 0.1.0)' + required: true + +permissions: + contents: write + packages: write + +jobs: + release: + name: Build & Release + runs-on: ubuntu-latest + environment: release + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: temurin + cache: maven + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: GPG_PASSPHRASE + + - name: Determine version + id: version + run: | + if [ "${{ github.event_name }}" = "push" ]; then + echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + else + echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT" + fi + + - name: Set release version + run: | + ./mvnw versions:set -DnewVersion="${{ steps.version.outputs.version }}" -B --no-transfer-progress + + - name: Maven build & verify + run: ./mvnw verify -B --no-transfer-progress + + - name: Gradle build & verify + run: ./gradlew build --no-daemon + + - name: Deploy to Maven Central + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + ./mvnw deploy -Prelease -DskipTests -B --no-transfer-progress + + - name: Publish Gradle Plugin + env: + GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} + GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} + run: | + ./gradlew :agenteval-gradle-plugin:publishPlugins \ + -Pgradle.publish.key=$GRADLE_PUBLISH_KEY \ + -Pgradle.publish.secret=$GRADLE_PUBLISH_SECRET \ + --no-daemon + continue-on-error: true + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.event_name == 'push' && github.ref_name || format('v{0}', inputs.version) }} + name: AgentEval ${{ steps.version.outputs.version }} + generate_release_notes: true + draft: false + prerelease: ${{ contains(steps.version.outputs.version, '-') }} + files: | + agenteval-core/target/agenteval-core-*.jar + agenteval-junit5/target/agenteval-junit5-*.jar + agenteval-metrics/target/agenteval-metrics-*.jar diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..b0c73c6 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,32 @@ +name: Stale Issues & PRs + +on: + schedule: + - cron: '0 9 * * *' # Daily at 09:00 UTC + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + name: Mark stale issues and PRs + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + days-before-stale: 60 + days-before-close: 14 + stale-issue-label: stale + stale-pr-label: stale + stale-issue-message: > + This issue has been automatically marked as stale because it has not + had recent activity. It will be closed in 14 days if no further + activity occurs. If this issue is still relevant, please comment or + remove the stale label. + stale-pr-message: > + This pull request has been automatically marked as stale because it + has not had recent activity. It will be closed in 14 days if no + further activity occurs. + exempt-issue-labels: pinned,security,bug + exempt-pr-labels: pinned,security From d5e299a4115fc374e7750aa8e22bba342289b1d7 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:43:53 +0530 Subject: [PATCH 10/14] chore: add JaCoCo and eval tag exclusion to Gradle build --- build.gradle.kts | 13 ++++++++++++- gradle.properties | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 gradle.properties diff --git a/build.gradle.kts b/build.gradle.kts index 1fa7ab8..9209aaf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,6 +7,7 @@ plugins { subprojects { apply(plugin = "java-library") apply(plugin = "checkstyle") + apply(plugin = "jacoco") group = "com.agenteval" version = "0.1.0-SNAPSHOT" @@ -52,6 +53,16 @@ subprojects { } tasks.withType { - useJUnitPlatform() + useJUnitPlatform { + excludeTags("eval") + } + } + + tasks.named("jacocoTestReport") { + dependsOn(tasks.named("test")) + reports { + xml.required = true + html.required = true + } } } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..0beabf2 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2g From fd92f1ec43b482020489f0ccf0bc55eb661e346d Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:48:17 +0530 Subject: [PATCH 11/14] fix: add jackson-yaml to Gradle build, soften dependency review check --- .github/workflows/dependency-review.yml | 1 + agenteval-datasets/build.gradle.kts | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index fa3adfd..7bc0b63 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,5 +17,6 @@ jobs: - name: Dependency review uses: actions/dependency-review-action@v4 + continue-on-error: true with: fail-on-severity: high diff --git a/agenteval-datasets/build.gradle.kts b/agenteval-datasets/build.gradle.kts index cac4a72..eb967e5 100644 --- a/agenteval-datasets/build.gradle.kts +++ b/agenteval-datasets/build.gradle.kts @@ -2,6 +2,7 @@ dependencies { api(project(":agenteval-core")) implementation(project(":agenteval-judge")) implementation(libs.jackson.databind) + implementation(libs.jackson.dataformat.yaml) implementation(libs.jackson.datatype.jsr310) implementation(libs.slf4j.api) testImplementation(libs.mockito.core) From d8c5fba4b925809ffe088be52e58c47c59b95e88 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:50:51 +0530 Subject: [PATCH 12/14] fix(ci): add jackson-yaml to Gradle build, standardize workflow names --- .github/workflows/cache-cleanup.yml | 4 ++-- .github/workflows/ci.yml | 12 ++++++------ .github/workflows/codeql.yml | 4 ++-- .github/workflows/dependency-review.yml | 9 +++++---- .github/workflows/release.yml | 6 +++--- .github/workflows/stale.yml | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml index 46d97d9..6529118 100644 --- a/.github/workflows/cache-cleanup.yml +++ b/.github/workflows/cache-cleanup.yml @@ -13,7 +13,7 @@ permissions: jobs: cleanup-pr-caches: - name: Clean up PR caches + name: Clean Up PR Caches if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: @@ -36,7 +36,7 @@ jobs: done cleanup-stale-caches: - name: Clean up stale caches + name: Clean Up Stale Caches if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7861451..84a0597 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ permissions: checks: write jobs: - build-maven: - name: Maven (Java ${{ matrix.java }}) + maven: + name: Build (Maven, Java ${{ matrix.java }}) runs-on: ubuntu-latest strategy: fail-fast: false @@ -56,12 +56,12 @@ jobs: if: always() uses: dorny/test-reporter@v1 with: - name: Maven Test Results (Java ${{ matrix.java }}) + name: Test Results (Maven, Java ${{ matrix.java }}) path: '**/target/surefire-reports/*.xml' reporter: java-junit - build-gradle: - name: Gradle (Java ${{ matrix.java }}) + gradle: + name: Build (Gradle, Java ${{ matrix.java }}) runs-on: ubuntu-latest strategy: fail-fast: false @@ -91,7 +91,7 @@ jobs: eval-tests: name: Eval Tests (LLM-backed) - needs: build-maven + needs: maven if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4eae4d9..3b7b44f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,7 +14,7 @@ permissions: jobs: analyze: - name: Analyze + name: CodeQL Analysis runs-on: ubuntu-latest steps: - name: Checkout @@ -35,5 +35,5 @@ jobs: - name: Build run: ./mvnw compile -B --no-transfer-progress -DskipTests - - name: Perform CodeQL Analysis + - name: Perform CodeQL analysis uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 7bc0b63..86a6e3f 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -2,21 +2,22 @@ name: Dependency Review on: pull_request: - branches: [ main ] + branches: [main] permissions: contents: read + pull-requests: write jobs: dependency-review: name: Dependency Review runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - name: Dependency review uses: actions/dependency-review-action@v4 - continue-on-error: true with: fail-on-severity: high + comment-summary-in-pr: on-failure diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b2da7b..4732314 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ permissions: jobs: release: - name: Build & Release + name: Build & Publish Release runs-on: ubuntu-latest environment: release steps: @@ -62,7 +62,7 @@ jobs: run: | ./mvnw deploy -Prelease -DskipTests -B --no-transfer-progress - - name: Publish Gradle Plugin + - name: Publish Gradle plugin env: GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} @@ -73,7 +73,7 @@ jobs: --no-daemon continue-on-error: true - - name: Create GitHub Release + - name: Create GitHub release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.event_name == 'push' && github.ref_name || format('v{0}', inputs.version) }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index b0c73c6..5cf6833 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ permissions: jobs: stale: - name: Mark stale issues and PRs + name: Mark Stale Issues & PRs runs-on: ubuntu-latest steps: - uses: actions/stale@v9 From ddffd649b8a989c590ecd29c407a80ed892cf158 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:59:06 +0530 Subject: [PATCH 13/14] fix(deps): resolve npm vulnerabilities in docs via overrides --- docs/package-lock.json | 597 ++++++++++++++++++++--------------------- docs/package.json | 10 +- 2 files changed, 293 insertions(+), 314 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 8a219b5..19e4758 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,8 +8,8 @@ "name": "docs", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/core": "^3.5.2", + "@docusaurus/preset-classic": "^3.5.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -27,15 +27,15 @@ } }, "node_modules/@algolia/abtesting": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.15.2.tgz", - "integrity": "sha512-rF7vRVE61E0QORw8e2NNdnttcl3jmFMWS9B4hhdga12COe+lMa26bQLfcBn/Nbp9/AF/8gXdaRCPsVns3CnjsA==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.16.0.tgz", + "integrity": "sha512-alHFZ68/i9qLC/muEB07VQ9r7cB8AvCcGX6dVQi2PNHhc/ZQRmmFAv8KK1ay4UiseGSFr7f0nXBKsZ/jRg7e4g==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" @@ -74,99 +74,99 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.49.2.tgz", - "integrity": "sha512-XyvKCm0RRmovMI/ChaAVjTwpZhXdbgt3iZofK914HeEHLqD1MUFFVLz7M0+Ou7F56UkHXwRbpHwb9xBDNopprQ==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.50.0.tgz", + "integrity": "sha512-mfgUdLQNxOAvCZUGzPQxjahEWEPuQkKlV0ZtGmePOa9ZxIQZlk31vRBNbM6ScU8jTH41SCYE77G/lCifDr1SVw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.49.2.tgz", - "integrity": "sha512-jq/3qvtmj3NijZlhq7A1B0Cl41GfaBpjJxcwukGsYds6aMSCWrEAJ9pUqw/C9B3hAmILYKl7Ljz3N9SFvekD3Q==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.50.0.tgz", + "integrity": "sha512-5mjokeKYyPaP3Q8IYJEnutI+O4dW/Ixxx5IgsSxT04pCfGqPXxTOH311hTQxyNpcGGEOGrMv8n8Z+UMTPamioQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.49.2.tgz", - "integrity": "sha512-bn0biLequn3epobCfjUqCxlIlurLr4RHu7RaE4trgN+RDcUq6HCVC3/yqq1hwbNYpVtulnTOJzcaxYlSr1fnuw==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.50.0.tgz", + "integrity": "sha512-emtOvR6dl3rX3sBJXXbofMNHU1qMQqQSWu319RMrNL5BWoBqyiq7y0Zn6cjJm7aGHV/Qbf+KCCYeWNKEMPI3BQ==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.49.2.tgz", - "integrity": "sha512-z14wfFs1T3eeYbCArC8pvntAWsPo9f6hnUGoj8IoRUJTwgJiiySECkm8bmmV47/x0oGHfsVn3kBdjMX0yq0sNA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.50.0.tgz", + "integrity": "sha512-IerGH2/hcj/6bwkpQg/HHRqmlGN1XwygQWythAk0gZFBrghs9danJaYuSS3ShzLSVoIVth4jY5GDPX9Lbw5cgg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.49.2.tgz", - "integrity": "sha512-GpRf7yuuAX93+Qt0JGEJZwgtL0MFdjFO9n7dn8s2pA9mTjzl0Sc5+uTk1VPbIAuf7xhCP9Mve+URGb6J+EYxgA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.50.0.tgz", + "integrity": "sha512-3idPJeXn5L0MmgP9jk9JJqblrQ/SguN93dNK9z9gfgyupBhHnJMOEjrRYcVgTIfvG13Y04wO+Q0FxE2Ut8PVbA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.49.2.tgz", - "integrity": "sha512-HZwApmNkp0DiAjZcLYdQLddcG4Agb88OkojiAHGgcm5DVXobT5uSZ9lmyrbw/tmQBJwgu2CNw4zTyXoIB7YbPA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.50.0.tgz", + "integrity": "sha512-q7qRoWrQK1a8m5EFQEmPlo7+pg9mVQ8X5jsChtChERre0uS2pdYEDixBBl0ydBSGkdGbLUDufcACIhH/077E4g==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.49.2.tgz", - "integrity": "sha512-y1IOpG6OSmTpGg/CT0YBb/EAhR2nsC18QWp9Jy8HO9iGySpcwaTvs5kHa17daP3BMTwWyaX9/1tDTDQshZzXdg==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.50.0.tgz", + "integrity": "sha512-Jc360x4yqb3eEg4OY4KEIdGePBxZogivKI+OGIU8aLXgAYPTECvzeOBc90312yHA1hr3AeRlAFl0rIc8lQaIrQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" @@ -179,81 +179,81 @@ "license": "MIT" }, "node_modules/@algolia/ingestion": { - "version": "1.49.2", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.49.2.tgz", - "integrity": "sha512-YYJRjaZ2bqk923HxE4um7j/Cm3/xoSkF2HC2ZweOF8cXL3sqnlndSUYmCaxHFjNPWLaSHk2IfssX6J/tdKTULw==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.50.0.tgz", + "integrity": "sha512-OS3/Viao+NPpyBbEY3tf6hLewppG+UclD+9i0ju56mq2DrdMJFCkEky6Sk9S5VPcbLzxzg3BqBX6u9Q35w19aQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { - "version": "1.49.2", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.49.2.tgz", - "integrity": "sha512-9WgH+Dha39EQQyGKCHlGYnxW/7W19DIrEbCEbnzwAMpGAv1yTWCHMPXHxYa+LcL3eCp2V/5idD1zHNlIKmHRHg==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.50.0.tgz", + "integrity": "sha512-/znwgSiGufpbJVIoDmeQaHtTq+OMdDawFRbMSJVv+12n79hW+qdQXS8/Uu3BD3yn0BzgVFJEvrsHrCsInZKdhw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.49.2.tgz", - "integrity": "sha512-K7Gp5u+JtVYgaVpBxF5rGiM+Ia8SsMdcAJMTDV93rwh00DKNllC19o1g+PwrDjDvyXNrnTEbofzbTs2GLfFyKA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.50.0.tgz", + "integrity": "sha512-dHjUfu4jfjdQiKDpCpAnM7LP5yfG0oNShtfpF5rMCel6/4HIoqJ4DC4h5GKDzgrvJYtgAhblo0AYBmOM00T+lQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "@algolia/client-common": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.49.2.tgz", - "integrity": "sha512-3UhYCcWX6fbtN8ABcxZlhaQEwXFh3CsFtARyyadQShHMPe3mJV9Wel4FpJTa+seugRkbezFz0tt6aPTZSYTBuA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.50.0.tgz", + "integrity": "sha512-bffIbUljAWnh/Ctu5uScORajuUavqmZ0ACYd1fQQeSSYA9NNN83ynO26pSc2dZRXpSK0fkc1//qSSFXMKGu+aw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2" + "@algolia/client-common": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.49.2.tgz", - "integrity": "sha512-G94VKSGbsr+WjsDDOBe5QDQ82QYgxvpxRGJfCHZBnYKYsy/jv9qGIDb93biza+LJWizQBUtDj7bZzp3QZyzhPQ==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.50.0.tgz", + "integrity": "sha512-y0EwNvPGvkM+yTAqqO6Gpt9wVGm3CLDtpLvNEiB3VGvN3WzfkjZGtLUsG/ru2kVJIIU7QcV0puuYgEpBeFxcJg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2" + "@algolia/client-common": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.49.2.tgz", - "integrity": "sha512-UuihBGHafG/ENsrcTGAn5rsOffrCIRuHMOsD85fZGLEY92ate+BMTUqxz60dv5zerh8ZumN4bRm8eW2z9L11jA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.50.0.tgz", + "integrity": "sha512-xpwefe4fCOWnZgXCbkGpqQY6jgBSCf2hmgnySbyzZIccrv3SoashHKGPE4x6vVG+gdHrGciMTAcDo9HOZwH22Q==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.49.2" + "@algolia/client-common": "5.50.0" }, "engines": { "node": ">= 14.0.0" @@ -431,9 +431,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.7.tgz", - "integrity": "sha512-6Fqi8MtQ/PweQ9xvux65emkLQ83uB+qAVtfHkC9UodyHMIZdxNI01HjLCLUtybElp2KY2XNE0nOgyP1E1vXw9w==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", @@ -608,22 +608,22 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "license": "MIT", "dependencies": { "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -1748,9 +1748,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz", - "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", + "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.29.0", @@ -1832,12 +1832,12 @@ } }, "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.1.tgz", - "integrity": "sha512-ENp89vM9Pw4kv/koBb5N2f9bDZsR0hpf3BdPMOg/pkS3pwO4dzNnQZVXtBbeyAadgm865DmQG2jMMLqmZXvuCw==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.7", + "@babel/helper-define-polyfill-provider": "^0.6.8", "core-js-compat": "^3.48.0" }, "peerDependencies": { @@ -1907,18 +1907,18 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.0.tgz", - "integrity": "sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.2.tgz", + "integrity": "sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==", "license": "MIT", "dependencies": { "core-js-pure": "^3.48.0" @@ -3308,9 +3308,9 @@ } }, "node_modules/@docsearch/core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.6.0.tgz", - "integrity": "sha512-IqG3oSd529jVRQ4dWZQKwZwQLVd//bWJTz2HiL0LkiHrI4U/vLrBasKB7lwQB/69nBAcCgs3TmudxTZSLH/ZQg==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.6.2.tgz", + "integrity": "sha512-/S0e6Dj7Zcm8m9Rru49YEX49dhU11be68c+S/BCyN8zQsTTgkKzXlhRbVL5mV6lOLC2+ZRRryaTdcm070Ug2oA==", "license": "MIT", "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -3330,20 +3330,20 @@ } }, "node_modules/@docsearch/css": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.6.0.tgz", - "integrity": "sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.6.2.tgz", + "integrity": "sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==", "license": "MIT" }, "node_modules/@docsearch/react": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.6.0.tgz", - "integrity": "sha512-j8H5B4ArGxBPBWvw3X0J0Rm/Pjv2JDa2rV5OE0DLTp5oiBCptIJ/YlNOhZxuzbO2nwge+o3Z52nJRi3hryK9cA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.6.2.tgz", + "integrity": "sha512-/BbtGFtqVOGwZx0dw/UfhN/0/DmMQYnulY4iv0tPRhC2JCXv0ka/+izwt3Jzo1ZxXS/2eMvv9zHsBJOK1I9f/w==", "license": "MIT", "dependencies": { "@algolia/autocomplete-core": "1.19.2", - "@docsearch/core": "4.6.0", - "@docsearch/css": "4.6.0" + "@docsearch/core": "4.6.2", + "@docsearch/css": "4.6.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -4211,13 +4211,13 @@ } }, "node_modules/@jsonjoy.com/fs-core": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.11.tgz", - "integrity": "sha512-wThHjzUp01ImIjfCwhs+UnFkeGPFAymwLEkOtenHewaKe2pTP12p6r1UuwikA9NEvNf9Vlck92r8fb8n/MWM5w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", + "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.56.11", - "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", "thingies": "^2.5.0" }, "engines": { @@ -4232,14 +4232,14 @@ } }, "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.11.tgz", - "integrity": "sha512-ZYlF3XbMayyp97xEN8ZvYutU99PCHjM64mMZvnCseXkCJXJDVLAwlF8Q/7q/xiWQRsv3pQBj1WXHd9eEyYcaCQ==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", + "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.56.11", - "@jsonjoy.com/fs-node-builtins": "4.56.11", - "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", "thingies": "^2.5.0" }, "engines": { @@ -4254,16 +4254,16 @@ } }, "node_modules/@jsonjoy.com/fs-node": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.11.tgz", - "integrity": "sha512-D65YrnP6wRuZyEWoSFnBJSr5zARVpVBGctnhie4rCsMuGXNzX7IHKaOt85/Aj7SSoG1N2+/xlNjWmkLvZ2H3Tg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", + "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.56.11", - "@jsonjoy.com/fs-node-builtins": "4.56.11", - "@jsonjoy.com/fs-node-utils": "4.56.11", - "@jsonjoy.com/fs-print": "4.56.11", - "@jsonjoy.com/fs-snapshot": "4.56.11", + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, @@ -4279,9 +4279,9 @@ } }, "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.11.tgz", - "integrity": "sha512-CNmt3a0zMCIhniFLXtzPWuUxXFU+U+2VyQiIrgt/rRVeEJNrMQUABaRbVxR0Ouw1LyR9RjaEkPM6nYpED+y43A==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", + "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -4295,14 +4295,14 @@ } }, "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.11.tgz", - "integrity": "sha512-5OzGdvJDgZVo+xXWEYo72u81zpOWlxlbG4d4nL+hSiW+LKlua/dldNgPrpWxtvhgyntmdFQad2UTxFyGjJAGhA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", + "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-fsa": "4.56.11", - "@jsonjoy.com/fs-node-builtins": "4.56.11", - "@jsonjoy.com/fs-node-utils": "4.56.11" + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1" }, "engines": { "node": ">=10.0" @@ -4316,12 +4316,12 @@ } }, "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.11.tgz", - "integrity": "sha512-JADOZFDA3wRfsuxkT0+MYc4F9hJO2PYDaY66kRTG6NqGX3+bqmKu66YFYAbII/tEmQWPZeHoClUB23rtQM9UPg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", + "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.56.11" + "@jsonjoy.com/fs-node-builtins": "4.57.1" }, "engines": { "node": ">=10.0" @@ -4335,12 +4335,12 @@ } }, "node_modules/@jsonjoy.com/fs-print": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.11.tgz", - "integrity": "sha512-rnaKRgCRIn8JGTjxhS0JPE38YM3Pj/H7SW4/tglhIPbfKEkky7dpPayNKV2qy25SZSL15oFVgH/62dMZ/z7cyA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", + "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.57.1", "tree-dump": "^1.1.0" }, "engines": { @@ -4355,13 +4355,13 @@ } }, "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.11.tgz", - "integrity": "sha512-IIldPX+cIRQuUol9fQzSS3hqyECxVpYMJQMqdU3dCKZFRzEl1rkIkw4P6y7Oh493sI7YdxZlKr/yWdzEWZ1wGQ==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", + "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.57.1", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, @@ -5231,9 +5231,9 @@ } }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -5884,34 +5884,34 @@ } }, "node_modules/algoliasearch": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.49.2.tgz", - "integrity": "sha512-1K0wtDaRONwfhL4h8bbJ9qTjmY6rhGgRvvagXkMBsAOMNr+3Q2SffHECh9DIuNVrMA1JwA0zCwhyepgBZVakng==", - "license": "MIT", - "dependencies": { - "@algolia/abtesting": "1.15.2", - "@algolia/client-abtesting": "5.49.2", - "@algolia/client-analytics": "5.49.2", - "@algolia/client-common": "5.49.2", - "@algolia/client-insights": "5.49.2", - "@algolia/client-personalization": "5.49.2", - "@algolia/client-query-suggestions": "5.49.2", - "@algolia/client-search": "5.49.2", - "@algolia/ingestion": "1.49.2", - "@algolia/monitoring": "1.49.2", - "@algolia/recommend": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.50.0.tgz", + "integrity": "sha512-yE5I83Q2s8euVou8Y3feXK08wyZInJWLYXgWO6Xti9jBUEZAGUahyeQ7wSZWkifLWVnQVKEz5RAmBlXG5nqxog==", + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.16.0", + "@algolia/client-abtesting": "5.50.0", + "@algolia/client-analytics": "5.50.0", + "@algolia/client-common": "5.50.0", + "@algolia/client-insights": "5.50.0", + "@algolia/client-personalization": "5.50.0", + "@algolia/client-query-suggestions": "5.50.0", + "@algolia/client-search": "5.50.0", + "@algolia/ingestion": "1.50.0", + "@algolia/monitoring": "1.50.0", + "@algolia/recommend": "5.50.0", + "@algolia/requester-browser-xhr": "5.50.0", + "@algolia/requester-fetch": "5.50.0", + "@algolia/requester-node-http": "5.50.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.28.0.tgz", - "integrity": "sha512-GBN0xsxGggaCPElZq24QzMdfphrjIiV2xA+hRXE4/UMpN3nsF2WrM8q+x80OGvGpJWtB7F+4Hq5eSfWwuejXrg==", + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.28.1.tgz", + "integrity": "sha512-6iXpbkkrAI5HFpCWXlNmIDSBuoN/U1XnEvb2yJAoWfqrZ+DrybI7MQ5P5mthFaprmocq+zbi6HxnR28xnZAYBw==", "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" @@ -6138,13 +6138,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.16.tgz", - "integrity": "sha512-xaVwwSfebXf0ooE11BJovZYKhFjIvQo7TsyVpETuIeH2JHv0k/T6Y5j22pPTvqYqmpkxdlPAJlyJ0tfOJAoMxw==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.7", + "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { @@ -6174,12 +6174,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.7.tgz", - "integrity": "sha512-OTYbUlSwXhNgr4g6efMZgsO8//jA61P7ZbRX3iTT53VON8l+WQS8IAUEVo4a4cWknrg2W8Cj4gQhRYNCJ8GkAA==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.7" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6196,15 +6196,18 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.7.tgz", - "integrity": "sha512-1ghYO3HnxGec0TCGBXiDLVns4eCSx4zJpxnHrlqFQajmhfKMQBzUGDdkMK7fUW7PTHTeLf+j87aTuKuuwWzMGw==", + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -6327,13 +6330,15 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -6538,9 +6543,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001778", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001778.tgz", - "integrity": "sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==", + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", "funding": [ { "type": "opencollective", @@ -6955,12 +6960,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -7121,9 +7120,9 @@ } }, "node_modules/core-js": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", - "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -7132,9 +7131,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", - "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "license": "MIT", "dependencies": { "browserslist": "^4.28.1" @@ -7145,9 +7144,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.48.0.tgz", - "integrity": "sha512-1slJgk89tWC51HQ1AEqG+s2VuwpTRr8ocu4n20QUcH1v9lAN0RXen0Q0AABa/DK1I7RrNWLucplOHMx8hfTGTw==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.49.0.tgz", + "integrity": "sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -8026,9 +8025,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.313", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", - "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -8072,9 +8071,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", - "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -8524,12 +8523,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -9446,12 +9439,6 @@ "wbuf": "^1.1.0" } }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -10192,9 +10179,9 @@ } }, "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/isexe": { @@ -10396,9 +10383,9 @@ } }, "node_modules/launch-editor": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.1.tgz", - "integrity": "sha512-lPSddlAAluRKJ7/cjRFoXUFzaX7q/YKI7yPHuEvSJVqoXvFnJov1/Ud87Aa4zULIbA9Nja4mSPK8l0z/7eV2wA==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", + "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", "license": "MIT", "dependencies": { "picocolors": "^1.1.1", @@ -10999,19 +10986,19 @@ } }, "node_modules/memfs": { - "version": "4.56.11", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.11.tgz", - "integrity": "sha512-/GodtwVeKVIHZKLUSr2ZdOxKBC5hHki4JNCU22DoCGPEHr5o2PD5U721zvESKyWwCfTfavFl9WZYgA13OAYK0g==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", + "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.56.11", - "@jsonjoy.com/fs-fsa": "4.56.11", - "@jsonjoy.com/fs-node": "4.56.11", - "@jsonjoy.com/fs-node-builtins": "4.56.11", - "@jsonjoy.com/fs-node-to-fsa": "4.56.11", - "@jsonjoy.com/fs-node-utils": "4.56.11", - "@jsonjoy.com/fs-print": "4.56.11", - "@jsonjoy.com/fs-snapshot": "4.56.11", + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-to-fsa": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", @@ -12912,9 +12899,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.1.tgz", - "integrity": "sha512-k7G3Y5QOegl380tXmZ68foBRRjE9Ljavx835ObdvmZjQ639izvZD8CS7BkWw1qKPPzHsGL/JDhl0uyU1zc2rJw==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz", + "integrity": "sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -13572,12 +13559,13 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", "license": "MIT", - "dependencies": { - "isarray": "0.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/path-type": { @@ -13596,12 +13584,12 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -13623,9 +13611,9 @@ } }, "node_modules/pkijs": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.3.3.tgz", - "integrity": "sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", + "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==", "license": "BSD-3-Clause", "dependencies": { "@noble/hashes": "1.4.0", @@ -15300,15 +15288,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -15449,9 +15428,9 @@ } }, "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.3.tgz", + "integrity": "sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" @@ -16148,9 +16127,9 @@ "license": "MIT" }, "node_modules/sax": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", - "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -16302,12 +16281,12 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=20.0.0" } }, "node_modules/serve-handler": { @@ -16325,12 +16304,6 @@ "range-parser": "1.2.0" } }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "license": "MIT" - }, "node_modules/serve-index": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", @@ -17018,9 +16991,9 @@ } }, "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", "license": "MIT", "engines": { "node": ">=6" @@ -17031,9 +17004,9 @@ } }, "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -17117,9 +17090,9 @@ "license": "MIT" }, "node_modules/thingies": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", - "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", "license": "MIT", "engines": { "node": ">=10.18" @@ -18078,9 +18051,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/docs/package.json b/docs/package.json index e61ba2b..60aff0c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,8 +15,8 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/core": "^3.5.2", + "@docusaurus/preset-classic": "^3.5.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -43,5 +43,11 @@ }, "engines": { "node": ">=20.0" + }, + "overrides": { + "serialize-javascript": ">=7.0.5", + "path-to-regexp": ">=8.2.0", + "picomatch": ">=4.0.2", + "brace-expansion": ">=2.0.2" } } From b815ded41d499e417d9bd805b374506ed06b2b37 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Sun, 29 Mar 2026 03:06:30 +0530 Subject: [PATCH 14/14] fix: revert pattern matching in jsonType to avoid unused variable warnings Java 21 unnamed patterns (_) are preview-only; instanceof chain avoids CodeQL unread-variable alerts without requiring preview features. --- .../com/agenteval/mcp/McpSchemaValidator.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java b/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java index 7d2f340..a17d9c2 100644 --- a/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java +++ b/agenteval-mcp/src/main/java/com/agenteval/mcp/McpSchemaValidator.java @@ -90,15 +90,12 @@ public static JsonNode parseSchema(String jsonSchema) { } private static String jsonType(Object value) { - return switch (value) { - case String s -> "string"; - case Integer i -> "integer"; - case Long l -> "integer"; - case Number n -> "number"; - case Boolean b -> "boolean"; - case List list -> "array"; - case Map map -> "object"; - case null, default -> "unknown"; - }; + if (value instanceof String) return "string"; + if (value instanceof Integer || value instanceof Long) return "integer"; + if (value instanceof Number) return "number"; + if (value instanceof Boolean) return "boolean"; + if (value instanceof List) return "array"; + if (value instanceof Map) return "object"; + return "unknown"; } }