Skip to content

Commit

Permalink
Update minor version in package.json, 2
Browse files Browse the repository at this point in the history
  • Loading branch information
aulorbe committed Nov 15, 2024
1 parent 5b0ee8b commit 2e85ee4
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 25 deletions.
4 changes: 2 additions & 2 deletions libs/langchain-pinecone/jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ module.exports = {
setupFiles: ["dotenv/config"],
testTimeout: 20_000,
passWithNoTests: true,
collectCoverageFrom: ["src/**/*.ts"]
};
collectCoverageFrom: ["src/**/*.ts"],
};
9 changes: 6 additions & 3 deletions libs/langchain-pinecone/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { Pinecone, PineconeConfiguration } from "@pinecone-database/pinecone";
import { getEnvironmentVariable } from "@langchain/core/utils/env";

export function getPineconeClient(config?: PineconeConfiguration): Pinecone {
if (getEnvironmentVariable("PINECONE_API_KEY") === undefined) {
if (
getEnvironmentVariable("PINECONE_API_KEY") === undefined ||
getEnvironmentVariable("PINECONE_API_KEY") === ""
) {
throw new Error("PINECONE_API_KEY must be set in environment");
}
if (!config) {
return new Pinecone()
return new Pinecone();
} else {
return new Pinecone(config);
}
}
}
43 changes: 29 additions & 14 deletions libs/langchain-pinecone/src/embeddings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable arrow-body-style */

import { Embeddings, type EmbeddingsParams } from "@langchain/core/embeddings";
import {
EmbeddingsList,
Expand Down Expand Up @@ -57,23 +59,32 @@ export class PineconeEmbeddings
}
}

// @returns A promise that resolves to an array of vectors for each document.
async embedDocuments(texts: string[]): Promise<number[][]> {
if (texts.length === 0) {
throw new Error(
"At least one document is required to generate embeddings"
);
}

let embeddings: EmbeddingsList;
let embeddings;
if (this.params) {
embeddings = await this.client.inference.embed(
this.model,
texts,
this.params
);
embeddings = await this.caller.call(async () => {
const result: EmbeddingsList = await this.client.inference.embed(
this.model,
texts,
this.params
);
return result;
});
} else {
embeddings = await this.client.inference.embed(this.model, texts, {});
embeddings = await this.caller.call(async () => {
const result: EmbeddingsList = await this.client.inference.embed(
this.model,
texts,
{}
);
return result;
});
}

const embeddingsList: number[][] = [];
Expand All @@ -95,13 +106,17 @@ export class PineconeEmbeddings
}
let embeddings: EmbeddingsList;
if (this.params) {
embeddings = await this.client.inference.embed(
this.model,
[text],
this.params
);
embeddings = await this.caller.call(async () => {
return await this.client.inference.embed(
this.model,
[text],
this.params
);
});
} else {
embeddings = await this.client.inference.embed(this.model, [text], {});
embeddings = await this.caller.call(async () => {
return await this.client.inference.embed(this.model, [text], {});
});
}
if (embeddings[0].values) {
return embeddings[0].values as number[];
Expand Down
39 changes: 39 additions & 0 deletions libs/langchain-pinecone/src/tests/client.int.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Pinecone } from "@pinecone-database/pinecone";
import { getPineconeClient } from "../client.js";

describe("Tests for getPineconeClient", () => {
test("Happy path for getPineconeClient with and without `config` obj passed", async () => {
const client = getPineconeClient();
expect(client).toBeInstanceOf(Pinecone);
expect(client).toHaveProperty("config"); // Config is always set to *at least* the user's api key

const clientWithConfig = getPineconeClient({
// eslint-disable-next-line no-process-env
apiKey: process.env.PINECONE_API_KEY!,
additionalHeaders: { header: "value" },
});
expect(clientWithConfig).toBeInstanceOf(Pinecone);
expect(client).toHaveProperty("config"); // Unfortunately cannot assert on contents of config b/c it's a private
// attribute of the Pinecone class
});

test("Unhappy path: expect getPineconeClient to throw error if reset PINECONE_API_KEY to empty string", async () => {
// eslint-disable-next-line no-process-env
const originalApiKey = process.env.PINECONE_API_KEY;
try {
// eslint-disable-next-line no-process-env
process.env.PINECONE_API_KEY = "";
const errorThrown = async () => {
getPineconeClient();
};
await expect(errorThrown).rejects.toThrow(Error);
await expect(errorThrown).rejects.toThrow(
"PINECONE_API_KEY must be set in environment"
);
} finally {
// Restore the original value of PINECONE_API_KEY
// eslint-disable-next-line no-process-env
process.env.PINECONE_API_KEY = originalApiKey;
}
});
});
43 changes: 43 additions & 0 deletions libs/langchain-pinecone/src/tests/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Pinecone, PineconeConfiguration } from "@pinecone-database/pinecone";
import { jest } from "@jest/globals";
import { getPineconeClient } from "../client.js";

// Mock the Pinecone class
jest.mock("@pinecone-database/pinecone", () => ({
Pinecone: jest.fn().mockImplementation((config) => ({
config,
inference: { embed: jest.fn() },
})),
}));

describe("Tests for getPineconeClient", () => {
test("Confirm getPineconeClient throws error when PINECONE_API_KEY is not set", async () => {
/* eslint-disable-next-line no-process-env */
process.env.PINECONE_API_KEY = "";
const errorThrown = async () => {
getPineconeClient();
};
await expect(errorThrown).rejects.toThrow(Error);
await expect(errorThrown).rejects.toThrow(
"PINECONE_API_KEY must be set in environment"
);
});

test("Confirm getPineconeClient calls Pinecone class (mocked) with and without config", async () => {
/* eslint-disable-next-line no-process-env */
process.env.PINECONE_API_KEY = "some-valid-api-key";

// With config
// Note: cannot assert on config contents themselves b/c `config` is a private attribute of the Pinecone class
const config: PineconeConfiguration = {
apiKey: "some-valid-api-key",
additionalHeaders: { header: "value" },
};
getPineconeClient(config);
expect(Pinecone).toHaveBeenCalledWith(config);

// Without config
getPineconeClient();
expect(Pinecone).toHaveBeenCalledWith();
});
});
8 changes: 2 additions & 6 deletions libs/langchain-pinecone/src/tests/translator.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,7 @@ describe("Pinecone self query", () => {
// !process.env.PINECONE_ENVIRONMENT ||
!testIndexName
) {
throw new Error(
"PINECONE_API_KEY and PINECONE_INDEX must be set"
);
throw new Error("PINECONE_API_KEY and PINECONE_INDEX must be set");
}

const embeddings = new OpenAIEmbeddings();
Expand Down Expand Up @@ -273,9 +271,7 @@ describe("Pinecone self query", () => {
// !process.env.PINECONE_ENVIRONMENT ||
!testIndexName
) {
throw new Error(
"PINECONE_API_KEY and PINECONE_INDEX must be set"
);
throw new Error("PINECONE_API_KEY and PINECONE_INDEX must be set");
}

const embeddings = new OpenAIEmbeddings();
Expand Down

0 comments on commit 2e85ee4

Please sign in to comment.