From 29589357621147921c0890ccd9feffcca8e6b1fb Mon Sep 17 00:00:00 2001 From: Brace Sproul Date: Mon, 10 Jun 2024 16:43:05 -0700 Subject: [PATCH 1/2] ci[minor]: Add more packages to lowest/latest deps ci workflow (#5703) * ci[minor]: Add more packages to lowest/latest deps ci workflow * update lc lowest deps to actual lc deps * cr * cr * langchain lowest and latest working * all passing * added openai * add missing ts-jest devdep to openai * add anthropic, add missing ts-jest dep to anthropic * install deps first in workflow * use overrides instead of resoultions, add missing step to workflow * refactor a lot of code into a shared script * fix anthropic and grammar * revert unwanted change --- .github/workflows/compatibility.yml | 108 ++++++++++++++++++ dependency_range_tests/docker-compose.yml | 106 +++++++++++++++-- .../scripts/{ => langchain}/node/package.json | 0 .../node/update_resolutions_lowest.js | 50 ++++++++ .../scripts/{ => langchain}/node/yarn.lock | 0 .../test-with-latest-deps.sh} | 0 .../test-with-lowest-deps.sh} | 2 +- .../scripts/node/update_resolutions_lowest.js | 34 ------ .../anthropic/node/package.json | 9 ++ .../node/update_resolutions_lowest.js | 22 ++++ .../anthropic/node/update_workspace_deps.js | 15 +++ .../anthropic/node/yarn.lock | 22 ++++ .../anthropic/test-with-latest-deps.sh | 35 ++++++ .../anthropic/test-with-lowest-deps.sh | 34 ++++++ .../community/node/package.json | 9 ++ .../node/update_resolutions_lowest.js | 36 ++++++ .../community/node/yarn.lock | 22 ++++ .../community/test-with-latest-deps.sh | 22 ++++ .../community/test-with-lowest-deps.sh | 35 ++++++ .../with_standard_tests/node/package.json | 7 ++ .../node/update_workspace_dependencies.js | 21 ++++ .../with_standard_tests/node/yarn.lock | 22 ++++ .../openai/node/package.json | 9 ++ .../openai/node/update_resolutions_lowest.js | 22 ++++ .../with_standard_tests/openai/node/yarn.lock | 22 ++++ .../openai/test-with-latest-deps.sh | 22 ++++ .../openai/test-with-lowest-deps.sh | 35 ++++++ .../scripts/with_standard_tests/shared.sh | 50 ++++++++ langchain/package.json | 2 +- libs/langchain-anthropic/package.json | 3 +- libs/langchain-azure-openai/package.json | 2 +- libs/langchain-cloudflare/package.json | 2 +- libs/langchain-cohere/package.json | 2 +- libs/langchain-community/package.json | 2 +- libs/langchain-google-gauth/package.json | 2 +- libs/langchain-google-genai/package.json | 2 +- libs/langchain-groq/package.json | 2 +- libs/langchain-mistralai/package.json | 2 +- libs/langchain-openai/package.json | 3 +- yarn.lock | 24 ++-- 40 files changed, 752 insertions(+), 67 deletions(-) rename dependency_range_tests/scripts/{ => langchain}/node/package.json (100%) create mode 100644 dependency_range_tests/scripts/langchain/node/update_resolutions_lowest.js rename dependency_range_tests/scripts/{ => langchain}/node/yarn.lock (100%) rename dependency_range_tests/scripts/{test-langchain-with-latest-deps.sh => langchain/test-with-latest-deps.sh} (100%) rename dependency_range_tests/scripts/{test-langchain-with-lowest-deps.sh => langchain/test-with-lowest-deps.sh} (84%) delete mode 100644 dependency_range_tests/scripts/node/update_resolutions_lowest.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/node/package.json create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_resolutions_lowest.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_workspace_deps.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/node/yarn.lock create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-latest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-lowest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/community/node/package.json create mode 100644 dependency_range_tests/scripts/with_standard_tests/community/node/update_resolutions_lowest.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/community/node/yarn.lock create mode 100644 dependency_range_tests/scripts/with_standard_tests/community/test-with-latest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/community/test-with-lowest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/node/package.json create mode 100644 dependency_range_tests/scripts/with_standard_tests/node/update_workspace_dependencies.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/node/yarn.lock create mode 100644 dependency_range_tests/scripts/with_standard_tests/openai/node/package.json create mode 100644 dependency_range_tests/scripts/with_standard_tests/openai/node/update_resolutions_lowest.js create mode 100644 dependency_range_tests/scripts/with_standard_tests/openai/node/yarn.lock create mode 100644 dependency_range_tests/scripts/with_standard_tests/openai/test-with-latest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/openai/test-with-lowest-deps.sh create mode 100644 dependency_range_tests/scripts/with_standard_tests/shared.sh diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml index 9b38e7d85147..6aacdab1f1b0 100644 --- a/.github/workflows/compatibility.yml +++ b/.github/workflows/compatibility.yml @@ -28,6 +28,7 @@ env: # Run a separate job for each check in the docker-compose file, # so that they run in parallel instead of overwhelming the default 2 CPU runner. jobs: + # LangChain test-langchain-with-latest-deps: runs-on: ubuntu-latest steps: @@ -37,6 +38,10 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests - name: Test LangChain with latest deps run: docker compose -f dependency_range_tests/docker-compose.yml run test-langchain-with-latest-deps @@ -49,5 +54,108 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests - name: Test LangChain with lowest deps run: docker compose -f dependency_range_tests/docker-compose.yml run test-langchain-with-lowest-deps + + # Community + test-community-with-latest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/community` with latest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-community-with-latest-deps + + test-community-with-lowest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/community` with lowest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-community-with-lowest-deps + + # OpenAI + test-openai-with-latest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/openai` with latest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-openai-with-latest-deps + + test-openai-with-lowest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/openai` with lowest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-openai-with-lowest-deps + + # Anthropic + test-anthropic-with-latest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/anthropic` with latest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-anthropic-with-latest-deps + + test-anthropic-with-lowest-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "yarn" + - name: Install dependencies + run: yarn install --immutable + - name: Build `@langchain/standard-tests` + run: yarn build --filter=@langchain/standard-tests + - name: Test `@langchain/anthropic` with lowest deps + run: docker compose -f dependency_range_tests/docker-compose.yml run test-anthropic-with-lowest-deps diff --git a/dependency_range_tests/docker-compose.yml b/dependency_range_tests/docker-compose.yml index da0544ee2747..b5729ae14e74 100644 --- a/dependency_range_tests/docker-compose.yml +++ b/dependency_range_tests/docker-compose.yml @@ -1,5 +1,6 @@ version: "3" services: + # LangChain test-langchain-with-latest-deps: image: node:18 environment: @@ -10,7 +11,7 @@ services: volumes: - ../langchain:/langchain - ./scripts:/scripts - command: bash /scripts/test-langchain-with-latest-deps.sh + command: bash /scripts/langchain/test-with-latest-deps.sh test-langchain-with-lowest-deps: image: node:18 environment: @@ -19,14 +20,99 @@ services: COHERE_API_KEY: ${COHERE_API_KEY} working_dir: /app volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests - ../langchain:/langchain - ./scripts:/scripts - command: bash /scripts/test-langchain-with-lowest-deps.sh - success: - image: alpine:3.14 - command: echo "Success" - depends_on: - test-langchain-with-latest-deps: - condition: service_completed_successfully - test-langchain-with-lowest-deps: - condition: service_completed_successfully + command: bash /scripts/langchain/test-with-lowest-deps.sh + + # Community + test-community-with-latest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-community:/libs/langchain-community + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/community/test-with-latest-deps.sh + test-community-with-lowest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-community:/libs/langchain-community + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/community/test-with-lowest-deps.sh + + # OpenAI + test-openai-with-latest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-openai:/libs/langchain-openai + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/openai/test-with-latest-deps.sh + test-openai-with-lowest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-openai:/libs/langchain-openai + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/openai/test-with-lowest-deps.sh + + # Anthropic + test-anthropic-with-latest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-anthropic:/libs/langchain-anthropic + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/anthropic/test-with-latest-deps.sh + test-anthropic-with-lowest-deps: + image: node:18 + environment: + PUPPETEER_SKIP_DOWNLOAD: "true" + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" + COHERE_API_KEY: ${COHERE_API_KEY} + working_dir: /app + volumes: + - ../turbo.json:/turbo.json + - ../package.json:/package.json + - ../libs/langchain-standard-tests:/libs/langchain-standard-tests + - ../libs/langchain-anthropic:/libs/langchain-anthropic + - ./scripts:/scripts + command: bash /scripts/with_standard_tests/anthropic/test-with-lowest-deps.sh diff --git a/dependency_range_tests/scripts/node/package.json b/dependency_range_tests/scripts/langchain/node/package.json similarity index 100% rename from dependency_range_tests/scripts/node/package.json rename to dependency_range_tests/scripts/langchain/node/package.json diff --git a/dependency_range_tests/scripts/langchain/node/update_resolutions_lowest.js b/dependency_range_tests/scripts/langchain/node/update_resolutions_lowest.js new file mode 100644 index 000000000000..5712a8b5770c --- /dev/null +++ b/dependency_range_tests/scripts/langchain/node/update_resolutions_lowest.js @@ -0,0 +1,50 @@ +const fs = require("fs"); +const semver = require("semver"); + +const communityPackageJsonPath = "package.json"; + +const currentPackageJson = JSON.parse(fs.readFileSync(communityPackageJsonPath)); + +if (currentPackageJson.dependencies["@langchain/core"] && !currentPackageJson.dependencies["@langchain/core"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/core"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/core": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/core": minVersion, + }; +} + +if (currentPackageJson.dependencies["@langchain/openai"] && !currentPackageJson.dependencies["@langchain/openai"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/openai"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/openai": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/openai": minVersion, + }; +} + +if (currentPackageJson.dependencies["@langchain/textsplitters"] && !currentPackageJson.dependencies["@langchain/textsplitters"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/textsplitters"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/textsplitters": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/textsplitters": minVersion, + }; +} + +fs.writeFileSync(communityPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/node/yarn.lock b/dependency_range_tests/scripts/langchain/node/yarn.lock similarity index 100% rename from dependency_range_tests/scripts/node/yarn.lock rename to dependency_range_tests/scripts/langchain/node/yarn.lock diff --git a/dependency_range_tests/scripts/test-langchain-with-latest-deps.sh b/dependency_range_tests/scripts/langchain/test-with-latest-deps.sh similarity index 100% rename from dependency_range_tests/scripts/test-langchain-with-latest-deps.sh rename to dependency_range_tests/scripts/langchain/test-with-latest-deps.sh diff --git a/dependency_range_tests/scripts/test-langchain-with-lowest-deps.sh b/dependency_range_tests/scripts/langchain/test-with-lowest-deps.sh similarity index 84% rename from dependency_range_tests/scripts/test-langchain-with-lowest-deps.sh rename to dependency_range_tests/scripts/langchain/test-with-lowest-deps.sh index 9040b5f905ae..e7f36a21cd01 100644 --- a/dependency_range_tests/scripts/test-langchain-with-lowest-deps.sh +++ b/dependency_range_tests/scripts/langchain/test-with-lowest-deps.sh @@ -11,7 +11,7 @@ shopt -s extglob cp -r ../langchain/!(node_modules|dist|dist-cjs|dist-esm|build|.next|.turbo) ./ mkdir -p /updater_script -cp -r /scripts/node/!(node_modules|dist|dist-cjs|dist-esm|build|.next|.turbo) /updater_script/ +cp -r /scripts/langchain/node/!(node_modules|dist|dist-cjs|dist-esm|build|.next|.turbo) /updater_script/ cd /updater_script diff --git a/dependency_range_tests/scripts/node/update_resolutions_lowest.js b/dependency_range_tests/scripts/node/update_resolutions_lowest.js deleted file mode 100644 index 354be36113e7..000000000000 --- a/dependency_range_tests/scripts/node/update_resolutions_lowest.js +++ /dev/null @@ -1,34 +0,0 @@ -const fs = require("fs"); -const semver = require("semver"); - -const currentPackageJson = JSON.parse(fs.readFileSync("./package.json")); - -if (currentPackageJson.dependencies["@langchain/core"] && !currentPackageJson.dependencies["@langchain/core"].includes("rc")) { - const minVersion = semver.minVersion( - currentPackageJson.dependencies["@langchain/core"] - ).version; - currentPackageJson.resolutions = { - ...currentPackageJson.resolutions, - "@langchain/core": minVersion, - }; - currentPackageJson.dependencies = { - ...currentPackageJson.dependencies, - "@langchain/core": minVersion, - }; -} - -if (currentPackageJson.dependencies["@langchain/community"] && !currentPackageJson.dependencies["@langchain/community"].includes("rc")) { - const minVersion = semver.minVersion( - currentPackageJson.dependencies["@langchain/community"] - ).version; - currentPackageJson.resolutions = { - ...currentPackageJson.resolutions, - "@langchain/community": minVersion, - }; - currentPackageJson.dependencies = { - ...currentPackageJson.dependencies, - "@langchain/community": minVersion, - }; -} - -fs.writeFileSync("./package.json", JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/node/package.json b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/package.json new file mode 100644 index 000000000000..a4622fc74597 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/package.json @@ -0,0 +1,9 @@ +{ + "name": "dependency-range-tests", + "version": "0.0.0", + "private": true, + "description": "Tests dependency ranges for LangChain.", + "dependencies": { + "semver": "^7.5.4" + } +} \ No newline at end of file diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_resolutions_lowest.js b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_resolutions_lowest.js new file mode 100644 index 000000000000..d2ed5e7ac928 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_resolutions_lowest.js @@ -0,0 +1,22 @@ +const fs = require("fs"); +const semver = require("semver"); + +const communityPackageJsonPath = "/app/monorepo/libs/langchain-anthropic/package.json"; + +const currentPackageJson = JSON.parse(fs.readFileSync(communityPackageJsonPath)); + +if (currentPackageJson.dependencies["@langchain/core"] && !currentPackageJson.dependencies["@langchain/core"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/core"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/core": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/core": minVersion, + }; +} + +fs.writeFileSync(communityPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_workspace_deps.js b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_workspace_deps.js new file mode 100644 index 000000000000..afb7087e470e --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/update_workspace_deps.js @@ -0,0 +1,15 @@ +const fs = require("fs"); + +const communityPackageJsonPath = "/app/monorepo/libs/langchain-anthropic/package.json"; +const currentPackageJson = JSON.parse(fs.readFileSync(communityPackageJsonPath)); + +// Anthropic has other workspaces as devDependencies, but tagged as `workspace:*` for the version. +// Update these to be `latest` for the test. +if (currentPackageJson.devDependencies["@langchain/community"]) { + currentPackageJson.devDependencies = { + ...currentPackageJson.devDependencies, + "@langchain/community": "latest", + }; +} + +fs.writeFileSync(communityPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/node/yarn.lock b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/yarn.lock new file mode 100644 index 000000000000..50ac73caa812 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/node/yarn.lock @@ -0,0 +1,22 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-latest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-latest-deps.sh new file mode 100644 index 000000000000..80beb0a3568d --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-latest-deps.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +# New monorepo directory paths +monorepo_dir="/app/monorepo" +monorepo_anthropic_dir="/app/monorepo/libs/langchain-anthropic" + +# Updater script will not live inside the monorepo +updater_script_dir="/app/updater_script" + +# Original directory paths +original_updater_script_dir="/scripts/with_standard_tests/anthropic/node" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh anthropic + +mkdir -p "$updater_script_dir" +cp "$original_updater_script_dir"/* "$updater_script_dir/" +cd "$updater_script_dir" +# Update any workspace dep to the latest version since not all workspaces are +# available in the test enviroment. +node "update_workspace_deps.js" + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/anthropic` to build and run tests +# We need to run inside the anthropic directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_anthropic_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-lowest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-lowest-deps.sh new file mode 100644 index 000000000000..0ae8ac11503b --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/anthropic/test-with-lowest-deps.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +monorepo_dir="/app/monorepo" +monorepo_openai_dir="/app/monorepo/libs/langchain-anthropic" +updater_script_dir="/app/updater_script" +original_updater_script_dir="/scripts/with_standard_tests/anthropic/node" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh anthropic + +# Copy the updater script to the monorepo +mkdir -p "$updater_script_dir" +cp "$original_updater_script_dir"/* "$updater_script_dir/" + +# Install deps (e.g semver) for the updater script +cd "$updater_script_dir" +yarn +# Run the updater script +node "update_resolutions_lowest.js" +node "update_workspace_deps.js" + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/anthropic` to build and run tests +# We need to run inside the package directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_openai_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/community/node/package.json b/dependency_range_tests/scripts/with_standard_tests/community/node/package.json new file mode 100644 index 000000000000..a4622fc74597 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/community/node/package.json @@ -0,0 +1,9 @@ +{ + "name": "dependency-range-tests", + "version": "0.0.0", + "private": true, + "description": "Tests dependency ranges for LangChain.", + "dependencies": { + "semver": "^7.5.4" + } +} \ No newline at end of file diff --git a/dependency_range_tests/scripts/with_standard_tests/community/node/update_resolutions_lowest.js b/dependency_range_tests/scripts/with_standard_tests/community/node/update_resolutions_lowest.js new file mode 100644 index 000000000000..b0da1629189e --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/community/node/update_resolutions_lowest.js @@ -0,0 +1,36 @@ +const fs = require("fs"); +const semver = require("semver"); + +const communityPackageJsonPath = "/app/monorepo/libs/langchain-community/package.json"; + +const currentPackageJson = JSON.parse(fs.readFileSync(communityPackageJsonPath)); + +if (currentPackageJson.dependencies["@langchain/core"] && !currentPackageJson.dependencies["@langchain/core"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/core"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/core": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/core": minVersion, + }; +} + +if (currentPackageJson.dependencies["@langchain/openai"] && !currentPackageJson.dependencies["@langchain/openai"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/openai"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/openai": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/openai": minVersion, + }; +} + +fs.writeFileSync(communityPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/community/node/yarn.lock b/dependency_range_tests/scripts/with_standard_tests/community/node/yarn.lock new file mode 100644 index 000000000000..50ac73caa812 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/community/node/yarn.lock @@ -0,0 +1,22 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/dependency_range_tests/scripts/with_standard_tests/community/test-with-latest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/community/test-with-latest-deps.sh new file mode 100644 index 000000000000..f7c65b71ac00 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/community/test-with-latest-deps.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +# New monorepo directory paths +monorepo_dir="/app/monorepo" +monorepo_community_dir="/app/monorepo/libs/langchain-community" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh community + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/community` to build and run tests +# We need to run inside the community directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_community_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/community/test-with-lowest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/community/test-with-lowest-deps.sh new file mode 100644 index 000000000000..a96debf040b7 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/community/test-with-lowest-deps.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +monorepo_dir="/app/monorepo" +monorepo_community_dir="/app/monorepo/libs/langchain-community" +updater_script_dir="/app/updater_script" +updater_script_dir="/app/updater_script" +original_updater_script_dir="/scripts/with_standard_tests/community/node" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh community + +# Copy the updater script to the monorepo +mkdir -p "$updater_script_dir" +cp "$original_updater_script_dir"/* "$updater_script_dir/" + +# Install deps (e.g semver) for the updater script +cd "$updater_script_dir" +yarn +# Run the updater script +node "update_resolutions_lowest.js" + + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/package` to build and run tests +# We need to run inside the package directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_community_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/node/package.json b/dependency_range_tests/scripts/with_standard_tests/node/package.json new file mode 100644 index 000000000000..ba8b482e7515 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/node/package.json @@ -0,0 +1,7 @@ +{ + "name": "dependency-range-tests", + "version": "0.0.0", + "private": true, + "description": "Tests dependency ranges for LangChain.", + "dependencies": {} +} \ No newline at end of file diff --git a/dependency_range_tests/scripts/with_standard_tests/node/update_workspace_dependencies.js b/dependency_range_tests/scripts/with_standard_tests/node/update_workspace_dependencies.js new file mode 100644 index 000000000000..755700a9c749 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/node/update_workspace_dependencies.js @@ -0,0 +1,21 @@ +const fs = require("fs"); + +const standardTestsPackageJsonPath = "/app/monorepo/libs/langchain-standard-tests/package.json"; + +const currentPackageJson = JSON.parse(fs.readFileSync(standardTestsPackageJsonPath)); + +if (currentPackageJson.dependencies["@langchain/core"]) { + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/core": "latest", + }; +} + +if (currentPackageJson.devDependencies["@langchain/scripts"]) { + currentPackageJson.devDependencies = { + ...currentPackageJson.devDependencies, + "@langchain/scripts": "latest", + }; +} + +fs.writeFileSync(standardTestsPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/node/yarn.lock b/dependency_range_tests/scripts/with_standard_tests/node/yarn.lock new file mode 100644 index 000000000000..50ac73caa812 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/node/yarn.lock @@ -0,0 +1,22 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/dependency_range_tests/scripts/with_standard_tests/openai/node/package.json b/dependency_range_tests/scripts/with_standard_tests/openai/node/package.json new file mode 100644 index 000000000000..a4622fc74597 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/openai/node/package.json @@ -0,0 +1,9 @@ +{ + "name": "dependency-range-tests", + "version": "0.0.0", + "private": true, + "description": "Tests dependency ranges for LangChain.", + "dependencies": { + "semver": "^7.5.4" + } +} \ No newline at end of file diff --git a/dependency_range_tests/scripts/with_standard_tests/openai/node/update_resolutions_lowest.js b/dependency_range_tests/scripts/with_standard_tests/openai/node/update_resolutions_lowest.js new file mode 100644 index 000000000000..d54d62d708e7 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/openai/node/update_resolutions_lowest.js @@ -0,0 +1,22 @@ +const fs = require("fs"); +const semver = require("semver"); + +const communityPackageJsonPath = "/app/monorepo/libs/langchain-openai/package.json"; + +const currentPackageJson = JSON.parse(fs.readFileSync(communityPackageJsonPath)); + +if (currentPackageJson.dependencies["@langchain/core"] && !currentPackageJson.dependencies["@langchain/core"].includes("rc")) { + const minVersion = semver.minVersion( + currentPackageJson.dependencies["@langchain/core"] + ).version; + currentPackageJson.overrides = { + ...currentPackageJson.overrides, + "@langchain/core": minVersion, + }; + currentPackageJson.dependencies = { + ...currentPackageJson.dependencies, + "@langchain/core": minVersion, + }; +} + +fs.writeFileSync(communityPackageJsonPath, JSON.stringify(currentPackageJson, null, 2)); diff --git a/dependency_range_tests/scripts/with_standard_tests/openai/node/yarn.lock b/dependency_range_tests/scripts/with_standard_tests/openai/node/yarn.lock new file mode 100644 index 000000000000..50ac73caa812 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/openai/node/yarn.lock @@ -0,0 +1,22 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/dependency_range_tests/scripts/with_standard_tests/openai/test-with-latest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/openai/test-with-latest-deps.sh new file mode 100644 index 000000000000..69bb581e414a --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/openai/test-with-latest-deps.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +# New monorepo directory paths +monorepo_dir="/app/monorepo" +monorepo_openai_dir="/app/monorepo/libs/langchain-openai" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh openai + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/openai` to build and run tests +# We need to run inside the openai directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_openai_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/openai/test-with-lowest-deps.sh b/dependency_range_tests/scripts/with_standard_tests/openai/test-with-lowest-deps.sh new file mode 100644 index 000000000000..91536708b13c --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/openai/test-with-lowest-deps.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export CI=true + +monorepo_dir="/app/monorepo" +monorepo_openai_dir="/app/monorepo/libs/langchain-openai" +updater_script_dir="/app/updater_script" +updater_script_dir="/app/updater_script" +original_updater_script_dir="/scripts/with_standard_tests/openai/node" + +# Run the shared script to copy all necessary folders/files +bash /scripts/with_standard_tests/shared.sh openai + +# Copy the updater script to the monorepo +mkdir -p "$updater_script_dir" +cp "$original_updater_script_dir"/* "$updater_script_dir/" + +# Install deps (e.g semver) for the updater script +cd "$updater_script_dir" +yarn +# Run the updater script +node "update_resolutions_lowest.js" + + +# Navigate back to monorepo root and install dependencies +cd "$monorepo_dir" +yarn + +# Navigate into `@langchain/package` to build and run tests +# We need to run inside the package directory so turbo repo does +# not try to build the package/its workspace dependencies. +cd "$monorepo_openai_dir" +yarn test diff --git a/dependency_range_tests/scripts/with_standard_tests/shared.sh b/dependency_range_tests/scripts/with_standard_tests/shared.sh new file mode 100644 index 000000000000..3a3eda1edb46 --- /dev/null +++ b/dependency_range_tests/scripts/with_standard_tests/shared.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Extract the package name from the first argument +package_name=$1 + +# New monorepo directory paths +monorepo_dir="/app/monorepo" +monorepo_libs_dir="$monorepo_dir/libs" +monorepo_package_dir="$monorepo_libs_dir/langchain-$package_name" +monorepo_standard_tests_dir="$monorepo_libs_dir/langchain-standard-tests" + +# Updater script will not live inside the monorepo +standard_tests_updater_script_dir="/app/with_standard_script" + +# Original directory paths +original_package_dir="/libs/langchain-$package_name" +original_standard_tests_dir="/libs/langchain-standard-tests" +original_package_json_dir="/package.json" +original_turbo_json_dir="/turbo.json" +original_standard_tests_updater_script_dir="/scripts/with_standard_tests/node" + +# enable extended globbing for omitting build artifacts +shopt -s extglob + +# Create the top level monorepo directory +mkdir -p "$monorepo_dir" + +# Copy `@langchain/standard-tests` WITH build artifacts from the host. +# This is because we build @langchain/standard-tests before running this script. +mkdir -p "$monorepo_standard_tests_dir/" +cp -r "$original_standard_tests_dir"/* "$monorepo_standard_tests_dir/" + +# Copy `@langchain/package` WITHOUT build artifacts from the host. +mkdir -p "$monorepo_package_dir/" +cp -r "$original_package_dir"/!(node_modules|dist|dist-cjs|dist-esm|build|.next|.turbo) "$monorepo_package_dir/" + +# Copy the turbo and package.json files for monorepo +cp "$original_turbo_json_dir" "$monorepo_dir/" +cp "$original_package_json_dir" "$monorepo_dir/" + +# Replace any workspace dependencies in `@langchain/standard-tests` +# with "latest" for the version. +mkdir -p "$standard_tests_updater_script_dir" +cp "$original_standard_tests_updater_script_dir"/* "$standard_tests_updater_script_dir/" +cd "$standard_tests_updater_script_dir" +# Run the updater script +node "update_workspace_dependencies.js" + +# Navigate back to root +cd "/app" diff --git a/langchain/package.json b/langchain/package.json index 5121d39f6e54..df97735b214c 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -580,7 +580,7 @@ "clean": "rm -rf .turbo dist/", "prepack": "yarn build", "release": "release-it --only-version --config .release-it.json", - "test": "yarn run build:deps && NODE_OPTIONS=--experimental-vm-modules jest --testPathIgnorePatterns=\\.int\\.test.ts --testTimeout 30000 --maxWorkers=50%", + "test": "NODE_OPTIONS=--experimental-vm-modules jest --testPathIgnorePatterns=\\.int\\.test.ts --testTimeout 30000 --maxWorkers=50%", "test:watch": "yarn run build:deps && NODE_OPTIONS=--experimental-vm-modules jest --watch --testPathIgnorePatterns=\\.int\\.test.ts", "test:integration": "yarn run build:deps && NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%", "test:single": "yarn run build:deps && NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000", diff --git a/libs/langchain-anthropic/package.json b/libs/langchain-anthropic/package.json index 22412ab3d84b..b7baf1e8feed 100644 --- a/libs/langchain-anthropic/package.json +++ b/libs/langchain-anthropic/package.json @@ -45,7 +45,7 @@ "@jest/globals": "^29.5.0", "@langchain/community": "workspace:*", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "dpdm": "^3.12.0", @@ -61,6 +61,7 @@ "prettier": "^2.8.3", "release-it": "^15.10.1", "rimraf": "^5.0.1", + "ts-jest": "^29.1.0", "typescript": "~5.1.6" }, "publishConfig": { diff --git a/libs/langchain-azure-openai/package.json b/libs/langchain-azure-openai/package.json index e7f498c05c18..c5cd736106f0 100644 --- a/libs/langchain-azure-openai/package.json +++ b/libs/langchain-azure-openai/package.json @@ -42,7 +42,7 @@ "@azure/identity": "^4.0.1", "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "dpdm": "^3.12.0", diff --git a/libs/langchain-cloudflare/package.json b/libs/langchain-cloudflare/package.json index 8b5e6d9afefd..7b6fb9db3042 100644 --- a/libs/langchain-cloudflare/package.json +++ b/libs/langchain-cloudflare/package.json @@ -43,7 +43,7 @@ "@cloudflare/workers-types": "^4.20231218.0", "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-cohere/package.json b/libs/langchain-cohere/package.json index a17c3a982b26..a06f9dccaba1 100644 --- a/libs/langchain-cohere/package.json +++ b/libs/langchain-cohere/package.json @@ -41,7 +41,7 @@ "devDependencies": { "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-community/package.json b/libs/langchain-community/package.json index 98290c67561e..b6228c721400 100644 --- a/libs/langchain-community/package.json +++ b/libs/langchain-community/package.json @@ -79,7 +79,7 @@ "@huggingface/inference": "^2.6.4", "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@layerup/layerup-security": "^1.5.12", "@mendable/firecrawl-js": "^0.0.13", "@mlc-ai/web-llm": "^0.2.40", diff --git a/libs/langchain-google-gauth/package.json b/libs/langchain-google-gauth/package.json index 4d28bfdabc54..e2338094c357 100644 --- a/libs/langchain-google-gauth/package.json +++ b/libs/langchain-google-gauth/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-google-genai/package.json b/libs/langchain-google-genai/package.json index 4456203c60e4..4e79453b5693 100644 --- a/libs/langchain-google-genai/package.json +++ b/libs/langchain-google-genai/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-groq/package.json b/libs/langchain-groq/package.json index 8672bb54dc31..11602004b093 100644 --- a/libs/langchain-groq/package.json +++ b/libs/langchain-groq/package.json @@ -45,7 +45,7 @@ "@jest/globals": "^29.5.0", "@langchain/openai": "workspace:^", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-mistralai/package.json b/libs/langchain-mistralai/package.json index f0cff626b1c7..59f8750e145a 100644 --- a/libs/langchain-mistralai/package.json +++ b/libs/langchain-mistralai/package.json @@ -44,7 +44,7 @@ "devDependencies": { "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "@tsconfig/recommended": "^1.0.3", diff --git a/libs/langchain-openai/package.json b/libs/langchain-openai/package.json index c3fd15cbcccf..f26b80168a5d 100644 --- a/libs/langchain-openai/package.json +++ b/libs/langchain-openai/package.json @@ -45,7 +45,7 @@ "@azure/identity": "^4.2.0", "@jest/globals": "^29.5.0", "@langchain/scripts": "~0.0.14", - "@langchain/standard-tests": "workspace:*", + "@langchain/standard-tests": "0.0.0", "@swc/core": "^1.3.90", "@swc/jest": "^0.2.29", "dpdm": "^3.12.0", @@ -61,6 +61,7 @@ "prettier": "^2.8.3", "release-it": "^15.10.1", "rimraf": "^5.0.1", + "ts-jest": "^29.1.0", "typescript": "~5.1.6" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index 1c739c5a7d6b..8cffe69926ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8931,7 +8931,7 @@ __metadata: "@langchain/community": "workspace:*" "@langchain/core": ">=0.2.5 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 dpdm: ^3.12.0 @@ -8948,6 +8948,7 @@ __metadata: prettier: ^2.8.3 release-it: ^15.10.1 rimraf: ^5.0.1 + ts-jest: ^29.1.0 typescript: ~5.1.6 zod: ^3.22.4 zod-to-json-schema: ^3.22.4 @@ -8964,7 +8965,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">0.1.0 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 dpdm: ^3.12.0 @@ -8996,7 +8997,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">0.1.0 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 "@tsconfig/recommended": ^1.0.3 @@ -9039,7 +9040,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">0.1.58 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 "@tsconfig/recommended": ^1.0.3 @@ -9101,7 +9102,7 @@ __metadata: "@langchain/core": ~0.2.6 "@langchain/openai": ~0.1.0 "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@layerup/layerup-security": ^1.5.12 "@mendable/firecrawl-js": ^0.0.13 "@mlc-ai/web-llm": ^0.2.40 @@ -9720,7 +9721,7 @@ __metadata: "@langchain/core": ">0.1.56 <0.3.0" "@langchain/google-common": ~0.0.18 "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 "@tsconfig/recommended": ^1.0.3 @@ -9754,7 +9755,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">0.1.5 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 "@tsconfig/recommended": ^1.0.3 @@ -9884,7 +9885,7 @@ __metadata: "@langchain/core": ">0.1.56 <0.3.0" "@langchain/openai": "workspace:^" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 "@tsconfig/recommended": ^1.0.3 @@ -9935,7 +9936,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">0.1.56 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@mistralai/mistralai": ^0.4.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 @@ -10052,7 +10053,7 @@ __metadata: "@jest/globals": ^29.5.0 "@langchain/core": ">=0.2.5 <0.3.0" "@langchain/scripts": ~0.0.14 - "@langchain/standard-tests": "workspace:*" + "@langchain/standard-tests": 0.0.0 "@swc/core": ^1.3.90 "@swc/jest": ^0.2.29 dpdm: ^3.12.0 @@ -10070,6 +10071,7 @@ __metadata: prettier: ^2.8.3 release-it: ^15.10.1 rimraf: ^5.0.1 + ts-jest: ^29.1.0 typescript: ~5.1.6 zod: ^3.22.4 zod-to-json-schema: ^3.22.3 @@ -10216,7 +10218,7 @@ __metadata: languageName: unknown linkType: soft -"@langchain/standard-tests@workspace:*, @langchain/standard-tests@workspace:libs/langchain-standard-tests": +"@langchain/standard-tests@0.0.0, @langchain/standard-tests@workspace:libs/langchain-standard-tests": version: 0.0.0-use.local resolution: "@langchain/standard-tests@workspace:libs/langchain-standard-tests" dependencies: From a550a7fb9bf92500caed2ace40da11204e84f66d Mon Sep 17 00:00:00 2001 From: Brace Sproul Date: Mon, 10 Jun 2024 17:41:27 -0700 Subject: [PATCH 2/2] google-vertexai[minor]: Move tests from gauth/webauth into vertexai packages (#5722) * google-vertexai[minor]: Move tests from gauth/webauth into vertexai packages * move auth test back to gauth --- .../src/tests/chat_models.int.test.ts | 226 ----------------- .../src/tests/llms.int.test.ts | 236 ------------------ .../src/tests/chat_models.int.test.ts | 21 ++ .../src/tests/llms.int.test.ts | 80 ------ .../src/tests/chat_models.int.test.ts | 151 ++++++++--- 5 files changed, 137 insertions(+), 577 deletions(-) delete mode 100644 libs/langchain-google-gauth/src/tests/chat_models.int.test.ts delete mode 100644 libs/langchain-google-gauth/src/tests/llms.int.test.ts diff --git a/libs/langchain-google-gauth/src/tests/chat_models.int.test.ts b/libs/langchain-google-gauth/src/tests/chat_models.int.test.ts deleted file mode 100644 index 83146ac72e00..000000000000 --- a/libs/langchain-google-gauth/src/tests/chat_models.int.test.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { expect, test } from "@jest/globals"; -import { BaseLanguageModelInput } from "@langchain/core/language_models/base"; -import { ChatPromptValue } from "@langchain/core/prompt_values"; -import { - AIMessage, - AIMessageChunk, - BaseMessage, - BaseMessageChunk, - BaseMessageLike, - HumanMessage, - // MessageContentComplex, - SystemMessage, - ToolMessage, -} from "@langchain/core/messages"; -import { GeminiTool } from "@langchain/google-common"; -import { ChatGoogle } from "../chat_models.js"; -import { GoogleLLM } from "../llms.js"; - -describe("GAuth Chat", () => { - test("platform", async () => { - const model = new GoogleLLM(); - expect(model.platform).toEqual("gcp"); - }); - - test("invoke", async () => { - const model = new ChatGoogle(); - try { - const res = await model.invoke("What is 1 + 1?"); - expect(res).toBeDefined(); - expect(res._getType()).toEqual("ai"); - - const aiMessage = res as AIMessageChunk; - expect(aiMessage.content).toBeDefined(); - - expect(typeof aiMessage.content).toBe("string"); - const text = aiMessage.content as string; - expect(text).toMatch(/(1 + 1 (equals|is|=) )?2.? ?/); - - /* - expect(aiMessage.content.length).toBeGreaterThan(0); - expect(aiMessage.content[0]).toBeDefined(); - const content = aiMessage.content[0] as MessageContentComplex; - expect(content).toHaveProperty("type"); - expect(content.type).toEqual("text"); - - const textContent = content as MessageContentText; - expect(textContent.text).toBeDefined(); - expect(textContent.text).toEqual("2"); - */ - } catch (e) { - console.error(e); - throw e; - } - }); - - test("generate", async () => { - const model = new ChatGoogle(); - try { - const messages: BaseMessage[] = [ - new SystemMessage( - "You will reply to all requests to flip a coin with either H, indicating heads, or T, indicating tails." - ), - new HumanMessage("Flip it"), - new AIMessage("T"), - new HumanMessage("Flip the coin again"), - ]; - const res = await model.predictMessages(messages); - expect(res).toBeDefined(); - expect(res._getType()).toEqual("ai"); - - const aiMessage = res as AIMessageChunk; - expect(aiMessage.content).toBeDefined(); - expect(["H", "T"]).toContainEqual(aiMessage.content); - } catch (e) { - console.error(e); - throw e; - } - }); - - test("stream", async () => { - const model = new ChatGoogle(); - try { - const input: BaseLanguageModelInput = new ChatPromptValue([ - new SystemMessage( - "You will reply to all requests to flip a coin with either H, indicating heads, or T, indicating tails." - ), - new HumanMessage("Flip it"), - new AIMessage("T"), - new HumanMessage("Flip the coin again"), - ]); - const res = await model.stream(input); - const resArray: BaseMessageChunk[] = []; - for await (const chunk of res) { - resArray.push(chunk); - } - expect(resArray).toBeDefined(); - expect(resArray.length).toBeGreaterThanOrEqual(1); - - const lastChunk = resArray[resArray.length - 1]; - expect(lastChunk).toBeDefined(); - expect(lastChunk._getType()).toEqual("ai"); - const aiChunk = lastChunk as AIMessageChunk; - console.log(aiChunk); - - console.log(JSON.stringify(resArray, null, 2)); - } catch (e) { - console.error(e); - throw e; - } - }); - - test("function", async () => { - const tools: GeminiTool[] = [ - { - functionDeclarations: [ - { - name: "test", - description: - "Run a test with a specific name and get if it passed or failed", - parameters: { - type: "object", - properties: { - testName: { - type: "string", - description: "The name of the test that should be run.", - }, - }, - required: ["testName"], - }, - }, - ], - }, - ]; - const model = new ChatGoogle().bind({ tools }); - const result = await model.invoke("Run a test on the cobalt project"); - expect(result).toHaveProperty("content"); - expect(result.content).toBe(""); - const args = result?.lc_kwargs?.additional_kwargs; - expect(args).toBeDefined(); - expect(args).toHaveProperty("tool_calls"); - expect(Array.isArray(args.tool_calls)).toBeTruthy(); - expect(args.tool_calls).toHaveLength(1); - const call = args.tool_calls[0]; - expect(call).toHaveProperty("type"); - expect(call.type).toBe("function"); - expect(call).toHaveProperty("function"); - const func = call.function; - expect(func).toBeDefined(); - expect(func).toHaveProperty("name"); - expect(func.name).toBe("test"); - expect(func).toHaveProperty("arguments"); - expect(typeof func.arguments).toBe("string"); - expect(func.arguments.replaceAll("\n", "")).toBe('{"testName":"cobalt"}'); - }); - - test("function reply", async () => { - const tools: GeminiTool[] = [ - { - functionDeclarations: [ - { - name: "test", - description: - "Run a test with a specific name and get if it passed or failed", - parameters: { - type: "object", - properties: { - testName: { - type: "string", - description: "The name of the test that should be run.", - }, - }, - required: ["testName"], - }, - }, - ], - }, - ]; - const model = new ChatGoogle().bind({ tools }); - const toolResult = { - testPassed: true, - }; - const messages: BaseMessageLike[] = [ - new HumanMessage("Run a test on the cobalt project."), - new AIMessage("", { - tool_calls: [ - { - id: "test", - type: "function", - function: { - name: "test", - arguments: '{"testName":"cobalt"}', - }, - }, - ], - }), - new ToolMessage(JSON.stringify(toolResult), "test"), - ]; - const res = await model.stream(messages); - const resArray: BaseMessageChunk[] = []; - for await (const chunk of res) { - resArray.push(chunk); - } - console.log(JSON.stringify(resArray, null, 2)); - }); - - test("withStructuredOutput", async () => { - const tool = { - name: "get_weather", - description: - "Get the weather of a specific location and return the temperature in Celsius.", - parameters: { - type: "object", - properties: { - location: { - type: "string", - description: "The name of city to get the weather for.", - }, - }, - required: ["location"], - }, - }; - const model = new ChatGoogle().withStructuredOutput(tool); - const result = await model.invoke("What is the weather in Paris?"); - expect(result).toHaveProperty("location"); - }); -}); diff --git a/libs/langchain-google-gauth/src/tests/llms.int.test.ts b/libs/langchain-google-gauth/src/tests/llms.int.test.ts deleted file mode 100644 index 61d2b77e11be..000000000000 --- a/libs/langchain-google-gauth/src/tests/llms.int.test.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { test } from "@jest/globals"; -import { - AIMessage, - BaseMessage, - HumanMessageChunk, - MessageContentComplex, -} from "@langchain/core/messages"; -import { ChatPromptValue } from "@langchain/core/prompt_values"; -import { GoogleLLM } from "../llms.js"; - -const imgData = { - blueSquare: - "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6AIbFwQSRaexCAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAJklEQVQY02P8//8/A27AxIAXsEAor31f0CS2OfEQ1j2Q0owU+RsAGNUJD2/04PgAAAAASUVORK5CYII=", -}; - -describe("GAuth LLM", () => { - test("platform", async () => { - const model = new GoogleLLM(); - expect(model.platform).toEqual("gcp"); - }); - - test("call", async () => { - const model = new GoogleLLM(); - try { - const res = await model.invoke("1 + 1 = "); - if (res.length === 1) { - expect(res).toBe("2"); - } else { - expect(res.length).toBeGreaterThan(0); - console.log("call result:", res); - } - } catch (xx) { - console.error(xx); - throw xx; - } - }); - - test("generate", async () => { - const model = new GoogleLLM(); - const res = await model.generate(["Print hello world."]); - expect(res).toHaveProperty("generations"); - expect(res.generations.length).toBeGreaterThan(0); - expect(res.generations[0].length).toBeGreaterThan(0); - expect(res.generations[0][0]).toHaveProperty("text"); - console.log("generate result:", JSON.stringify(res, null, 2)); - }); - - test("stream", async () => { - const model = new GoogleLLM(); - const stream = await model.stream( - "What is the answer to live, the universe, and everything? Be verbose." - ); - const chunks = []; - for await (const chunk of stream) { - chunks.push(chunk); - } - expect(chunks.length).toBeGreaterThan(1); - }); - - test("predictMessage image", async () => { - const model = new GoogleLLM({ - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const res = await model.predictMessages(messages); - expect(res).toBeInstanceOf(AIMessage); - expect(Array.isArray(res.content)).toEqual(true); - expect(res.content[0]).toHaveProperty("text"); - console.log("res", res); - }); - - test("invoke image", async () => { - const model = new GoogleLLM({ - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const input = new ChatPromptValue(messages); - const res = await model.invoke(input); - expect(res).toBeDefined(); - expect(res.length).toBeGreaterThan(0); - console.log("res", res); - }); -}); - -describe.skip("GAuth LLM gai", () => { - test("platform", async () => { - const model = new GoogleLLM({ - platformType: "gai", - }); - expect(model.platform).toEqual("gai"); - }); - - /* - * This test currently fails in AI Studio due to zealous safety systems - */ - test.skip("call", async () => { - const model = new GoogleLLM({ - platformType: "gai", - }); - try { - const res = await model.invoke("1 + 1 = "); - if (res.length === 1) { - expect(res).toBe("2"); - } else { - console.log("call result:", res); - expect(res.length).toBeGreaterThan(0); - } - } catch (xx) { - console.error(xx); - throw xx; - } - }); - - test("call", async () => { - const model = new GoogleLLM({ - platformType: "gai", - }); - try { - const res = await model.invoke("If the time is 1:00, what time is it?"); - expect(res.length).toBeGreaterThan(0); - expect(res.substring(0, 4)).toEqual("1:00"); - } catch (xx) { - console.error(xx); - throw xx; - } - }); - - test("generate", async () => { - const model = new GoogleLLM({ - platformType: "gai", - }); - const res = await model.generate(["Print hello world."]); - expect(res).toHaveProperty("generations"); - expect(res.generations.length).toBeGreaterThan(0); - expect(res.generations[0].length).toBeGreaterThan(0); - expect(res.generations[0][0]).toHaveProperty("text"); - console.log("generate result:", JSON.stringify(res, null, 2)); - }); - - test("stream", async () => { - const model = new GoogleLLM({ - platformType: "gai", - }); - const stream = await model.stream( - "What is the answer to live, the universe, and everything? Be verbose." - ); - const chunks = []; - try { - for await (const chunk of stream) { - chunks.push(chunk); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (xx: any) { - expect(xx?.message).toEqual("Finish reason: RECITATION"); - } - expect(chunks.length).toBeGreaterThan(1); - }); - - test("predictMessage image", async () => { - const model = new GoogleLLM({ - platformType: "gai", - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const res = await model.predictMessages(messages); - expect(res).toBeInstanceOf(AIMessage); - expect(Array.isArray(res.content)).toEqual(true); - expect(res.content[0]).toHaveProperty("text"); - console.log("res", res); - }); - - test("invoke image", async () => { - const model = new GoogleLLM({ - platformType: "gai", - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const input = new ChatPromptValue(messages); - const res = await model.invoke(input); - expect(res).toBeDefined(); - expect(res.length).toBeGreaterThan(0); - console.log("res", res); - }); -}); diff --git a/libs/langchain-google-vertexai-web/src/tests/chat_models.int.test.ts b/libs/langchain-google-vertexai-web/src/tests/chat_models.int.test.ts index e737d61d0bdf..38db387d36dc 100644 --- a/libs/langchain-google-vertexai-web/src/tests/chat_models.int.test.ts +++ b/libs/langchain-google-vertexai-web/src/tests/chat_models.int.test.ts @@ -166,6 +166,27 @@ describe("Google APIKey Chat", () => { console.log(res2); expect(res2.content).toContain("24"); }); + + test("withStructuredOutput", async () => { + const tool = { + name: "get_weather", + description: + "Get the weather of a specific location and return the temperature in Celsius.", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "The name of city to get the weather for.", + }, + }, + required: ["location"], + }, + }; + const model = new ChatVertexAI().withStructuredOutput(tool); + const result = await model.invoke("What is the weather in Paris?"); + expect(result).toHaveProperty("location"); + }); }); describe("Google Webauth Chat", () => { diff --git a/libs/langchain-google-vertexai-web/src/tests/llms.int.test.ts b/libs/langchain-google-vertexai-web/src/tests/llms.int.test.ts index 2b8155710edf..cf92f36d2bae 100644 --- a/libs/langchain-google-vertexai-web/src/tests/llms.int.test.ts +++ b/libs/langchain-google-vertexai-web/src/tests/llms.int.test.ts @@ -108,86 +108,6 @@ describe("Google APIKey LLM", () => { }); }); -describe("Google WebAuth LLM", () => { - test("platform", async () => { - const model = new VertexAI(); - expect(model.platform).toEqual("gcp"); - }); - - test("call", async () => { - const model = new VertexAI(); - const res = await model.invoke("1 + 1 = "); - if (res.length === 1) { - expect(res).toBe("2"); - } else { - expect(res.length).toBeGreaterThan(0); - console.log("call result:", res); - } - }); - - test("stream", async () => { - const model = new VertexAI(); - const stream = await model.stream( - "What is the answer to live, the universe, and everything? Be verbose." - ); - const chunks = []; - for await (const chunk of stream) { - chunks.push(chunk); - } - expect(chunks.length).toBeGreaterThan(1); - }); - - test("predictMessage image", async () => { - const model = new VertexAI({ - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const res = await model.predictMessages(messages); - expect(res).toBeInstanceOf(AIMessage); - expect(Array.isArray(res.content)).toEqual(true); - expect(res.content[0]).toHaveProperty("text"); - console.log("res", res); - }); - - test("invoke image", async () => { - const model = new VertexAI({ - modelName: "gemini-pro-vision", - }); - const message: MessageContentComplex[] = [ - { - type: "text", - text: "What is in this image?", - }, - { - type: "image_url", - image_url: `data:image/png;base64,${imgData.blueSquare}`, - }, - ]; - - const messages: BaseMessage[] = [ - new HumanMessageChunk({ content: message }), - ]; - const input = new ChatPromptValue(messages); - const res = await model.invoke(input); - expect(res).toBeDefined(); - expect(res.length).toBeGreaterThan(0); - console.log("res", res); - }); -}); - describe("Google WebAuth gai LLM", () => { test("platform", async () => { const model = new VertexAI({ diff --git a/libs/langchain-google-vertexai/src/tests/chat_models.int.test.ts b/libs/langchain-google-vertexai/src/tests/chat_models.int.test.ts index 0f43cadc95aa..4ba3eccdf073 100644 --- a/libs/langchain-google-vertexai/src/tests/chat_models.int.test.ts +++ b/libs/langchain-google-vertexai/src/tests/chat_models.int.test.ts @@ -1,6 +1,4 @@ import { test } from "@jest/globals"; -// eslint-disable-next-line import/no-extraneous-dependencies -import { z } from "zod"; import { BaseLanguageModelInput } from "@langchain/core/language_models/base"; import { ChatPromptValue } from "@langchain/core/prompt_values"; import { @@ -8,21 +6,15 @@ import { AIMessageChunk, BaseMessage, BaseMessageChunk, + BaseMessageLike, HumanMessage, - // MessageContentComplex, - // MessageContentText, SystemMessage, + ToolMessage, } from "@langchain/core/messages"; -import { ConsoleCallbackHandler } from "@langchain/core/tracers/console"; import { ChatVertexAI } from "../chat_models.js"; -import { VertexAI } from "../llms.js"; +import { GeminiTool } from "../types.js"; describe("GAuth Chat", () => { - test("platform", async () => { - const model = new VertexAI(); - expect(model.platform).toEqual("gcp"); - }); - test("invoke", async () => { const model = new ChatVertexAI(); try { @@ -126,29 +118,118 @@ describe("GAuth Chat", () => { } }); - test("structuredOutput", async () => { - const handler = new ConsoleCallbackHandler(); - - const calculatorSchema = z.object({ - operation: z - .enum(["add", "subtract", "multiply", "divide"]) - .describe("The type of operation to execute"), - number1: z.number().describe("The first number to operate on."), - number2: z.number().describe("The second number to operate on."), - }); - - const model = new ChatVertexAI({ - temperature: 0.7, - model: "gemini-1.0-pro", - callbacks: [handler], - }).withStructuredOutput(calculatorSchema); - - const response = await model.invoke("What is 1628253239 times 81623836?"); - expect(response).toHaveProperty("operation"); - expect(response.operation).toEqual("multiply"); - expect(response).toHaveProperty("number1"); - expect(response.number1).toEqual(1628253239); - expect(response).toHaveProperty("number2"); - expect(response.number2).toEqual(81623836); + test("function", async () => { + const tools: GeminiTool[] = [ + { + functionDeclarations: [ + { + name: "test", + description: + "Run a test with a specific name and get if it passed or failed", + parameters: { + type: "object", + properties: { + testName: { + type: "string", + description: "The name of the test that should be run.", + }, + }, + required: ["testName"], + }, + }, + ], + }, + ]; + const model = new ChatVertexAI().bind({ tools }); + const result = await model.invoke("Run a test on the cobalt project"); + expect(result).toHaveProperty("content"); + expect(result.content).toBe(""); + const args = result?.lc_kwargs?.additional_kwargs; + expect(args).toBeDefined(); + expect(args).toHaveProperty("tool_calls"); + expect(Array.isArray(args.tool_calls)).toBeTruthy(); + expect(args.tool_calls).toHaveLength(1); + const call = args.tool_calls[0]; + expect(call).toHaveProperty("type"); + expect(call.type).toBe("function"); + expect(call).toHaveProperty("function"); + const func = call.function; + expect(func).toBeDefined(); + expect(func).toHaveProperty("name"); + expect(func.name).toBe("test"); + expect(func).toHaveProperty("arguments"); + expect(typeof func.arguments).toBe("string"); + expect(func.arguments.replaceAll("\n", "")).toBe('{"testName":"cobalt"}'); + }); + + test("function reply", async () => { + const tools: GeminiTool[] = [ + { + functionDeclarations: [ + { + name: "test", + description: + "Run a test with a specific name and get if it passed or failed", + parameters: { + type: "object", + properties: { + testName: { + type: "string", + description: "The name of the test that should be run.", + }, + }, + required: ["testName"], + }, + }, + ], + }, + ]; + const model = new ChatVertexAI().bind({ tools }); + const toolResult = { + testPassed: true, + }; + const messages: BaseMessageLike[] = [ + new HumanMessage("Run a test on the cobalt project."), + new AIMessage("", { + tool_calls: [ + { + id: "test", + type: "function", + function: { + name: "test", + arguments: '{"testName":"cobalt"}', + }, + }, + ], + }), + new ToolMessage(JSON.stringify(toolResult), "test"), + ]; + const res = await model.stream(messages); + const resArray: BaseMessageChunk[] = []; + for await (const chunk of res) { + resArray.push(chunk); + } + console.log(JSON.stringify(resArray, null, 2)); + }); + + test("withStructuredOutput", async () => { + const tool = { + name: "get_weather", + description: + "Get the weather of a specific location and return the temperature in Celsius.", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "The name of city to get the weather for.", + }, + }, + required: ["location"], + }, + }; + const model = new ChatVertexAI().withStructuredOutput(tool); + const result = await model.invoke("What is the weather in Paris?"); + expect(result).toHaveProperty("location"); }); });