From 286499388dffab6deb86c46f6b2174df4cf4b7a5 Mon Sep 17 00:00:00 2001 From: Alex Yang <himself65@outlook.com> Date: Mon, 22 Apr 2024 02:13:29 -0500 Subject: [PATCH] fix: agent class should implement ChatEngine interface (#746) --- packages/core/e2e/node/claude.e2e.ts | 6 ++- packages/core/e2e/node/openai.e2e.ts | 24 ++++++++---- packages/core/e2e/tsconfig.json | 11 ++---- packages/core/src/agent/base.ts | 39 ++++++++++++++----- packages/core/src/cloud/LlamaCloudIndex.ts | 4 +- .../chat/CondenseQuestionChatEngine.ts | 6 +-- packages/core/src/engines/chat/types.ts | 16 ++++---- .../src/engines/query/RetrieverQueryEngine.ts | 7 +--- .../src/engines/query/RouterQueryEngine.ts | 8 ++-- .../engines/query/SubQuestionQueryEngine.ts | 7 +--- packages/core/src/indices/BaseIndex.ts | 4 +- packages/core/src/indices/keyword/index.ts | 4 +- packages/core/src/indices/summary/index.ts | 4 +- .../core/src/indices/vectorStore/index.ts | 4 +- packages/core/src/tools/QueryEngineTool.ts | 6 +-- packages/core/src/types.ts | 2 +- .../edge/e2e/test-edge-runtime/package.json | 2 +- .../src/engines/query/JSONQueryEngine.ts | 4 +- pnpm-lock.yaml | 11 +----- 19 files changed, 92 insertions(+), 77 deletions(-) diff --git a/packages/core/e2e/node/claude.e2e.ts b/packages/core/e2e/node/claude.e2e.ts index 1afda5e5b..c22a717f2 100644 --- a/packages/core/e2e/node/claude.e2e.ts +++ b/packages/core/e2e/node/claude.e2e.ts @@ -2,7 +2,7 @@ import { consola } from "consola"; import { Anthropic, FunctionTool, Settings, type LLM } from "llamaindex"; import { AnthropicAgent } from "llamaindex/agent/anthropic"; import { extractText } from "llamaindex/llm/utils"; -import { ok } from "node:assert"; +import { ok, strictEqual } from "node:assert"; import { beforeEach, test } from "node:test"; import { sumNumbersTool } from "./fixtures/tools.js"; import { mockLLMEvent } from "./utils.js"; @@ -71,10 +71,12 @@ await test("anthropic agent", async (t) => { }, ], }); - const { response } = await agent.chat({ + const { response, sources } = await agent.chat({ message: "What is the weather in San Francisco?", }); consola.debug("response:", response.message.content); + + strictEqual(sources.length, 1); ok(extractText(response.message.content).includes("35")); }); diff --git a/packages/core/e2e/node/openai.e2e.ts b/packages/core/e2e/node/openai.e2e.ts index 5bd086915..0d18634e3 100644 --- a/packages/core/e2e/node/openai.e2e.ts +++ b/packages/core/e2e/node/openai.e2e.ts @@ -13,6 +13,7 @@ import { SummaryIndex, VectorStoreIndex, type LLM, + type ToolOutput, } from "llamaindex"; import { extractText } from "llamaindex/llm/utils"; import { ok, strictEqual } from "node:assert"; @@ -222,10 +223,12 @@ await test("agent with object function call", async (t) => { ), ], }); - const { response } = await agent.chat({ + const { response, sources } = await agent.chat({ message: "What is the weather in San Francisco?", }); consola.debug("response:", response.message.content); + + strictEqual(sources.length, 1); ok(extractText(response.message.content).includes("72")); }); }); @@ -253,10 +256,12 @@ await test("agent", async (t) => { }, ], }); - const { response } = await agent.chat({ + const { response, sources } = await agent.chat({ message: "What is the weather in San Francisco?", }); consola.debug("response:", response.message.content); + + strictEqual(sources.length, 1); ok(extractText(response.message.content).includes("35")); }); @@ -290,9 +295,10 @@ await test("agent", async (t) => { const agent = new OpenAIAgent({ tools: [showUniqueId], }); - const { response } = await agent.chat({ + const { response, sources } = await agent.chat({ message: "My name is Alex Yang. What is my unique id?", }); + strictEqual(sources.length, 1); ok(extractText(response.message.content).includes(uniqueId)); }); @@ -301,10 +307,11 @@ await test("agent", async (t) => { tools: [sumNumbersTool], }); - const { response } = await openaiAgent.chat({ + const { response, sources } = await openaiAgent.chat({ message: "how much is 1 + 1?", }); + strictEqual(sources.length, 1); ok(extractText(response.message.content).includes("2")); }); }); @@ -319,18 +326,21 @@ await test("agent stream", async (t) => { tools: [sumNumbersTool, divideNumbersTool], }); - const { response } = await agent.chat({ + const stream = await agent.chat({ message: "Divide 16 by 2 then add 20", stream: true, }); let message = ""; + let soruces: ToolOutput[] = []; - for await (const chunk of response) { - message += chunk.delta; + for await (const { response, sources: _sources } of stream) { + message += response.delta; + soruces = _sources; } strictEqual(fn.mock.callCount(), 2); + strictEqual(soruces.length, 2); ok(message.includes("28")); Settings.callbackManager.off("llm-tool-call", fn); }); diff --git a/packages/core/e2e/tsconfig.json b/packages/core/e2e/tsconfig.json index 409139772..6260e0875 100644 --- a/packages/core/e2e/tsconfig.json +++ b/packages/core/e2e/tsconfig.json @@ -4,14 +4,11 @@ "outDir": "./lib", "module": "node16", "moduleResolution": "node16", - "target": "ESNext" + "target": "ESNext", + "lib": ["ES2022"], + "types": ["node"] }, - "include": [ - "./**/*.ts", - "./mock-module.js", - "./mock-register.js", - "./fixtures" - ], + "include": ["./node", "./mock-module.js", "./mock-register.js", "./fixtures"], "references": [ { "path": "../../core/tsconfig.json" diff --git a/packages/core/src/agent/base.ts b/packages/core/src/agent/base.ts index 9c1b804c5..0a65937e1 100644 --- a/packages/core/src/agent/base.ts +++ b/packages/core/src/agent/base.ts @@ -1,5 +1,6 @@ import { pipeline, randomUUID } from "@llamaindex/env"; import { + type ChatEngine, type ChatEngineParamsNonStreaming, type ChatEngineParamsStreaming, } from "../engines/chat/index.js"; @@ -171,8 +172,9 @@ export async function* createTaskImpl< } export type AgentStreamChatResponse<Options extends object> = { - response: ReadableStream<ChatResponseChunk<Options>>; - sources: ToolOutput[]; + response: ChatResponseChunk<Options>; + // sources of the response, will emit when new tool outputs are available + sources?: ToolOutput[]; }; export type AgentChatResponse<Options extends object> = { @@ -276,7 +278,12 @@ export abstract class AgentRunner< > ? AdditionalMessageOptions : never, -> { +> implements + ChatEngine< + AgentChatResponse<AdditionalMessageOptions>, + ReadableStream<AgentStreamChatResponse<AdditionalMessageOptions>> + > +{ readonly #llm: AI; readonly #tools: | BaseToolWithCall[] @@ -370,13 +377,13 @@ export abstract class AgentRunner< ): Promise<AgentChatResponse<AdditionalMessageOptions>>; async chat( params: ChatEngineParamsStreaming, - ): Promise<AgentStreamChatResponse<AdditionalMessageOptions>>; + ): Promise<ReadableStream<AgentStreamChatResponse<AdditionalMessageOptions>>>; @wrapEventCaller async chat( params: ChatEngineParamsNonStreaming | ChatEngineParamsStreaming, ): Promise< | AgentChatResponse<AdditionalMessageOptions> - | AgentStreamChatResponse<AdditionalMessageOptions> + | ReadableStream<AgentStreamChatResponse<AdditionalMessageOptions>> > { const task = await this.createTask(params.message, !!params.stream); const stepOutput = await pipeline( @@ -397,14 +404,26 @@ export abstract class AgentRunner< const { output, taskStep } = stepOutput; this.#chatHistory = [...taskStep.context.store.messages]; if (isAsyncIterable(output)) { - return { - response: output, - sources: [...taskStep.context.store.toolOutputs], - } satisfies AgentStreamChatResponse<AdditionalMessageOptions>; + return output.pipeThrough< + AgentStreamChatResponse<AdditionalMessageOptions> + >( + new TransformStream({ + transform(chunk, controller) { + controller.enqueue({ + response: chunk, + get sources() { + return [...taskStep.context.store.toolOutputs]; + }, + }); + }, + }), + ); } else { return { response: output, - sources: [...taskStep.context.store.toolOutputs], + get sources() { + return [...taskStep.context.store.toolOutputs]; + }, } satisfies AgentChatResponse<AdditionalMessageOptions>; } } diff --git a/packages/core/src/cloud/LlamaCloudIndex.ts b/packages/core/src/cloud/LlamaCloudIndex.ts index 94c0d03c7..0445313db 100644 --- a/packages/core/src/cloud/LlamaCloudIndex.ts +++ b/packages/core/src/cloud/LlamaCloudIndex.ts @@ -5,7 +5,7 @@ import { RetrieverQueryEngine } from "../engines/query/RetrieverQueryEngine.js"; import type { TransformComponent } from "../ingestion/types.js"; import type { BaseNodePostprocessor } from "../postprocessors/types.js"; import type { BaseSynthesizer } from "../synthesizers/types.js"; -import type { BaseQueryEngine } from "../types.js"; +import type { QueryEngine } from "../types.js"; import type { CloudRetrieveParams } from "./LlamaCloudRetriever.js"; import { LlamaCloudRetriever } from "./LlamaCloudRetriever.js"; import { getPipelineCreate } from "./config.js"; @@ -178,7 +178,7 @@ export class LlamaCloudIndex { preFilters?: unknown; nodePostprocessors?: BaseNodePostprocessor[]; } & CloudRetrieveParams, - ): BaseQueryEngine { + ): QueryEngine { const retriever = new LlamaCloudRetriever({ ...this.params, ...params, diff --git a/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts b/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts index 6e629c1d4..2f885bfb5 100644 --- a/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts +++ b/packages/core/src/engines/chat/CondenseQuestionChatEngine.ts @@ -12,7 +12,7 @@ import { wrapEventCaller } from "../../internal/context/EventCaller.js"; import type { ChatMessage, LLM } from "../../llm/index.js"; import { extractText, streamReducer } from "../../llm/utils.js"; import { PromptMixin } from "../../prompts/index.js"; -import type { BaseQueryEngine } from "../../types.js"; +import type { QueryEngine } from "../../types.js"; import type { ChatEngine, ChatEngineParamsNonStreaming, @@ -33,13 +33,13 @@ export class CondenseQuestionChatEngine extends PromptMixin implements ChatEngine { - queryEngine: BaseQueryEngine; + queryEngine: QueryEngine; chatHistory: ChatHistory; llm: LLM; condenseMessagePrompt: CondenseQuestionPrompt; constructor(init: { - queryEngine: BaseQueryEngine; + queryEngine: QueryEngine; chatHistory: ChatMessage[]; serviceContext?: ServiceContext; condenseMessagePrompt?: CondenseQuestionPrompt; diff --git a/packages/core/src/engines/chat/types.ts b/packages/core/src/engines/chat/types.ts index a3d554156..d81e0035a 100644 --- a/packages/core/src/engines/chat/types.ts +++ b/packages/core/src/engines/chat/types.ts @@ -23,21 +23,21 @@ export interface ChatEngineParamsNonStreaming extends ChatEngineParamsBase { stream?: false | null; } -export interface ChatEngineAgentParams extends ChatEngineParamsBase { - toolChoice?: string | Record<string, any>; - stream?: boolean; -} - /** * A ChatEngine is used to handle back and forth chats between the application and the LLM. */ -export interface ChatEngine { +export interface ChatEngine< + // synchronous response + R = Response, + // asynchronous response + AR extends AsyncIterable<unknown> = AsyncIterable<R>, +> { /** * Send message along with the class's current chat history to the LLM. * @param params */ - chat(params: ChatEngineParamsStreaming): Promise<AsyncIterable<Response>>; - chat(params: ChatEngineParamsNonStreaming): Promise<Response>; + chat(params: ChatEngineParamsStreaming): Promise<AR>; + chat(params: ChatEngineParamsNonStreaming): Promise<R>; /** * Resets the chat history so that it's empty. diff --git a/packages/core/src/engines/query/RetrieverQueryEngine.ts b/packages/core/src/engines/query/RetrieverQueryEngine.ts index da8d617a9..153cb4265 100644 --- a/packages/core/src/engines/query/RetrieverQueryEngine.ts +++ b/packages/core/src/engines/query/RetrieverQueryEngine.ts @@ -7,7 +7,7 @@ import { PromptMixin } from "../../prompts/Mixin.js"; import type { BaseSynthesizer } from "../../synthesizers/index.js"; import { ResponseSynthesizer } from "../../synthesizers/index.js"; import type { - BaseQueryEngine, + QueryEngine, QueryEngineParamsNonStreaming, QueryEngineParamsStreaming, } from "../../types.js"; @@ -15,10 +15,7 @@ import type { /** * A query engine that uses a retriever to query an index and then synthesizes the response. */ -export class RetrieverQueryEngine - extends PromptMixin - implements BaseQueryEngine -{ +export class RetrieverQueryEngine extends PromptMixin implements QueryEngine { retriever: BaseRetriever; responseSynthesizer: BaseSynthesizer; nodePostprocessors: BaseNodePostprocessor[]; diff --git a/packages/core/src/engines/query/RouterQueryEngine.ts b/packages/core/src/engines/query/RouterQueryEngine.ts index 925fcfe6a..197fec076 100644 --- a/packages/core/src/engines/query/RouterQueryEngine.ts +++ b/packages/core/src/engines/query/RouterQueryEngine.ts @@ -7,14 +7,14 @@ import type { BaseSelector } from "../../selectors/index.js"; import { LLMSingleSelector } from "../../selectors/index.js"; import { TreeSummarize } from "../../synthesizers/index.js"; import type { - BaseQueryEngine, QueryBundle, + QueryEngine, QueryEngineParamsNonStreaming, QueryEngineParamsStreaming, } from "../../types.js"; type RouterQueryEngineTool = { - queryEngine: BaseQueryEngine; + queryEngine: QueryEngine; description: string; }; @@ -54,9 +54,9 @@ async function combineResponses( /** * A query engine that uses multiple query engines and selects the best one. */ -export class RouterQueryEngine extends PromptMixin implements BaseQueryEngine { +export class RouterQueryEngine extends PromptMixin implements QueryEngine { private selector: BaseSelector; - private queryEngines: BaseQueryEngine[]; + private queryEngines: QueryEngine[]; private metadatas: RouterQueryEngineMetadata[]; private summarizer: TreeSummarize; private verbose: boolean; diff --git a/packages/core/src/engines/query/SubQuestionQueryEngine.ts b/packages/core/src/engines/query/SubQuestionQueryEngine.ts index b06e40e96..188e0ab9a 100644 --- a/packages/core/src/engines/query/SubQuestionQueryEngine.ts +++ b/packages/core/src/engines/query/SubQuestionQueryEngine.ts @@ -11,8 +11,8 @@ import { } from "../../synthesizers/index.js"; import type { - BaseQueryEngine, BaseTool, + QueryEngine, QueryEngineParamsNonStreaming, QueryEngineParamsStreaming, ToolMetadata, @@ -24,10 +24,7 @@ import type { BaseQuestionGenerator, SubQuestion } from "./types.js"; /** * SubQuestionQueryEngine decomposes a question into subquestions and then */ -export class SubQuestionQueryEngine - extends PromptMixin - implements BaseQueryEngine -{ +export class SubQuestionQueryEngine extends PromptMixin implements QueryEngine { responseSynthesizer: BaseSynthesizer; questionGen: BaseQuestionGenerator; queryEngines: BaseTool[]; diff --git a/packages/core/src/indices/BaseIndex.ts b/packages/core/src/indices/BaseIndex.ts index 2cce62428..69f9a79b9 100644 --- a/packages/core/src/indices/BaseIndex.ts +++ b/packages/core/src/indices/BaseIndex.ts @@ -8,7 +8,7 @@ import type { BaseDocumentStore } from "../storage/docStore/types.js"; import type { BaseIndexStore } from "../storage/indexStore/types.js"; import type { VectorStore } from "../storage/vectorStore/types.js"; import type { BaseSynthesizer } from "../synthesizers/types.js"; -import type { BaseQueryEngine } from "../types.js"; +import type { QueryEngine } from "../types.js"; import { IndexStruct } from "./IndexStruct.js"; import { IndexStructType } from "./json-to-index-struct.js"; @@ -87,7 +87,7 @@ export abstract class BaseIndex<T> { abstract asQueryEngine(options?: { retriever?: BaseRetriever; responseSynthesizer?: BaseSynthesizer; - }): BaseQueryEngine; + }): QueryEngine; /** * Insert a document into the index. diff --git a/packages/core/src/indices/keyword/index.ts b/packages/core/src/indices/keyword/index.ts index 2f0441e0c..06d59fed6 100644 --- a/packages/core/src/indices/keyword/index.ts +++ b/packages/core/src/indices/keyword/index.ts @@ -17,7 +17,7 @@ import type { StorageContext } from "../../storage/StorageContext.js"; import { storageContextFromDefaults } from "../../storage/StorageContext.js"; import type { BaseDocumentStore } from "../../storage/docStore/types.js"; import type { BaseSynthesizer } from "../../synthesizers/index.js"; -import type { BaseQueryEngine } from "../../types.js"; +import type { QueryEngine } from "../../types.js"; import type { BaseIndexInit } from "../BaseIndex.js"; import { BaseIndex, KeywordTable } from "../BaseIndex.js"; import { IndexStructType } from "../json-to-index-struct.js"; @@ -234,7 +234,7 @@ export class KeywordTableIndex extends BaseIndex<KeywordTable> { responseSynthesizer?: BaseSynthesizer; preFilters?: unknown; nodePostprocessors?: BaseNodePostprocessor[]; - }): BaseQueryEngine { + }): QueryEngine { const { retriever, responseSynthesizer } = options ?? {}; return new RetrieverQueryEngine( retriever ?? this.asRetriever(), diff --git a/packages/core/src/indices/summary/index.ts b/packages/core/src/indices/summary/index.ts index 54f381738..3a29cd0ac 100644 --- a/packages/core/src/indices/summary/index.ts +++ b/packages/core/src/indices/summary/index.ts @@ -23,7 +23,7 @@ import { CompactAndRefine, ResponseSynthesizer, } from "../../synthesizers/index.js"; -import type { BaseQueryEngine } from "../../types.js"; +import type { QueryEngine } from "../../types.js"; import type { BaseIndexInit } from "../BaseIndex.js"; import { BaseIndex } from "../BaseIndex.js"; import { IndexList, IndexStructType } from "../json-to-index-struct.js"; @@ -171,7 +171,7 @@ export class SummaryIndex extends BaseIndex<IndexList> { responseSynthesizer?: BaseSynthesizer; preFilters?: unknown; nodePostprocessors?: BaseNodePostprocessor[]; - }): BaseQueryEngine & RetrieverQueryEngine { + }): QueryEngine & RetrieverQueryEngine { let { retriever, responseSynthesizer } = options ?? {}; if (!retriever) { diff --git a/packages/core/src/indices/vectorStore/index.ts b/packages/core/src/indices/vectorStore/index.ts index c2818d3bd..cac64098b 100644 --- a/packages/core/src/indices/vectorStore/index.ts +++ b/packages/core/src/indices/vectorStore/index.ts @@ -37,7 +37,7 @@ import type { import type { BaseIndexStore } from "../../storage/indexStore/types.js"; import { VectorStoreQueryMode } from "../../storage/vectorStore/types.js"; import type { BaseSynthesizer } from "../../synthesizers/types.js"; -import type { BaseQueryEngine } from "../../types.js"; +import type { QueryEngine } from "../../types.js"; import type { BaseIndexInit } from "../BaseIndex.js"; import { BaseIndex } from "../BaseIndex.js"; import { IndexDict, IndexStructType } from "../json-to-index-struct.js"; @@ -284,7 +284,7 @@ export class VectorStoreIndex extends BaseIndex<IndexDict> { responseSynthesizer?: BaseSynthesizer; preFilters?: MetadataFilters; nodePostprocessors?: BaseNodePostprocessor[]; - }): BaseQueryEngine & RetrieverQueryEngine { + }): QueryEngine & RetrieverQueryEngine { const { retriever, responseSynthesizer } = options ?? {}; return new RetrieverQueryEngine( retriever ?? this.asRetriever(), diff --git a/packages/core/src/tools/QueryEngineTool.ts b/packages/core/src/tools/QueryEngineTool.ts index 9af842c29..d2c03ad93 100644 --- a/packages/core/src/tools/QueryEngineTool.ts +++ b/packages/core/src/tools/QueryEngineTool.ts @@ -1,5 +1,5 @@ import type { JSONSchemaType } from "ajv"; -import type { BaseQueryEngine, BaseTool, ToolMetadata } from "../types.js"; +import type { BaseTool, QueryEngine, ToolMetadata } from "../types.js"; const DEFAULT_NAME = "query_engine_tool"; const DEFAULT_DESCRIPTION = @@ -17,7 +17,7 @@ const DEFAULT_PARAMETERS: JSONSchemaType<QueryEngineParam> = { }; export type QueryEngineToolParams = { - queryEngine: BaseQueryEngine; + queryEngine: QueryEngine; metadata: ToolMetadata<JSONSchemaType<QueryEngineParam>>; }; @@ -26,7 +26,7 @@ export type QueryEngineParam = { }; export class QueryEngineTool implements BaseTool<QueryEngineParam> { - private queryEngine: BaseQueryEngine; + private queryEngine: QueryEngine; metadata: ToolMetadata<JSONSchemaType<QueryEngineParam>>; constructor({ queryEngine, metadata }: QueryEngineToolParams) { diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 7e95ea709..f18764943 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -22,7 +22,7 @@ export interface QueryEngineParamsNonStreaming extends QueryEngineParamsBase { /** * A query engine is a question answerer that can use one or more steps. */ -export interface BaseQueryEngine { +export interface QueryEngine { /** * Query the query engine and get a response. * @param params diff --git a/packages/edge/e2e/test-edge-runtime/package.json b/packages/edge/e2e/test-edge-runtime/package.json index ad68db43f..644dd5c1a 100644 --- a/packages/edge/e2e/test-edge-runtime/package.json +++ b/packages/edge/e2e/test-edge-runtime/package.json @@ -14,7 +14,7 @@ "react-dom": "^18" }, "devDependencies": { - "@types/node": "^20", + "@types/node": "^20.12.7", "@types/react": "^18", "@types/react-dom": "^18", "typescript": "^5" diff --git a/packages/experimental/src/engines/query/JSONQueryEngine.ts b/packages/experimental/src/engines/query/JSONQueryEngine.ts index 070a389fc..c91140796 100644 --- a/packages/experimental/src/engines/query/JSONQueryEngine.ts +++ b/packages/experimental/src/engines/query/JSONQueryEngine.ts @@ -5,7 +5,7 @@ import { Response } from "llamaindex"; import { serviceContextFromDefaults, type ServiceContext } from "llamaindex"; import type { - BaseQueryEngine, + QueryEngine, QueryEngineParamsNonStreaming, QueryEngineParamsStreaming, } from "llamaindex"; @@ -89,7 +89,7 @@ type OutputProcessor = typeof defaultOutputProcessor; /** * A JSON query engine that uses JSONPath to query a JSON object. */ -export class JSONQueryEngine implements BaseQueryEngine { +export class JSONQueryEngine implements QueryEngine { jsonValue: JSONSchemaType; jsonSchema: JSONSchemaType; serviceContext: ServiceContext; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 699e084a6..a0a8004b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -484,8 +484,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: ^20 - version: 20.11.20 + specifier: ^20.12.7 + version: 20.12.7 '@types/react': specifier: ^18 version: 18.2.65 @@ -2542,9 +2542,6 @@ packages: '@types/node@18.19.31': resolution: {integrity: sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==} - '@types/node@20.11.20': - resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} - '@types/node@20.12.7': resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} @@ -11356,10 +11353,6 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@20.11.20': - dependencies: - undici-types: 5.26.5 - '@types/node@20.12.7': dependencies: undici-types: 5.26.5 -- GitLab