Skip to content

Commit

Permalink
partners[minor]: Add standard chat model tests to partner packages (#…
Browse files Browse the repository at this point in the history
…5660)

* partners[minor]: Add standard chat model tests to partner packages

* google genai

* yarn

* groq

* groq nit and mistral

* add to azure in chat openai

* chore: lint files

* drop azure openai pkg

* add generic constructor args to standard tests pkg

* implement cloudflare standard tests

* implement cohere standard tests

* google genai package standard tests

* groq

* allow for custom function call ids, fix mistral

* azure tests

* chore: lint files

* update standard tests gh action to run all pkgs

* chore: lint files

* revert workflow file rename

* fix workflow job naming issue

* add anthropic, fix api keys

* cache deps?

* fix build

* update standard tests

* cr

* fix

* remove dep on job which doesnt exist

* cr

* cr
  • Loading branch information
bracesproul authored Jun 4, 2024
1 parent 1959ca7 commit e834086
Show file tree
Hide file tree
Showing 28 changed files with 829 additions and 106 deletions.
57 changes: 53 additions & 4 deletions .github/workflows/standard-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ name: Standard Tests (Integration)
on:
workflow_dispatch:
schedule:
- cron: '0 13 * * *'
- cron: '0 13 * * *'

jobs:
openai:
standard-tests:
runs-on: ubuntu-latest
strategy:
matrix:
package: [anthropic, cohere, google-genai, groq, mistralai]
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18.x
Expand All @@ -17,7 +20,53 @@ jobs:
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
- name: Run standard tests (integration)
run: yarn test:standard:int --filter=@langchain/openai
- name: Run standard tests (integration) for ${{ matrix.package }}
run: yarn test:standard:int --filter=@langchain/${{ matrix.package }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}

# The `@langchain/openai` package contains standard tests for ChatOpenAI and AzureChatOpenAI
# We want to run these separately, so we need to pass the exact path for each test, which means
# we need separate jobs for each test.
standard-tests-openai:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
- name: Build `@langchain/openai`
run: yarn build --filter=@langchain/openai
- name: Run standard tests (integration) for ChatOpenAI
run: yarn workspace @langchain/openai test:single src/tests/chat_models.standard.int.test.ts
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

standard-tests-azure-openai:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
- name: Build `@langchain/openai`
run: yarn build --filter=@langchain/openai
- name: Run standard tests (integration) for `@langchain/openai` AzureChatOpenAI
run: yarn workspace @langchain/openai test:single src/tests/azure/chat_models.standard.int.test.ts
env:
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_API_DEPLOYMENT_NAME: "chat"
AZURE_OPENAI_API_VERSION: ${{ secrets.AZURE_OPENAI_API_VERSION }}
AZURE_OPENAI_BASE_PATH: ${{ secrets.AZURE_OPENAI_BASE_PATH }}
17 changes: 5 additions & 12 deletions libs/langchain-azure-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,18 @@
"scripts": {
"build": "yarn turbo:command build:internal --filter=@langchain/azure-openai",
"build:internal": "yarn lc-build:v2 --create-entrypoints --pre --tree-shaking",
"build:deps": "yarn run turbo:command build --filter=@langchain/core",
"build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/",
"build:cjs": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist-cjs/ -p tsconfig.cjs.json && yarn move-cjs-to-dist && rimraf dist-cjs",
"build:watch": "yarn create-entrypoints && tsc --outDir dist/ --watch",
"build:scripts": "yarn create-entrypoints && yarn check-tree-shaking",
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
"lint": "yarn lint:eslint && yarn lint:dpdm",
"lint:fix": "yarn lint:eslint --fix && yarn lint:dpdm",
"clean": "rm -rf .turbo dist/",
"prepack": "yarn build",
"test": "yarn run build:deps && 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:single": "yarn run build:deps && NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000",
"test": "NODE_OPTIONS=--experimental-vm-modules jest --testPathIgnorePatterns=\\.int\\.test.ts --testTimeout 30000 --maxWorkers=50%",
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --testPathIgnorePatterns=\\.int\\.test.ts",
"test:single": "NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000",
"test:int": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"format": "prettier --config .prettierrc --write \"src\"",
"format:check": "prettier --config .prettierrc --check \"src\"",
"move-cjs-to-dist": "yarn lc-build --config ./langchain.config.js --move-cjs-dist",
"create-entrypoints": "yarn lc-build --config ./langchain.config.js --create-entrypoints",
"check-tree-shaking": "yarn lc-build --config ./langchain.config.js --tree-shaking"
"format:check": "prettier --config .prettierrc --check \"src\""
},
"author": "LangChain",
"license": "MIT",
Expand All @@ -50,6 +42,7 @@
"@azure/identity": "^4.0.1",
"@jest/globals": "^29.5.0",
"@langchain/scripts": "~0.0.14",
"@langchain/standard-tests": "workspace:*",
"@swc/core": "^1.3.90",
"@swc/jest": "^0.2.29",
"dpdm": "^3.12.0",
Expand Down
13 changes: 5 additions & 8 deletions libs/langchain-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
"scripts": {
"build": "yarn turbo:command build:internal --filter=@langchain/cloudflare",
"build:internal": "yarn lc-build:v2 --create-entrypoints --pre --tree-shaking",
"build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
"build:cjs": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist-cjs/ -p tsconfig.cjs.json && yarn move-cjs-to-dist && rm -rf dist-cjs",
"build:watch": "yarn create-entrypoints && tsc --outDir dist/ --watch",
"build:scripts": "yarn create-entrypoints && yarn check-tree-shaking",
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
"lint": "yarn lint:eslint && yarn lint:dpdm",
Expand All @@ -30,11 +26,11 @@
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --testPathIgnorePatterns=\\.int\\.test.ts",
"test:single": "NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000",
"test:int": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard:unit": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.standard\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard:int": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.standard\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard": "yarn test:standard:unit && yarn test:standard:int",
"format": "prettier --config .prettierrc --write \"src\"",
"format:check": "prettier --config .prettierrc --check \"src\"",
"move-cjs-to-dist": "yarn lc-build --config ./langchain.config.js --move-cjs-dist",
"create-entrypoints": "yarn lc-build --config ./langchain.config.js --create-entrypoints",
"check-tree-shaking": "yarn lc-build --config ./langchain.config.js --tree-shaking"
"format:check": "prettier --config .prettierrc --check \"src\""
},
"author": "LangChain",
"license": "MIT",
Expand All @@ -47,6 +43,7 @@
"@cloudflare/workers-types": "^4.20231218.0",
"@jest/globals": "^29.5.0",
"@langchain/scripts": "~0.0.14",
"@langchain/standard-tests": "workspace:*",
"@swc/core": "^1.3.90",
"@swc/jest": "^0.2.29",
"@tsconfig/recommended": "^1.0.3",
Expand Down
10 changes: 10 additions & 0 deletions libs/langchain-cloudflare/src/chat_models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
LangSmithParams,
SimpleChatModel,
type BaseChatModelParams,
} from "@langchain/core/language_models/chat_models";
Expand Down Expand Up @@ -81,6 +82,15 @@ export class ChatCloudflareWorkersAI
}
}

getLsParams(options: this["ParsedCallOptions"]): LangSmithParams {
return {
ls_provider: "openai",
ls_model_name: this.model,
ls_model_type: "chat",
ls_stop: options.stop,
};
}

get lc_secrets(): { [key: string]: string } | undefined {
return {
cloudflareApiToken: "CLOUDFLARE_API_TOKEN",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-process-env */
import { test, expect } from "@jest/globals";
import { ChatModelIntegrationTests } from "@langchain/standard-tests";
import { AIMessageChunk } from "@langchain/core/messages";
import {
ChatCloudflareWorkersAI,
ChatCloudflareWorkersAICallOptions,
} from "../chat_models.js";

class ChatCloudflareWorkersAIStandardIntegrationTests extends ChatModelIntegrationTests<
ChatCloudflareWorkersAICallOptions,
AIMessageChunk
> {
constructor() {
if (
!process.env.CLOUDFLARE_ACCOUNT_ID ||
!process.env.CLOUDFLARE_API_TOKEN
) {
throw new Error(
"Skipping Cloudflare Workers AI integration tests because CLOUDFLARE_ACCOUNT_ID or CLOUDFLARE_API_TOKEN is not set"
);
}
super({
Cls: ChatCloudflareWorkersAI,
chatModelHasToolCalling: false,
chatModelHasStructuredOutput: false,
constructorArgs: {},
});
}

async testUsageMetadataStreaming() {
this.skipTestMessage(
"testUsageMetadataStreaming",
"ChatCloudflareWorkersAI",
"Streaming tokens is not currently supported."
);
}

async testUsageMetadata() {
this.skipTestMessage(
"testUsageMetadata",
"ChatCloudflareWorkersAI",
"Usage metadata tokens is not currently supported."
);
}
}

const testClass = new ChatCloudflareWorkersAIStandardIntegrationTests();

test("ChatCloudflareWorkersAIStandardIntegrationTests", async () => {
const testResults = await testClass.runTests();
expect(testResults).toBe(true);
});
50 changes: 50 additions & 0 deletions libs/langchain-cloudflare/src/tests/chat_models.standard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable no-process-env */
import { test, expect } from "@jest/globals";
import { ChatModelUnitTests } from "@langchain/standard-tests";
import { AIMessageChunk } from "@langchain/core/messages";
import { LangSmithParams } from "@langchain/core/language_models/chat_models";
import {
ChatCloudflareWorkersAI,
ChatCloudflareWorkersAICallOptions,
} from "../chat_models.js";

class ChatCloudflareWorkersAIStandardUnitTests extends ChatModelUnitTests<
ChatCloudflareWorkersAICallOptions,
AIMessageChunk
> {
constructor() {
super({
Cls: ChatCloudflareWorkersAI,
chatModelHasToolCalling: false,
chatModelHasStructuredOutput: false,
constructorArgs: {},
});
}

testChatModelInitApiKey() {
this.skipTestMessage(
"testChatModelInitApiKey",
"ChatCloudflareWorkersAI",
this.multipleApiKeysRequiredMessage
);
}

expectedLsParams(): Partial<LangSmithParams> {
console.warn(
"Overriding testStandardParams. ChatCloudflareWorkersAI does not support temperature or max tokens."
);
return {
ls_provider: "string",
ls_model_name: "string",
ls_model_type: "chat",
ls_stop: ["Array<string>"],
};
}
}

const testClass = new ChatCloudflareWorkersAIStandardUnitTests();

test("ChatCloudflareWorkersAIStandardUnitTests", () => {
const testResults = testClass.runTests();
expect(testResults).toBe(true);
});
13 changes: 5 additions & 8 deletions libs/langchain-cohere/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
"scripts": {
"build": "yarn turbo:command build:internal --filter=@langchain/cohere",
"build:internal": "yarn lc-build:v2 --create-entrypoints --pre --tree-shaking",
"build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
"build:cjs": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist-cjs/ -p tsconfig.cjs.json && yarn move-cjs-to-dist && rm -rf dist-cjs",
"build:watch": "yarn create-entrypoints && tsc --outDir dist/ --watch",
"build:scripts": "yarn create-entrypoints && yarn check-tree-shaking",
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
"lint": "yarn lint:eslint && yarn lint:dpdm",
Expand All @@ -30,11 +26,11 @@
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --testPathIgnorePatterns=\\.int\\.test.ts",
"test:single": "NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000",
"test:int": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard:unit": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.standard\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard:int": "NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.standard\\.int\\.test.ts --testTimeout 100000 --maxWorkers=50%",
"test:standard": "yarn test:standard:unit && yarn test:standard:int",
"format": "prettier --config .prettierrc --write \"src\"",
"format:check": "prettier --config .prettierrc --check \"src\"",
"move-cjs-to-dist": "yarn lc-build --config ./langchain.config.js --move-cjs-dist",
"create-entrypoints": "yarn lc-build --config ./langchain.config.js --create-entrypoints",
"check-tree-shaking": "yarn lc-build --config ./langchain.config.js --tree-shaking"
"format:check": "prettier --config .prettierrc --check \"src\""
},
"author": "LangChain",
"license": "MIT",
Expand All @@ -45,6 +41,7 @@
"devDependencies": {
"@jest/globals": "^29.5.0",
"@langchain/scripts": "~0.0.14",
"@langchain/standard-tests": "workspace:*",
"@swc/core": "^1.3.90",
"@swc/jest": "^0.2.29",
"@tsconfig/recommended": "^1.0.3",
Expand Down
2 changes: 1 addition & 1 deletion libs/langchain-cohere/src/chat_models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ interface TokenUsage {
totalTokens?: number;
}

interface CohereChatCallOptions
export interface CohereChatCallOptions
extends BaseLanguageModelCallOptions,
Partial<Omit<Cohere.ChatRequest, "message">>,
Partial<Omit<Cohere.ChatStreamRequest, "message">> {}
Expand Down
47 changes: 47 additions & 0 deletions libs/langchain-cohere/src/tests/chat_models.standard.int.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* eslint-disable no-process-env */
import { test, expect } from "@jest/globals";
import { ChatModelIntegrationTests } from "@langchain/standard-tests";
import { AIMessageChunk } from "@langchain/core/messages";
import { ChatCohere, CohereChatCallOptions } from "../chat_models.js";

class ChatCohereStandardIntegrationTests extends ChatModelIntegrationTests<
CohereChatCallOptions,
AIMessageChunk
> {
constructor() {
if (!process.env.COHERE_API_KEY) {
throw new Error(
"Can not run Cohere integration tests because COHERE_API_KEY is not set"
);
}
super({
Cls: ChatCohere,
chatModelHasToolCalling: false,
chatModelHasStructuredOutput: false,
constructorArgs: {},
});
}

async testUsageMetadataStreaming() {
this.skipTestMessage(
"testUsageMetadataStreaming",
"ChatCohere",
"Streaming tokens is not currently supported."
);
}

async testUsageMetadata() {
this.skipTestMessage(
"testUsageMetadata",
"ChatCohere",
"Usage metadata tokens is not currently supported."
);
}
}

const testClass = new ChatCohereStandardIntegrationTests();

test("ChatCohereStandardIntegrationTests", async () => {
const testResults = await testClass.runTests();
expect(testResults).toBe(true);
});
Loading

0 comments on commit e834086

Please sign in to comment.