From 0652352e9270f45c7b8eaada2bb8bd7fe50ac0b8 Mon Sep 17 00:00:00 2001
From: Alex Yang <himself65@outlook.com>
Date: Sat, 27 Jan 2024 00:46:04 -0600
Subject: [PATCH] chore: fix circular dependency (#459)

---
 .github/workflows/test.yml                    |  3 +
 packages/core/jest.config.cjs                 |  2 +-
 packages/core/package.json                    |  2 +-
 packages/core/src/OutputParser.ts             | 18 +---
 packages/core/src/Prompt.ts                   |  3 +-
 packages/core/src/QueryEngine.ts              | 44 +++-------
 packages/core/src/QuestionGenerator.ts        | 26 ++----
 packages/core/src/Tool.ts                     | 20 -----
 .../core/src/embeddings/OpenAIEmbedding.ts    |  2 +-
 packages/core/src/embeddings/types.ts         | 12 +--
 packages/core/src/embeddings/utils.ts         | 13 ++-
 .../chat/CondenseQuestionChatEngine.ts        |  2 +-
 packages/core/src/index.ts                    |  4 +-
 packages/core/src/indices/BaseIndex.ts        |  2 +-
 .../src/indices/keyword/KeywordTableIndex.ts  |  3 +-
 .../core/src/indices/summary/SummaryIndex.ts  |  3 +-
 .../indices/vectorStore/VectorStoreIndex.ts   |  3 +-
 packages/core/src/llm/LLM.ts                  |  4 +-
 packages/core/src/llm/index.ts                |  7 +-
 .../core/src/llm/{openai.ts => open_ai.ts}    |  0
 .../src/llm/{replicate.ts => replicate_ai.ts} |  2 -
 .../{AssemblyAI.ts => AssemblyAIReader.ts}    |  0
 .../storage/vectorStore/SimpleVectorStore.ts  |  2 +-
 .../core/src/tests/CallbackManager.test.ts    |  2 +-
 .../core/src/tests/MetadataExtractors.test.ts |  2 +-
 packages/core/src/types.ts                    | 82 +++++++++++++++++++
 26 files changed, 141 insertions(+), 122 deletions(-)
 delete mode 100644 packages/core/src/Tool.ts
 rename packages/core/src/llm/{openai.ts => open_ai.ts} (100%)
 rename packages/core/src/llm/{replicate.ts => replicate_ai.ts} (97%)
 rename packages/core/src/readers/{AssemblyAI.ts => AssemblyAIReader.ts} (100%)
 create mode 100644 packages/core/src/types.ts

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1a88479cd..7e03e5c97 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -36,3 +36,6 @@ jobs:
         working-directory: ./packages/core
       - name: Run Type Check
         run: pnpm run type-check
+      - name: Run Circular Dependency Check
+        run: pnpm run circular-check
+        working-directory: ./packages/core
diff --git a/packages/core/jest.config.cjs b/packages/core/jest.config.cjs
index b359e058b..3f6d6b147 100644
--- a/packages/core/jest.config.cjs
+++ b/packages/core/jest.config.cjs
@@ -2,5 +2,5 @@
 module.exports = {
   preset: "ts-jest",
   testEnvironment: "node",
-  testPathIgnorePatterns: ["/lib/"],
+  testPathIgnorePatterns: ["/lib/", "/node_modules/", "/dist/"],
 };
diff --git a/packages/core/package.json b/packages/core/package.json
index 8edcf06da..81523f32b 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -81,6 +81,6 @@
     "modify-package-json": "node ./scripts/modify-package-json.mjs",
     "prepublish": "pnpm run modify-package-json && echo \"please cd ./dist and run pnpm publish\" && exit 1",
     "dev": "bunchee -w",
-    "circular-check": "madge --circular ./src/*.ts"
+    "circular-check": "madge -c ./src/index.ts"
   }
 }
diff --git a/packages/core/src/OutputParser.ts b/packages/core/src/OutputParser.ts
index 12d96ceff..052eaf8c4 100644
--- a/packages/core/src/OutputParser.ts
+++ b/packages/core/src/OutputParser.ts
@@ -1,20 +1,4 @@
-import { SubQuestion } from "./QuestionGenerator";
-
-/**
- * An OutputParser is used to extract structured data from the raw output of the LLM.
- */
-export interface BaseOutputParser<T> {
-  parse(output: string): T;
-  format(output: string): string;
-}
-
-/**
- * StructuredOutput is just a combo of the raw output and the parsed output.
- */
-export interface StructuredOutput<T> {
-  rawOutput: string;
-  parsedOutput: T;
-}
+import { BaseOutputParser, StructuredOutput, SubQuestion } from "./types";
 
 /**
  * Error class for output parsing. Due to the nature of LLMs, anytime we use LLM
diff --git a/packages/core/src/Prompt.ts b/packages/core/src/Prompt.ts
index b89fe7720..8e181fb92 100644
--- a/packages/core/src/Prompt.ts
+++ b/packages/core/src/Prompt.ts
@@ -1,6 +1,5 @@
 import { ChatMessage } from "./llm/types";
-import { SubQuestion } from "./QuestionGenerator";
-import { ToolMetadata } from "./Tool";
+import { SubQuestion, ToolMetadata } from "./types";
 
 /**
  * A SimplePrompt is a function that takes a dictionary of inputs and returns a string.
diff --git a/packages/core/src/QueryEngine.ts b/packages/core/src/QueryEngine.ts
index 790930d71..8a3a2437e 100644
--- a/packages/core/src/QueryEngine.ts
+++ b/packages/core/src/QueryEngine.ts
@@ -1,13 +1,8 @@
 import { NodeWithScore, TextNode } from "./Node";
-import {
-  BaseQuestionGenerator,
-  LLMQuestionGenerator,
-  SubQuestion,
-} from "./QuestionGenerator";
+import { LLMQuestionGenerator } from "./QuestionGenerator";
 import { Response } from "./Response";
 import { BaseRetriever } from "./Retriever";
 import { ServiceContext, serviceContextFromDefaults } from "./ServiceContext";
-import { QueryEngineTool, ToolMetadata } from "./Tool";
 import { Event } from "./callbacks/CallbackManager";
 import { randomUUID } from "./env";
 import { BaseNodePostprocessor } from "./postprocessors";
@@ -16,34 +11,15 @@ import {
   CompactAndRefine,
   ResponseSynthesizer,
 } from "./synthesizers";
-
-/**
- * Parameters for sending a query.
- */
-export interface QueryEngineParamsBase {
-  query: string;
-  parentEvent?: Event;
-}
-
-export interface QueryEngineParamsStreaming extends QueryEngineParamsBase {
-  stream: true;
-}
-
-export interface QueryEngineParamsNonStreaming extends QueryEngineParamsBase {
-  stream?: false | null;
-}
-
-/**
- * A query engine is a question answerer that can use one or more steps.
- */
-export interface BaseQueryEngine {
-  /**
-   * Query the query engine and get a response.
-   * @param params
-   */
-  query(params: QueryEngineParamsStreaming): Promise<AsyncIterable<Response>>;
-  query(params: QueryEngineParamsNonStreaming): Promise<Response>;
-}
+import {
+  BaseQueryEngine,
+  BaseQuestionGenerator,
+  QueryEngineParamsNonStreaming,
+  QueryEngineParamsStreaming,
+  QueryEngineTool,
+  SubQuestion,
+  ToolMetadata,
+} from "./types";
 
 /**
  * A query engine that uses a retriever to query an index and then synthesizes the response.
diff --git a/packages/core/src/QuestionGenerator.ts b/packages/core/src/QuestionGenerator.ts
index eceac0303..b52ed5b04 100644
--- a/packages/core/src/QuestionGenerator.ts
+++ b/packages/core/src/QuestionGenerator.ts
@@ -1,28 +1,18 @@
-import {
-  BaseOutputParser,
-  StructuredOutput,
-  SubQuestionOutputParser,
-} from "./OutputParser";
+import { SubQuestionOutputParser } from "./OutputParser";
 import {
   SubQuestionPrompt,
   buildToolsText,
   defaultSubQuestionPrompt,
 } from "./Prompt";
-import { ToolMetadata } from "./Tool";
 import { OpenAI } from "./llm/LLM";
 import { LLM } from "./llm/types";
-
-export interface SubQuestion {
-  subQuestion: string;
-  toolName: string;
-}
-
-/**
- * QuestionGenerators generate new questions for the LLM using tools and a user query.
- */
-export interface BaseQuestionGenerator {
-  generate(tools: ToolMetadata[], query: string): Promise<SubQuestion[]>;
-}
+import {
+  BaseOutputParser,
+  BaseQuestionGenerator,
+  StructuredOutput,
+  SubQuestion,
+  ToolMetadata,
+} from "./types";
 
 /**
  * LLMQuestionGenerator uses the LLM to generate new questions for the LLM using tools and a user query.
diff --git a/packages/core/src/Tool.ts b/packages/core/src/Tool.ts
deleted file mode 100644
index 9474f358c..000000000
--- a/packages/core/src/Tool.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { BaseQueryEngine } from "./QueryEngine";
-
-export interface ToolMetadata {
-  description: string;
-  name: string;
-}
-
-/**
- * Simple Tool interface. Likely to change.
- */
-export interface BaseTool {
-  metadata: ToolMetadata;
-}
-
-/**
- * A Tool that uses a QueryEngine.
- */
-export interface QueryEngineTool extends BaseTool {
-  queryEngine: BaseQueryEngine;
-}
diff --git a/packages/core/src/embeddings/OpenAIEmbedding.ts b/packages/core/src/embeddings/OpenAIEmbedding.ts
index a777679f3..5fc469825 100644
--- a/packages/core/src/embeddings/OpenAIEmbedding.ts
+++ b/packages/core/src/embeddings/OpenAIEmbedding.ts
@@ -6,7 +6,7 @@ import {
   getAzureModel,
   shouldUseAzure,
 } from "../llm/azure";
-import { OpenAISession, getOpenAISession } from "../llm/openai";
+import { OpenAISession, getOpenAISession } from "../llm/open_ai";
 import { BaseEmbedding } from "./types";
 
 export const ALL_OPENAI_EMBEDDING_MODELS = {
diff --git a/packages/core/src/embeddings/types.ts b/packages/core/src/embeddings/types.ts
index b091c942c..bff218875 100644
--- a/packages/core/src/embeddings/types.ts
+++ b/packages/core/src/embeddings/types.ts
@@ -1,16 +1,6 @@
 import { BaseNode, MetadataMode } from "../Node";
 import { TransformComponent } from "../ingestion";
-import { similarity } from "./utils";
-
-/**
- * Similarity type
- * Default is cosine similarity. Dot product and negative Euclidean distance are also supported.
- */
-export enum SimilarityType {
-  DEFAULT = "cosine",
-  DOT_PRODUCT = "dot_product",
-  EUCLIDEAN = "euclidean",
-}
+import { SimilarityType, similarity } from "./utils";
 
 export abstract class BaseEmbedding implements TransformComponent {
   similarity(
diff --git a/packages/core/src/embeddings/utils.ts b/packages/core/src/embeddings/utils.ts
index 0c2ba7a28..803701a7b 100644
--- a/packages/core/src/embeddings/utils.ts
+++ b/packages/core/src/embeddings/utils.ts
@@ -2,8 +2,17 @@ import _ from "lodash";
 import { ImageType } from "../Node";
 import { DEFAULT_SIMILARITY_TOP_K } from "../constants";
 import { defaultFS } from "../env";
-import { VectorStoreQueryMode } from "../storage";
-import { SimilarityType } from "./types";
+import { VectorStoreQueryMode } from "../storage/vectorStore/types";
+
+/**
+ * Similarity type
+ * Default is cosine similarity. Dot product and negative Euclidean distance are also supported.
+ */
+export enum SimilarityType {
+  DEFAULT = "cosine",
+  DOT_PRODUCT = "dot_product",
+  EUCLIDEAN = "euclidean",
+}
 
 /**
  * The similarity between two embeddings.
diff --git a/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts b/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts
index 07ce7aad4..6d8e93b49 100644
--- a/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts
+++ b/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts
@@ -4,7 +4,6 @@ import {
   defaultCondenseQuestionPrompt,
   messagesToHistoryStr,
 } from "../../Prompt";
-import { BaseQueryEngine } from "../../QueryEngine";
 import { Response } from "../../Response";
 import {
   ServiceContext,
@@ -12,6 +11,7 @@ import {
 } from "../../ServiceContext";
 import { ChatMessage, LLM } from "../../llm";
 import { extractText, streamReducer } from "../../llm/utils";
+import { BaseQueryEngine } from "../../types";
 import {
   ChatEngine,
   ChatEngineParamsNonStreaming,
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index dd2e57fc5..a668a4b9e 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -10,7 +10,6 @@ export * from "./Response";
 export * from "./Retriever";
 export * from "./ServiceContext";
 export * from "./TextSplitter";
-export * from "./Tool";
 export * from "./callbacks/CallbackManager";
 export * from "./constants";
 export * from "./embeddings";
@@ -21,7 +20,7 @@ export * from "./ingestion";
 export * from "./llm";
 export * from "./nodeParsers";
 export * from "./postprocessors";
-export * from "./readers/AssemblyAI";
+export * from "./readers/AssemblyAIReader";
 export * from "./readers/CSVReader";
 export * from "./readers/DocxReader";
 export * from "./readers/HTMLReader";
@@ -33,3 +32,4 @@ export * from "./readers/SimpleMongoReader";
 export * from "./readers/base";
 export * from "./storage";
 export * from "./synthesizers";
+export type * from "./types";
diff --git a/packages/core/src/indices/BaseIndex.ts b/packages/core/src/indices/BaseIndex.ts
index 1f0ee6757..c63b38919 100644
--- a/packages/core/src/indices/BaseIndex.ts
+++ b/packages/core/src/indices/BaseIndex.ts
@@ -1,5 +1,4 @@
 import { BaseNode, Document, jsonToNode } from "../Node";
-import { BaseQueryEngine } from "../QueryEngine";
 import { BaseRetriever } from "../Retriever";
 import { ServiceContext } from "../ServiceContext";
 import { randomUUID } from "../env";
@@ -8,6 +7,7 @@ import { BaseDocumentStore } from "../storage/docStore/types";
 import { BaseIndexStore } from "../storage/indexStore/types";
 import { VectorStore } from "../storage/vectorStore/types";
 import { BaseSynthesizer } from "../synthesizers";
+import { BaseQueryEngine } from "../types";
 
 /**
  * The underlying structure of each index.
diff --git a/packages/core/src/indices/keyword/KeywordTableIndex.ts b/packages/core/src/indices/keyword/KeywordTableIndex.ts
index fe1ec7c81..8072aeb63 100644
--- a/packages/core/src/indices/keyword/KeywordTableIndex.ts
+++ b/packages/core/src/indices/keyword/KeywordTableIndex.ts
@@ -1,6 +1,6 @@
 import { BaseNode, Document, MetadataMode } from "../../Node";
 import { defaultKeywordExtractPrompt } from "../../Prompt";
-import { BaseQueryEngine, RetrieverQueryEngine } from "../../QueryEngine";
+import { RetrieverQueryEngine } from "../../QueryEngine";
 import { BaseRetriever } from "../../Retriever";
 import {
   ServiceContext,
@@ -13,6 +13,7 @@ import {
   storageContextFromDefaults,
 } from "../../storage";
 import { BaseSynthesizer } from "../../synthesizers";
+import { BaseQueryEngine } from "../../types";
 import {
   BaseIndex,
   BaseIndexInit,
diff --git a/packages/core/src/indices/summary/SummaryIndex.ts b/packages/core/src/indices/summary/SummaryIndex.ts
index 391685dd8..774dfac2a 100644
--- a/packages/core/src/indices/summary/SummaryIndex.ts
+++ b/packages/core/src/indices/summary/SummaryIndex.ts
@@ -1,6 +1,6 @@
 import _ from "lodash";
 import { BaseNode, Document } from "../../Node";
-import { BaseQueryEngine, RetrieverQueryEngine } from "../../QueryEngine";
+import { RetrieverQueryEngine } from "../../QueryEngine";
 import { BaseRetriever } from "../../Retriever";
 import {
   ServiceContext,
@@ -18,6 +18,7 @@ import {
   CompactAndRefine,
   ResponseSynthesizer,
 } from "../../synthesizers";
+import { BaseQueryEngine } from "../../types";
 import {
   BaseIndex,
   BaseIndexInit,
diff --git a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
index 64c9a90e2..832d46216 100644
--- a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
+++ b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
@@ -6,7 +6,7 @@ import {
   ObjectType,
   splitNodesByType,
 } from "../../Node";
-import { BaseQueryEngine, RetrieverQueryEngine } from "../../QueryEngine";
+import { RetrieverQueryEngine } from "../../QueryEngine";
 import { BaseRetriever } from "../../Retriever";
 import {
   ServiceContext,
@@ -26,6 +26,7 @@ import {
   storageContextFromDefaults,
 } from "../../storage";
 import { BaseSynthesizer } from "../../synthesizers";
+import { BaseQueryEngine } from "../../types";
 import {
   BaseIndex,
   BaseIndexInit,
diff --git a/packages/core/src/llm/LLM.ts b/packages/core/src/llm/LLM.ts
index aaaac65bf..3df872512 100644
--- a/packages/core/src/llm/LLM.ts
+++ b/packages/core/src/llm/LLM.ts
@@ -25,9 +25,9 @@ import {
   shouldUseAzure,
 } from "./azure";
 import { BaseLLM } from "./base";
-import { OpenAISession, getOpenAISession } from "./openai";
+import { OpenAISession, getOpenAISession } from "./open_ai";
 import { PortkeySession, getPortkeySession } from "./portkey";
-import { ReplicateSession } from "./replicate";
+import { ReplicateSession } from "./replicate_ai";
 import {
   ChatMessage,
   ChatResponse,
diff --git a/packages/core/src/llm/index.ts b/packages/core/src/llm/index.ts
index a76289989..16dcd5353 100644
--- a/packages/core/src/llm/index.ts
+++ b/packages/core/src/llm/index.ts
@@ -1,5 +1,10 @@
 export * from "./LLM";
-export * from "./mistral";
+export {
+  ALL_AVAILABLE_MISTRAL_MODELS,
+  MistralAI,
+  MistralAISession,
+} from "./mistral";
 export { Ollama } from "./ollama";
+export * from "./open_ai";
 export { TogetherLLM } from "./together";
 export * from "./types";
diff --git a/packages/core/src/llm/openai.ts b/packages/core/src/llm/open_ai.ts
similarity index 100%
rename from packages/core/src/llm/openai.ts
rename to packages/core/src/llm/open_ai.ts
diff --git a/packages/core/src/llm/replicate.ts b/packages/core/src/llm/replicate_ai.ts
similarity index 97%
rename from packages/core/src/llm/replicate.ts
rename to packages/core/src/llm/replicate_ai.ts
index 6716b631f..d452df38e 100644
--- a/packages/core/src/llm/replicate.ts
+++ b/packages/core/src/llm/replicate_ai.ts
@@ -28,5 +28,3 @@ export function getReplicateSession(replicateKey: string | null = null) {
 
   return defaultReplicateSession;
 }
-
-export * from "openai";
diff --git a/packages/core/src/readers/AssemblyAI.ts b/packages/core/src/readers/AssemblyAIReader.ts
similarity index 100%
rename from packages/core/src/readers/AssemblyAI.ts
rename to packages/core/src/readers/AssemblyAIReader.ts
diff --git a/packages/core/src/storage/vectorStore/SimpleVectorStore.ts b/packages/core/src/storage/vectorStore/SimpleVectorStore.ts
index 5c9170628..f4095e242 100644
--- a/packages/core/src/storage/vectorStore/SimpleVectorStore.ts
+++ b/packages/core/src/storage/vectorStore/SimpleVectorStore.ts
@@ -4,7 +4,7 @@ import {
   getTopKEmbeddings,
   getTopKEmbeddingsLearner,
   getTopKMMREmbeddings,
-} from "../../embeddings";
+} from "../../embeddings/utils";
 import { defaultFS, path } from "../../env";
 import { GenericFileSystem, exists } from "../FileSystem";
 import { DEFAULT_PERSIST_DIR } from "../constants";
diff --git a/packages/core/src/tests/CallbackManager.test.ts b/packages/core/src/tests/CallbackManager.test.ts
index da56efd1c..8c150a343 100644
--- a/packages/core/src/tests/CallbackManager.test.ts
+++ b/packages/core/src/tests/CallbackManager.test.ts
@@ -13,7 +13,7 @@ import { ResponseSynthesizer, SimpleResponseBuilder } from "../synthesizers";
 import { mockEmbeddingModel, mockLlmGeneration } from "./utility/mockOpenAI";
 
 // Mock the OpenAI getOpenAISession function during testing
-jest.mock("../llm/openai", () => {
+jest.mock("../llm/open_ai", () => {
   return {
     getOpenAISession: jest.fn().mockImplementation(() => null),
   };
diff --git a/packages/core/src/tests/MetadataExtractors.test.ts b/packages/core/src/tests/MetadataExtractors.test.ts
index 5d8ef8a35..57026943e 100644
--- a/packages/core/src/tests/MetadataExtractors.test.ts
+++ b/packages/core/src/tests/MetadataExtractors.test.ts
@@ -21,7 +21,7 @@ import {
 } from "./utility/mockOpenAI";
 
 // Mock the OpenAI getOpenAISession function during testing
-jest.mock("../llm/openai", () => {
+jest.mock("../llm/open_ai", () => {
   return {
     getOpenAISession: jest.fn().mockImplementation(() => null),
   };
diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts
new file mode 100644
index 000000000..4f38fdcaf
--- /dev/null
+++ b/packages/core/src/types.ts
@@ -0,0 +1,82 @@
+/**
+ * Top level types to avoid circular dependencies
+ */
+
+import { Event } from "./callbacks/CallbackManager";
+import { Response } from "./Response";
+
+/**
+ * Parameters for sending a query.
+ */
+export interface QueryEngineParamsBase {
+  query: string;
+  parentEvent?: Event;
+}
+
+export interface QueryEngineParamsStreaming extends QueryEngineParamsBase {
+  stream: true;
+}
+
+export interface QueryEngineParamsNonStreaming extends QueryEngineParamsBase {
+  stream?: false | null;
+}
+
+/**
+ * A query engine is a question answerer that can use one or more steps.
+ */
+export interface BaseQueryEngine {
+  /**
+   * Query the query engine and get a response.
+   * @param params
+   */
+  query(params: QueryEngineParamsStreaming): Promise<AsyncIterable<Response>>;
+  query(params: QueryEngineParamsNonStreaming): Promise<Response>;
+}
+
+/**
+ * Simple Tool interface. Likely to change.
+ */
+export interface BaseTool {
+  metadata: ToolMetadata;
+}
+
+/**
+ * A Tool that uses a QueryEngine.
+ */
+export interface QueryEngineTool extends BaseTool {
+  queryEngine: BaseQueryEngine;
+}
+
+export interface SubQuestion {
+  subQuestion: string;
+  toolName: string;
+}
+
+/**
+ * An OutputParser is used to extract structured data from the raw output of the LLM.
+ */
+export interface BaseOutputParser<T> {
+  parse(output: string): T;
+
+  format(output: string): string;
+}
+
+/**
+ * StructuredOutput is just a combo of the raw output and the parsed output.
+ */
+export interface StructuredOutput<T> {
+  rawOutput: string;
+  parsedOutput: T;
+}
+
+export interface ToolMetadata {
+  description: string;
+  name: string;
+}
+
+/**
+ * QuestionGenerators generate new questions for the LLM using tools and a user query.
+ */
+export interface BaseQuestionGenerator {
+  generate(tools: ToolMetadata[], query: string): Promise<SubQuestion[]>;
+}
-- 
GitLab