@langchain/classic 1.0.45 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/agents/agent.cjs.map +1 -1
- package/dist/agents/chat/index.cjs +2 -1
- package/dist/agents/chat/index.cjs.map +1 -1
- package/dist/agents/chat/index.js +2 -1
- package/dist/agents/chat/index.js.map +1 -1
- package/dist/agents/chat_convo/index.cjs +7 -5
- package/dist/agents/chat_convo/index.cjs.map +1 -1
- package/dist/agents/chat_convo/index.js +7 -5
- package/dist/agents/chat_convo/index.js.map +1 -1
- package/dist/agents/chat_convo/outputParser.cjs.map +1 -1
- package/dist/agents/executor.cjs +22 -19
- package/dist/agents/executor.cjs.map +1 -1
- package/dist/agents/executor.js +22 -19
- package/dist/agents/executor.js.map +1 -1
- package/dist/agents/format_scratchpad/log_to_message.cjs.map +1 -1
- package/dist/agents/format_scratchpad/openai_functions.cjs.map +1 -1
- package/dist/agents/mrkl/index.cjs +9 -6
- package/dist/agents/mrkl/index.cjs.map +1 -1
- package/dist/agents/mrkl/index.js +9 -6
- package/dist/agents/mrkl/index.js.map +1 -1
- package/dist/agents/mrkl/outputParser.d.cts +1 -1
- package/dist/agents/mrkl/outputParser.d.ts +1 -1
- package/dist/agents/openai_functions/index.cjs +2 -1
- package/dist/agents/openai_functions/index.cjs.map +1 -1
- package/dist/agents/openai_functions/index.js +2 -1
- package/dist/agents/openai_functions/index.js.map +1 -1
- package/dist/agents/openai_functions/output_parser.cjs.map +1 -1
- package/dist/agents/openai_tools/index.cjs.map +1 -1
- package/dist/agents/openai_tools/output_parser.cjs.map +1 -1
- package/dist/agents/react/output_parser.cjs.map +1 -1
- package/dist/agents/structured_chat/index.cjs +6 -5
- package/dist/agents/structured_chat/index.cjs.map +1 -1
- package/dist/agents/structured_chat/index.js +6 -5
- package/dist/agents/structured_chat/index.js.map +1 -1
- package/dist/agents/structured_chat/outputParser.cjs.map +1 -1
- package/dist/agents/tool_calling/output_parser.cjs.map +1 -1
- package/dist/agents/toolkits/conversational_retrieval/token_buffer_memory.cjs.map +1 -1
- package/dist/agents/toolkits/conversational_retrieval/tool.cjs +2 -1
- package/dist/agents/toolkits/conversational_retrieval/tool.cjs.map +1 -1
- package/dist/agents/toolkits/conversational_retrieval/tool.js +2 -1
- package/dist/agents/toolkits/conversational_retrieval/tool.js.map +1 -1
- package/dist/agents/toolkits/json/json.cjs +10 -8
- package/dist/agents/toolkits/json/json.cjs.map +1 -1
- package/dist/agents/toolkits/json/json.js +10 -8
- package/dist/agents/toolkits/json/json.js.map +1 -1
- package/dist/agents/toolkits/openapi/openapi.cjs +12 -9
- package/dist/agents/toolkits/openapi/openapi.cjs.map +1 -1
- package/dist/agents/toolkits/openapi/openapi.js +12 -9
- package/dist/agents/toolkits/openapi/openapi.js.map +1 -1
- package/dist/agents/toolkits/sql/sql.cjs +10 -8
- package/dist/agents/toolkits/sql/sql.cjs.map +1 -1
- package/dist/agents/toolkits/sql/sql.js +10 -8
- package/dist/agents/toolkits/sql/sql.js.map +1 -1
- package/dist/agents/toolkits/vectorstore/vectorstore.cjs +20 -16
- package/dist/agents/toolkits/vectorstore/vectorstore.cjs.map +1 -1
- package/dist/agents/toolkits/vectorstore/vectorstore.js +20 -16
- package/dist/agents/toolkits/vectorstore/vectorstore.js.map +1 -1
- package/dist/agents/xml/index.cjs +2 -1
- package/dist/agents/xml/index.cjs.map +1 -1
- package/dist/agents/xml/index.js +2 -1
- package/dist/agents/xml/index.js.map +1 -1
- package/dist/chains/base.cjs.map +1 -1
- package/dist/chains/chat_vector_db_chain.cjs +2 -1
- package/dist/chains/chat_vector_db_chain.cjs.map +1 -1
- package/dist/chains/chat_vector_db_chain.js +2 -1
- package/dist/chains/chat_vector_db_chain.js.map +1 -1
- package/dist/chains/conversational_retrieval_chain.cjs +2 -1
- package/dist/chains/conversational_retrieval_chain.cjs.map +1 -1
- package/dist/chains/conversational_retrieval_chain.js +2 -1
- package/dist/chains/conversational_retrieval_chain.js.map +1 -1
- package/dist/chains/openai_functions/base.cjs.map +1 -1
- package/dist/chains/openai_functions/extraction.cjs.map +1 -1
- package/dist/chains/openai_functions/openapi.cjs +9 -8
- package/dist/chains/openai_functions/openapi.cjs.map +1 -1
- package/dist/chains/openai_functions/openapi.js +9 -8
- package/dist/chains/openai_functions/openapi.js.map +1 -1
- package/dist/chains/openai_functions/tagging.cjs.map +1 -1
- package/dist/chains/openai_moderation.cjs.map +1 -1
- package/dist/chains/query_constructor/index.cjs +15 -9
- package/dist/chains/query_constructor/index.cjs.map +1 -1
- package/dist/chains/query_constructor/index.js +15 -9
- package/dist/chains/query_constructor/index.js.map +1 -1
- package/dist/chains/query_constructor/parser.cjs +12 -6
- package/dist/chains/query_constructor/parser.cjs.map +1 -1
- package/dist/chains/query_constructor/parser.js +12 -6
- package/dist/chains/query_constructor/parser.js.map +1 -1
- package/dist/chains/question_answering/load.cjs +35 -29
- package/dist/chains/question_answering/load.cjs.map +1 -1
- package/dist/chains/question_answering/load.js +35 -29
- package/dist/chains/question_answering/load.js.map +1 -1
- package/dist/chains/router/multi_prompt.cjs +5 -3
- package/dist/chains/router/multi_prompt.cjs.map +1 -1
- package/dist/chains/router/multi_prompt.js +5 -3
- package/dist/chains/router/multi_prompt.js.map +1 -1
- package/dist/chains/router/multi_retrieval_qa.cjs +18 -11
- package/dist/chains/router/multi_retrieval_qa.cjs.map +1 -1
- package/dist/chains/router/multi_retrieval_qa.js +18 -11
- package/dist/chains/router/multi_retrieval_qa.js.map +1 -1
- package/dist/chains/sequential_chain.cjs +6 -5
- package/dist/chains/sequential_chain.cjs.map +1 -1
- package/dist/chains/sequential_chain.js +6 -5
- package/dist/chains/sequential_chain.js.map +1 -1
- package/dist/chains/sql_db/sql_db_chain.cjs +2 -1
- package/dist/chains/sql_db/sql_db_chain.cjs.map +1 -1
- package/dist/chains/sql_db/sql_db_chain.js +2 -1
- package/dist/chains/sql_db/sql_db_chain.js.map +1 -1
- package/dist/chains/summarization/load.cjs +35 -29
- package/dist/chains/summarization/load.cjs.map +1 -1
- package/dist/chains/summarization/load.js +35 -29
- package/dist/chains/summarization/load.js.map +1 -1
- package/dist/chat_models/universal.cjs +12 -10
- package/dist/chat_models/universal.cjs.map +1 -1
- package/dist/chat_models/universal.js +12 -10
- package/dist/chat_models/universal.js.map +1 -1
- package/dist/document_loaders/fs/buffer.cjs.map +1 -1
- package/dist/document_loaders/fs/directory.cjs.map +1 -1
- package/dist/document_loaders/fs/multi_file.cjs.map +1 -1
- package/dist/document_loaders/fs/text.cjs.map +1 -1
- package/dist/document_transformers/openai_functions.cjs.map +1 -1
- package/dist/embeddings/cache_backed.cjs.map +1 -1
- package/dist/evaluation/comparison/pairwise.cjs +4 -2
- package/dist/evaluation/comparison/pairwise.cjs.map +1 -1
- package/dist/evaluation/comparison/pairwise.js +4 -2
- package/dist/evaluation/comparison/pairwise.js.map +1 -1
- package/dist/evaluation/criteria/criteria.cjs +4 -2
- package/dist/evaluation/criteria/criteria.cjs.map +1 -1
- package/dist/evaluation/criteria/criteria.js +4 -2
- package/dist/evaluation/criteria/criteria.js.map +1 -1
- package/dist/experimental/autogpt/agent.cjs +8 -7
- package/dist/experimental/autogpt/agent.cjs.map +1 -1
- package/dist/experimental/autogpt/agent.js +8 -7
- package/dist/experimental/autogpt/agent.js.map +1 -1
- package/dist/experimental/autogpt/prompt.cjs +2 -1
- package/dist/experimental/autogpt/prompt.cjs.map +1 -1
- package/dist/experimental/autogpt/prompt.js +2 -1
- package/dist/experimental/autogpt/prompt.js.map +1 -1
- package/dist/experimental/autogpt/prompt_generator.cjs.map +1 -1
- package/dist/experimental/chains/violation_of_expectations/violation_of_expectations_chain.cjs.map +1 -1
- package/dist/experimental/openai_assistant/index.cjs.map +1 -1
- package/dist/experimental/plan_and_execute/agent_executor.cjs +3 -2
- package/dist/experimental/plan_and_execute/agent_executor.cjs.map +1 -1
- package/dist/experimental/plan_and_execute/agent_executor.js +3 -2
- package/dist/experimental/plan_and_execute/agent_executor.js.map +1 -1
- package/dist/hub/base.cjs.map +1 -1
- package/dist/hub/base.js.map +1 -1
- package/dist/hub/index.cjs +2 -1
- package/dist/hub/index.cjs.map +1 -1
- package/dist/hub/index.js +2 -1
- package/dist/hub/index.js.map +1 -1
- package/dist/hub/node.cjs +4 -2
- package/dist/hub/node.cjs.map +1 -1
- package/dist/hub/node.js +4 -2
- package/dist/hub/node.js.map +1 -1
- package/dist/load/index.cjs.map +1 -1
- package/dist/memory/buffer_memory.cjs.map +1 -1
- package/dist/memory/buffer_token_memory.cjs.map +1 -1
- package/dist/memory/buffer_window_memory.cjs.map +1 -1
- package/dist/memory/chat_memory.cjs.map +1 -1
- package/dist/memory/entity_memory.cjs +2 -1
- package/dist/memory/entity_memory.cjs.map +1 -1
- package/dist/memory/entity_memory.js +2 -1
- package/dist/memory/entity_memory.js.map +1 -1
- package/dist/memory/summary.cjs.map +1 -1
- package/dist/memory/summary_buffer.cjs.map +1 -1
- package/dist/memory/vector_store.cjs.map +1 -1
- package/dist/output_parsers/fix.cjs +2 -1
- package/dist/output_parsers/fix.cjs.map +1 -1
- package/dist/output_parsers/fix.js +2 -1
- package/dist/output_parsers/fix.js.map +1 -1
- package/dist/output_parsers/openai_functions.cjs.map +1 -1
- package/dist/output_parsers/structured.cjs.map +1 -1
- package/dist/retrievers/document_compressors/chain_extract.cjs +2 -1
- package/dist/retrievers/document_compressors/chain_extract.cjs.map +1 -1
- package/dist/retrievers/document_compressors/chain_extract.js +2 -1
- package/dist/retrievers/document_compressors/chain_extract.js.map +1 -1
- package/dist/retrievers/matryoshka_retriever.cjs.map +1 -1
- package/dist/retrievers/multi_query.cjs +2 -1
- package/dist/retrievers/multi_query.cjs.map +1 -1
- package/dist/retrievers/multi_query.js +2 -1
- package/dist/retrievers/multi_query.js.map +1 -1
- package/dist/smith/runner_utils.cjs.map +1 -1
- package/dist/stores/file/node.cjs.map +1 -1
- package/dist/tools/render.cjs.map +1 -1
- package/dist/tools/retriever.cjs +2 -1
- package/dist/tools/retriever.cjs.map +1 -1
- package/dist/tools/retriever.js +2 -1
- package/dist/tools/retriever.js.map +1 -1
- package/dist/tools/webbrowser.cjs +2 -1
- package/dist/tools/webbrowser.cjs.map +1 -1
- package/dist/tools/webbrowser.js +2 -1
- package/dist/tools/webbrowser.js.map +1 -1
- package/dist/util/hub.cjs.map +1 -1
- package/dist/vectorstores/memory.cjs +2 -1
- package/dist/vectorstores/memory.cjs.map +1 -1
- package/dist/vectorstores/memory.js +2 -1
- package/dist/vectorstores/memory.js.map +1 -1
- package/package.json +23 -23
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/xml/index.ts"],"sourcesContent":["import type {\n BaseLanguageModel,\n BaseLanguageModelInterface,\n} from \"@langchain/core/language_models/base\";\nimport type { ToolInterface } from \"@langchain/core/tools\";\nimport { RunnablePassthrough } from \"@langchain/core/runnables\";\nimport type { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport { AgentStep, AgentAction, AgentFinish } from \"@langchain/core/agents\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport {\n AIMessagePromptTemplate,\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n} from \"@langchain/core/prompts\";\nimport { CallbackManager } from \"@langchain/core/callbacks/manager\";\nimport { LLMChain } from \"../../chains/llm_chain.js\";\nimport {\n AgentArgs,\n AgentRunnableSequence,\n BaseSingleActionAgent,\n} from \"../agent.js\";\nimport { AGENT_INSTRUCTIONS } from \"./prompt.js\";\nimport { XMLAgentOutputParser } from \"./output_parser.js\";\nimport { renderTextDescription } from \"../../tools/render.js\";\nimport { formatXml } from \"../format_scratchpad/xml.js\";\n\n/**\n * Interface for the input to the XMLAgent class.\n */\nexport interface XMLAgentInput {\n tools: ToolInterface[];\n llmChain: LLMChain;\n}\n\n/**\n * Class that represents an agent that uses XML tags.\n */\nexport class XMLAgent extends BaseSingleActionAgent implements XMLAgentInput {\n static lc_name() {\n return \"XMLAgent\";\n }\n\n lc_namespace = [\"langchain\", \"agents\", \"xml\"];\n\n tools: ToolInterface[];\n\n llmChain: LLMChain;\n\n outputParser: XMLAgentOutputParser = new XMLAgentOutputParser();\n\n _agentType() {\n return \"xml\" as const;\n }\n\n constructor(fields: XMLAgentInput) {\n super(fields);\n this.tools = fields.tools;\n this.llmChain = fields.llmChain;\n }\n\n get inputKeys() {\n return [\"input\"];\n }\n\n static createPrompt() {\n return ChatPromptTemplate.fromMessages([\n HumanMessagePromptTemplate.fromTemplate(AGENT_INSTRUCTIONS),\n AIMessagePromptTemplate.fromTemplate(\"{intermediate_steps}\"),\n ]);\n }\n\n /**\n * Plans the next action or finish state of the agent based on the\n * provided steps, inputs, and optional callback manager.\n * @param steps The steps to consider in planning.\n * @param inputs The inputs to consider in planning.\n * @param callbackManager Optional CallbackManager to use in planning.\n * @returns A Promise that resolves to an AgentAction or AgentFinish object representing the planned action or finish state.\n */\n async plan(\n steps: AgentStep[],\n inputs: ChainValues,\n callbackManager?: CallbackManager\n ): Promise<AgentAction | AgentFinish> {\n let log = \"\";\n for (const { action, observation } of steps) {\n log += `<tool>${action.tool}</tool><tool_input>${action.toolInput}</tool_input><observation>${observation}</observation>`;\n }\n let tools = \"\";\n for (const tool of this.tools) {\n tools += `${tool.name}: ${tool.description}\\n`;\n }\n const _inputs = {\n intermediate_steps: log,\n tools,\n question: inputs.input,\n stop: [\"</tool_input>\", \"</final_answer>\"],\n };\n const response = await this.llmChain.call(_inputs, callbackManager);\n return this.outputParser.parse(response[this.llmChain.outputKey]);\n }\n\n /**\n * Creates an XMLAgent from a BaseLanguageModel and a list of tools.\n * @param llm The BaseLanguageModel to use.\n * @param tools The tools to be used by the agent.\n * @param args Optional arguments for creating the agent.\n * @returns An instance of XMLAgent.\n */\n static fromLLMAndTools(\n llm: BaseLanguageModelInterface,\n tools: ToolInterface[],\n args?: XMLAgentInput & Pick<AgentArgs, \"callbacks\">\n ) {\n const prompt = XMLAgent.createPrompt();\n const chain = new LLMChain({\n prompt,\n llm,\n callbacks: args?.callbacks,\n });\n return new XMLAgent({\n llmChain: chain,\n tools,\n });\n }\n}\n\n/**\n * Params used by the createXmlAgent function.\n */\nexport type CreateXmlAgentParams = {\n /** LLM to use for the agent. */\n llm: BaseLanguageModelInterface;\n /** Tools this agent has access to. */\n tools: ToolInterface[];\n /**\n * The prompt to use. Must have input keys for\n * `tools` and `agent_scratchpad`.\n */\n prompt: BasePromptTemplate;\n /**\n * Whether to invoke the underlying model in streaming mode,\n * allowing streaming of intermediate steps. Defaults to true.\n */\n streamRunnable?: boolean;\n};\n\n/**\n * Create an agent that uses XML to format its logic.\n * @param params Params required to create the agent. Includes an LLM, tools, and prompt.\n * @returns A runnable sequence representing an agent. It takes as input all the same input\n * variables as the prompt passed in does. It returns as output either an\n * AgentAction or AgentFinish.\n *\n * @example\n * ```typescript\n * import { AgentExecutor, createXmlAgent } from \"langchain/agents\";\n * import { pull } from \"langchain/hub\";\n * import type { PromptTemplate } from \"@langchain/core/prompts\";\n *\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n *\n * // Define the tools the agent will have access to.\n * const tools = [...];\n *\n * // Get the prompt to use - you can modify this!\n * // If you want to see the prompt in full, you can at:\n * // https://smith.langchain.com/hub/hwchase17/xml-agent-convo\n * const prompt = await pull<PromptTemplate>(\"hwchase17/xml-agent-convo\");\n *\n * const llm = new ChatAnthropic({\n * temperature: 0,\n * });\n *\n * const agent = await createXmlAgent({\n * llm,\n * tools,\n * prompt,\n * });\n *\n * const agentExecutor = new AgentExecutor({\n * agent,\n * tools,\n * });\n *\n * const result = await agentExecutor.invoke({\n * input: \"what is LangChain?\",\n * });\n *\n * // With chat history\n * const result2 = await agentExecutor.invoke({\n * input: \"what's my name?\",\n * // Notice that chat_history is a string, since this prompt is aimed at LLMs, not chat models\n * chat_history: \"Human: Hi! My name is Cob\\nAI: Hello Cob! Nice to meet you\",\n * });\n * ```\n */\nexport async function createXmlAgent({\n llm,\n tools,\n prompt,\n streamRunnable,\n}: CreateXmlAgentParams) {\n const missingVariables = [\"tools\", \"agent_scratchpad\"].filter(\n (v) => !prompt.inputVariables.includes(v)\n );\n if (missingVariables.length > 0) {\n throw new Error(\n `Provided prompt is missing required input variables: ${JSON.stringify(\n missingVariables\n )}`\n );\n }\n const partialedPrompt = await prompt.partial({\n tools: renderTextDescription(tools),\n });\n // TODO: Add .bind to core runnable interface.\n const llmWithStop = (llm as BaseLanguageModel).withConfig({\n stop: [\"</tool_input>\", \"</final_answer>\"],\n });\n const agent = AgentRunnableSequence.fromRunnables(\n [\n RunnablePassthrough.assign({\n agent_scratchpad: (input: { steps: AgentStep[] }) =>\n formatXml(input.steps),\n }),\n partialedPrompt,\n llmWithStop,\n new XMLAgentOutputParser(),\n ],\n {\n name: \"XMLAgent\",\n streamRunnable,\n singleAction: true,\n }\n );\n return agent;\n}\n"],"mappings":";;;;;;;;;;;;AAqCA,IAAa,WAAb,MAAa,iBAAiB,sBAA+C;CAC3E,OAAO,UAAU;EACf,OAAO;CACT;CAEA,eAAe;EAAC;EAAa;EAAU;CAAK;CAE5C;CAEA;CAEA,eAAqC,IAAI,qBAAqB;CAE9D,aAAa;EACX,OAAO;CACT;CAEA,YAAY,QAAuB;EACjC,MAAM,MAAM;EACZ,KAAK,QAAQ,OAAO;EACpB,KAAK,WAAW,OAAO;CACzB;CAEA,IAAI,YAAY;EACd,OAAO,CAAC,OAAO;CACjB;CAEA,OAAO,eAAe;EACpB,OAAO,mBAAmB,aAAa,CACrC,2BAA2B,aAAa,kBAAkB,GAC1D,wBAAwB,aAAa,sBAAsB,CAC7D,CAAC;CACH;;;;;;;;;CAUA,MAAM,KACJ,OACA,QACA,iBACoC;EACpC,IAAI,MAAM;EACV,KAAK,MAAM,EAAE,QAAQ,iBAAiB,OACpC,OAAO,SAAS,OAAO,KAAK,qBAAqB,OAAO,UAAU,4BAA4B,YAAY;EAE5G,IAAI,QAAQ;EACZ,KAAK,MAAM,QAAQ,KAAK,OACtB,SAAS,GAAG,KAAK,KAAK,IAAI,KAAK,YAAY;EAE7C,MAAM,UAAU;GACd,oBAAoB;GACpB;GACA,UAAU,OAAO;GACjB,MAAM,CAAC,iBAAiB,iBAAiB;EAC3C;EACA,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK,SAAS,eAAe;EAClE,OAAO,KAAK,aAAa,MAAM,SAAS,KAAK,SAAS,UAAU;CAClE;;;;;;;;CASA,OAAO,gBACL,KACA,OACA,MACA;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/xml/index.ts"],"sourcesContent":["import type {\n BaseLanguageModel,\n BaseLanguageModelInterface,\n} from \"@langchain/core/language_models/base\";\nimport type { ToolInterface } from \"@langchain/core/tools\";\nimport { RunnablePassthrough } from \"@langchain/core/runnables\";\nimport type { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport { AgentStep, AgentAction, AgentFinish } from \"@langchain/core/agents\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport {\n AIMessagePromptTemplate,\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n} from \"@langchain/core/prompts\";\nimport { CallbackManager } from \"@langchain/core/callbacks/manager\";\nimport { LLMChain } from \"../../chains/llm_chain.js\";\nimport {\n AgentArgs,\n AgentRunnableSequence,\n BaseSingleActionAgent,\n} from \"../agent.js\";\nimport { AGENT_INSTRUCTIONS } from \"./prompt.js\";\nimport { XMLAgentOutputParser } from \"./output_parser.js\";\nimport { renderTextDescription } from \"../../tools/render.js\";\nimport { formatXml } from \"../format_scratchpad/xml.js\";\n\n/**\n * Interface for the input to the XMLAgent class.\n */\nexport interface XMLAgentInput {\n tools: ToolInterface[];\n llmChain: LLMChain;\n}\n\n/**\n * Class that represents an agent that uses XML tags.\n */\nexport class XMLAgent extends BaseSingleActionAgent implements XMLAgentInput {\n static lc_name() {\n return \"XMLAgent\";\n }\n\n lc_namespace = [\"langchain\", \"agents\", \"xml\"];\n\n tools: ToolInterface[];\n\n llmChain: LLMChain;\n\n outputParser: XMLAgentOutputParser = new XMLAgentOutputParser();\n\n _agentType() {\n return \"xml\" as const;\n }\n\n constructor(fields: XMLAgentInput) {\n super(fields);\n this.tools = fields.tools;\n this.llmChain = fields.llmChain;\n }\n\n get inputKeys() {\n return [\"input\"];\n }\n\n static createPrompt() {\n return ChatPromptTemplate.fromMessages([\n HumanMessagePromptTemplate.fromTemplate(AGENT_INSTRUCTIONS),\n AIMessagePromptTemplate.fromTemplate(\"{intermediate_steps}\"),\n ]);\n }\n\n /**\n * Plans the next action or finish state of the agent based on the\n * provided steps, inputs, and optional callback manager.\n * @param steps The steps to consider in planning.\n * @param inputs The inputs to consider in planning.\n * @param callbackManager Optional CallbackManager to use in planning.\n * @returns A Promise that resolves to an AgentAction or AgentFinish object representing the planned action or finish state.\n */\n async plan(\n steps: AgentStep[],\n inputs: ChainValues,\n callbackManager?: CallbackManager\n ): Promise<AgentAction | AgentFinish> {\n let log = \"\";\n for (const { action, observation } of steps) {\n log += `<tool>${action.tool}</tool><tool_input>${action.toolInput}</tool_input><observation>${observation}</observation>`;\n }\n let tools = \"\";\n for (const tool of this.tools) {\n tools += `${tool.name}: ${tool.description}\\n`;\n }\n const _inputs = {\n intermediate_steps: log,\n tools,\n question: inputs.input,\n stop: [\"</tool_input>\", \"</final_answer>\"],\n };\n const response = await this.llmChain.call(_inputs, callbackManager);\n return this.outputParser.parse(response[this.llmChain.outputKey]);\n }\n\n /**\n * Creates an XMLAgent from a BaseLanguageModel and a list of tools.\n * @param llm The BaseLanguageModel to use.\n * @param tools The tools to be used by the agent.\n * @param args Optional arguments for creating the agent.\n * @returns An instance of XMLAgent.\n */\n static fromLLMAndTools(\n llm: BaseLanguageModelInterface,\n tools: ToolInterface[],\n args?: XMLAgentInput & Pick<AgentArgs, \"callbacks\">\n ) {\n const prompt = XMLAgent.createPrompt();\n const chain = new LLMChain({\n prompt,\n llm,\n callbacks: args?.callbacks,\n });\n return new XMLAgent({\n llmChain: chain,\n tools,\n });\n }\n}\n\n/**\n * Params used by the createXmlAgent function.\n */\nexport type CreateXmlAgentParams = {\n /** LLM to use for the agent. */\n llm: BaseLanguageModelInterface;\n /** Tools this agent has access to. */\n tools: ToolInterface[];\n /**\n * The prompt to use. Must have input keys for\n * `tools` and `agent_scratchpad`.\n */\n prompt: BasePromptTemplate;\n /**\n * Whether to invoke the underlying model in streaming mode,\n * allowing streaming of intermediate steps. Defaults to true.\n */\n streamRunnable?: boolean;\n};\n\n/**\n * Create an agent that uses XML to format its logic.\n * @param params Params required to create the agent. Includes an LLM, tools, and prompt.\n * @returns A runnable sequence representing an agent. It takes as input all the same input\n * variables as the prompt passed in does. It returns as output either an\n * AgentAction or AgentFinish.\n *\n * @example\n * ```typescript\n * import { AgentExecutor, createXmlAgent } from \"langchain/agents\";\n * import { pull } from \"langchain/hub\";\n * import type { PromptTemplate } from \"@langchain/core/prompts\";\n *\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n *\n * // Define the tools the agent will have access to.\n * const tools = [...];\n *\n * // Get the prompt to use - you can modify this!\n * // If you want to see the prompt in full, you can at:\n * // https://smith.langchain.com/hub/hwchase17/xml-agent-convo\n * const prompt = await pull<PromptTemplate>(\"hwchase17/xml-agent-convo\");\n *\n * const llm = new ChatAnthropic({\n * temperature: 0,\n * });\n *\n * const agent = await createXmlAgent({\n * llm,\n * tools,\n * prompt,\n * });\n *\n * const agentExecutor = new AgentExecutor({\n * agent,\n * tools,\n * });\n *\n * const result = await agentExecutor.invoke({\n * input: \"what is LangChain?\",\n * });\n *\n * // With chat history\n * const result2 = await agentExecutor.invoke({\n * input: \"what's my name?\",\n * // Notice that chat_history is a string, since this prompt is aimed at LLMs, not chat models\n * chat_history: \"Human: Hi! My name is Cob\\nAI: Hello Cob! Nice to meet you\",\n * });\n * ```\n */\nexport async function createXmlAgent({\n llm,\n tools,\n prompt,\n streamRunnable,\n}: CreateXmlAgentParams) {\n const missingVariables = [\"tools\", \"agent_scratchpad\"].filter(\n (v) => !prompt.inputVariables.includes(v)\n );\n if (missingVariables.length > 0) {\n throw new Error(\n `Provided prompt is missing required input variables: ${JSON.stringify(\n missingVariables\n )}`\n );\n }\n const partialedPrompt = await prompt.partial({\n tools: renderTextDescription(tools),\n });\n // TODO: Add .bind to core runnable interface.\n const llmWithStop = (llm as BaseLanguageModel).withConfig({\n stop: [\"</tool_input>\", \"</final_answer>\"],\n });\n const agent = AgentRunnableSequence.fromRunnables(\n [\n RunnablePassthrough.assign({\n agent_scratchpad: (input: { steps: AgentStep[] }) =>\n formatXml(input.steps),\n }),\n partialedPrompt,\n llmWithStop,\n new XMLAgentOutputParser(),\n ],\n {\n name: \"XMLAgent\",\n streamRunnable,\n singleAction: true,\n }\n );\n return agent;\n}\n"],"mappings":";;;;;;;;;;;;AAqCA,IAAa,WAAb,MAAa,iBAAiB,sBAA+C;CAC3E,OAAO,UAAU;EACf,OAAO;CACT;CAEA,eAAe;EAAC;EAAa;EAAU;CAAK;CAE5C;CAEA;CAEA,eAAqC,IAAI,qBAAqB;CAE9D,aAAa;EACX,OAAO;CACT;CAEA,YAAY,QAAuB;EACjC,MAAM,MAAM;EACZ,KAAK,QAAQ,OAAO;EACpB,KAAK,WAAW,OAAO;CACzB;CAEA,IAAI,YAAY;EACd,OAAO,CAAC,OAAO;CACjB;CAEA,OAAO,eAAe;EACpB,OAAO,mBAAmB,aAAa,CACrC,2BAA2B,aAAa,kBAAkB,GAC1D,wBAAwB,aAAa,sBAAsB,CAC7D,CAAC;CACH;;;;;;;;;CAUA,MAAM,KACJ,OACA,QACA,iBACoC;EACpC,IAAI,MAAM;EACV,KAAK,MAAM,EAAE,QAAQ,iBAAiB,OACpC,OAAO,SAAS,OAAO,KAAK,qBAAqB,OAAO,UAAU,4BAA4B,YAAY;EAE5G,IAAI,QAAQ;EACZ,KAAK,MAAM,QAAQ,KAAK,OACtB,SAAS,GAAG,KAAK,KAAK,IAAI,KAAK,YAAY;EAE7C,MAAM,UAAU;GACd,oBAAoB;GACpB;GACA,UAAU,OAAO;GACjB,MAAM,CAAC,iBAAiB,iBAAiB;EAC3C;EACA,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK,SAAS,eAAe;EAClE,OAAO,KAAK,aAAa,MAAM,SAAS,KAAK,SAAS,UAAU;CAClE;;;;;;;;CASA,OAAO,gBACL,KACA,OACA,MACA;EACA,MAAM,SAAS,SAAS,aAAa;EACrC,MAAM,QAAQ,IAAI,SAAS;GACzB;GACA;GACA,WAAW,MAAM;EACnB,CAAC;EACD,OAAO,IAAI,SAAS;GAClB,UAAU;GACV;EACF,CAAC;CACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEA,eAAsB,eAAe,EACnC,KACA,OACA,QACA,kBACuB;CACvB,MAAM,mBAAmB,CAAC,SAAS,kBAAkB,CAAC,CAAC,QACpD,MAAM,CAAC,OAAO,eAAe,SAAS,CAAC,CAC1C;CACA,IAAI,iBAAiB,SAAS,GAC5B,MAAM,IAAI,MACR,wDAAwD,KAAK,UAC3D,gBACF,GACF;CAEF,MAAM,kBAAkB,MAAM,OAAO,QAAQ,EAC3C,OAAO,sBAAsB,KAAK,EACpC,CAAC;CAED,MAAM,cAAe,IAA0B,WAAW,EACxD,MAAM,CAAC,iBAAiB,iBAAiB,EAC3C,CAAC;CAiBD,OAhBc,sBAAsB,cAClC;EACE,oBAAoB,OAAO,EACzB,mBAAmB,UACjB,UAAU,MAAM,KAAK,EACzB,CAAC;EACD;EACA;EACA,IAAI,qBAAqB;CAC3B,GACA;EACE,MAAM;EACN;EACA,cAAc;CAChB,CAES;AACb"}
|
package/dist/chains/base.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.cjs","names":["BaseLangChain","CallbackManager","RUN_KEY"],"sources":["../../src/chains/base.ts"],"sourcesContent":["import { BaseMemory } from \"@langchain/core/memory\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { RUN_KEY } from \"@langchain/core/outputs\";\nimport {\n CallbackManagerForChainRun,\n CallbackManager,\n Callbacks,\n parseCallbackConfigArg,\n} from \"@langchain/core/callbacks/manager\";\nimport { ensureConfig, type RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseLangChain,\n BaseLangChainParams,\n} from \"@langchain/core/language_models/base\";\nimport { SerializedBaseChain } from \"./serde.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nexport interface ChainInputs extends BaseLangChainParams {\n memory?: BaseMemory;\n\n /**\n * @deprecated Use `callbacks` instead\n */\n callbackManager?: CallbackManager;\n}\n\n/**\n * Base interface that all chains must implement.\n */\nexport abstract class BaseChain<\n RunInput extends ChainValues = ChainValues,\n RunOutput extends ChainValues = ChainValues,\n>\n extends BaseLangChain<RunInput, RunOutput>\n implements ChainInputs\n{\n declare memory?: BaseMemory;\n\n get lc_namespace(): string[] {\n return [\"langchain\", \"chains\", this._chainType()];\n }\n\n constructor(\n fields?: BaseMemory | ChainInputs,\n /** @deprecated */\n verbose?: boolean,\n /** @deprecated */\n callbacks?: Callbacks\n ) {\n if (\n arguments.length === 1 &&\n typeof fields === \"object\" &&\n !(\"saveContext\" in fields)\n ) {\n // fields is not a BaseMemory\n const { memory, callbackManager, ...rest } = fields;\n super({ ...rest, callbacks: callbackManager ?? rest.callbacks });\n this.memory = memory;\n } else {\n // fields is a BaseMemory\n super({ verbose, callbacks });\n this.memory = fields as BaseMemory;\n }\n }\n\n /** @ignore */\n _selectMemoryInputs(values: ChainValues): ChainValues {\n const valuesForMemory = { ...values };\n if (\"signal\" in valuesForMemory) {\n delete valuesForMemory.signal;\n }\n if (\"timeout\" in valuesForMemory) {\n delete valuesForMemory.timeout;\n }\n return valuesForMemory;\n }\n\n /**\n * Invoke the chain with the provided input and returns the output.\n * @param input Input values for the chain run.\n * @param config Optional configuration for the Runnable.\n * @returns Promise that resolves with the output of the chain run.\n */\n async invoke(input: RunInput, options?: RunnableConfig): Promise<RunOutput> {\n const config = ensureConfig(options);\n const fullValues = await this._formatValues(input);\n const callbackManager_ = await CallbackManager.configure(\n config?.callbacks,\n this.callbacks,\n config?.tags,\n this.tags,\n config?.metadata,\n this.metadata,\n { verbose: this.verbose }\n );\n const runManager = await callbackManager_?.handleChainStart(\n this.toJSON(),\n fullValues,\n undefined,\n undefined,\n undefined,\n undefined,\n config?.runName\n );\n let outputValues: RunOutput;\n try {\n if (fullValues.signal) {\n let listener: (() => void) | undefined;\n outputValues = (await Promise.race([\n this._call(fullValues as RunInput, runManager, config),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(new Error(\"AbortError\"));\n };\n fullValues.signal?.addEventListener(\"abort\", listener, {\n once: true,\n });\n }),\n ]).finally(() => {\n if (fullValues.signal && listener) {\n fullValues.signal.removeEventListener(\"abort\", listener);\n }\n })) as RunOutput;\n } else {\n outputValues = await this._call(\n fullValues as RunInput,\n runManager,\n config\n );\n }\n } catch (e) {\n await runManager?.handleChainError(e);\n throw e;\n }\n if (!(this.memory == null)) {\n await this.memory.saveContext(\n this._selectMemoryInputs(input),\n outputValues\n );\n }\n await runManager?.handleChainEnd(outputValues);\n // add the runManager's currentRunId to the outputValues\n Object.defineProperty(outputValues, RUN_KEY, {\n value: runManager ? { runId: runManager?.runId } : undefined,\n configurable: true,\n });\n return outputValues;\n }\n\n private _validateOutputs(outputs: Record<string, unknown>): void {\n const missingKeys = this.outputKeys.filter((k) => !(k in outputs));\n if (missingKeys.length) {\n throw new Error(\n `Missing output keys: ${missingKeys.join(\n \", \"\n )} from chain ${this._chainType()}`\n );\n }\n }\n\n async prepOutputs(\n inputs: Record<string, unknown>,\n outputs: Record<string, unknown>,\n returnOnlyOutputs = false\n ) {\n this._validateOutputs(outputs);\n if (this.memory) {\n await this.memory.saveContext(inputs, outputs);\n }\n if (returnOnlyOutputs) {\n return outputs;\n }\n return { ...inputs, ...outputs };\n }\n\n /**\n * Run the core logic of this chain and return the output\n */\n abstract _call(\n values: RunInput,\n runManager?: CallbackManagerForChainRun,\n config?: RunnableConfig\n ): Promise<RunOutput>;\n\n /**\n * Return the string type key uniquely identifying this class of chain.\n */\n abstract _chainType(): string;\n\n /**\n * Return a json-like object representing this chain.\n */\n serialize(): SerializedBaseChain {\n throw new Error(\"Method not implemented.\");\n }\n\n abstract get inputKeys(): string[];\n\n abstract get outputKeys(): string[];\n\n /** @deprecated Use .invoke() instead. Will be removed in 0.2.0. */\n async run(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n input: any,\n config?: Callbacks | RunnableConfig\n ): Promise<string> {\n const inputKeys = this.inputKeys.filter(\n (k) => !this.memory?.memoryKeys.includes(k)\n );\n const isKeylessInput = inputKeys.length <= 1;\n if (!isKeylessInput) {\n throw new Error(\n `Chain ${this._chainType()} expects multiple inputs, cannot use 'run' `\n );\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const values = inputKeys.length ? { [inputKeys[0]]: input } : ({} as any);\n const returnValues = await this.call(values, config);\n const keys = Object.keys(returnValues);\n\n if (keys.length === 1) {\n return returnValues[keys[0]];\n }\n throw new Error(\n \"return values have multiple keys, `run` only supported when one key currently\"\n );\n }\n\n protected async _formatValues(\n values: ChainValues & { signal?: AbortSignal; timeout?: number }\n ) {\n const fullValues = { ...values } as typeof values;\n if (fullValues.timeout && !fullValues.signal) {\n fullValues.signal = AbortSignal.timeout(fullValues.timeout);\n delete fullValues.timeout;\n }\n if (!(this.memory == null)) {\n const newValues = await this.memory.loadMemoryVariables(\n this._selectMemoryInputs(values)\n );\n for (const [key, value] of Object.entries(newValues)) {\n fullValues[key] = value;\n }\n }\n return fullValues;\n }\n\n /**\n * @deprecated Use .invoke() instead. Will be removed in 0.2.0.\n *\n * Run the core logic of this chain and add to output if desired.\n *\n * Wraps _call and handles memory.\n */\n async call(\n values: ChainValues & { signal?: AbortSignal; timeout?: number },\n config?: Callbacks | RunnableConfig,\n /** @deprecated */\n tags?: string[]\n ): Promise<RunOutput> {\n const parsedConfig = { tags, ...parseCallbackConfigArg(config) };\n return this.invoke(values as RunInput, parsedConfig);\n }\n\n /**\n * @deprecated Use .batch() instead. Will be removed in 0.2.0.\n *\n * Call the chain on all inputs in the list\n */\n async apply(\n inputs: RunInput[],\n config?: (Callbacks | RunnableConfig)[]\n ): Promise<RunOutput[]> {\n return Promise.all(\n inputs.map(async (i, idx) => this.call(i, config?.[idx]))\n );\n }\n\n /**\n * Load a chain from a json-like object describing it.\n */\n static async deserialize(\n data: SerializedBaseChain,\n values: LoadValues = {}\n ): Promise<BaseChain> {\n switch (data._type) {\n case \"llm_chain\": {\n const { LLMChain } = await import(\"./llm_chain.js\");\n return LLMChain.deserialize(data);\n }\n case \"sequential_chain\": {\n const { SequentialChain } = await import(\"./sequential_chain.js\");\n return SequentialChain.deserialize(data);\n }\n case \"simple_sequential_chain\": {\n const { SimpleSequentialChain } = await import(\"./sequential_chain.js\");\n return SimpleSequentialChain.deserialize(data);\n }\n case \"stuff_documents_chain\": {\n const { StuffDocumentsChain } = await import(\"./combine_docs_chain.js\");\n return StuffDocumentsChain.deserialize(data);\n }\n case \"map_reduce_documents_chain\": {\n const { MapReduceDocumentsChain } =\n await import(\"./combine_docs_chain.js\");\n return MapReduceDocumentsChain.deserialize(data);\n }\n case \"refine_documents_chain\": {\n const { RefineDocumentsChain } =\n await import(\"./combine_docs_chain.js\");\n return RefineDocumentsChain.deserialize(data);\n }\n case \"vector_db_qa\": {\n const { VectorDBQAChain } = await import(\"./vector_db_qa.js\");\n return VectorDBQAChain.deserialize(data, values);\n }\n case \"api_chain\": {\n const { APIChain } = await import(\"./api/api_chain.js\");\n return APIChain.deserialize(data);\n }\n default:\n throw new Error(\n `Invalid prompt type in config: ${\n (data as SerializedBaseChain)._type\n }`\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["BaseLangChain","ensureConfig","CallbackManager","RUN_KEY","parseCallbackConfigArg"],"sources":["../../src/chains/base.ts"],"sourcesContent":["import { BaseMemory } from \"@langchain/core/memory\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { RUN_KEY } from \"@langchain/core/outputs\";\nimport {\n CallbackManagerForChainRun,\n CallbackManager,\n Callbacks,\n parseCallbackConfigArg,\n} from \"@langchain/core/callbacks/manager\";\nimport { ensureConfig, type RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseLangChain,\n BaseLangChainParams,\n} from \"@langchain/core/language_models/base\";\nimport { SerializedBaseChain } from \"./serde.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nexport interface ChainInputs extends BaseLangChainParams {\n memory?: BaseMemory;\n\n /**\n * @deprecated Use `callbacks` instead\n */\n callbackManager?: CallbackManager;\n}\n\n/**\n * Base interface that all chains must implement.\n */\nexport abstract class BaseChain<\n RunInput extends ChainValues = ChainValues,\n RunOutput extends ChainValues = ChainValues,\n>\n extends BaseLangChain<RunInput, RunOutput>\n implements ChainInputs\n{\n declare memory?: BaseMemory;\n\n get lc_namespace(): string[] {\n return [\"langchain\", \"chains\", this._chainType()];\n }\n\n constructor(\n fields?: BaseMemory | ChainInputs,\n /** @deprecated */\n verbose?: boolean,\n /** @deprecated */\n callbacks?: Callbacks\n ) {\n if (\n arguments.length === 1 &&\n typeof fields === \"object\" &&\n !(\"saveContext\" in fields)\n ) {\n // fields is not a BaseMemory\n const { memory, callbackManager, ...rest } = fields;\n super({ ...rest, callbacks: callbackManager ?? rest.callbacks });\n this.memory = memory;\n } else {\n // fields is a BaseMemory\n super({ verbose, callbacks });\n this.memory = fields as BaseMemory;\n }\n }\n\n /** @ignore */\n _selectMemoryInputs(values: ChainValues): ChainValues {\n const valuesForMemory = { ...values };\n if (\"signal\" in valuesForMemory) {\n delete valuesForMemory.signal;\n }\n if (\"timeout\" in valuesForMemory) {\n delete valuesForMemory.timeout;\n }\n return valuesForMemory;\n }\n\n /**\n * Invoke the chain with the provided input and returns the output.\n * @param input Input values for the chain run.\n * @param config Optional configuration for the Runnable.\n * @returns Promise that resolves with the output of the chain run.\n */\n async invoke(input: RunInput, options?: RunnableConfig): Promise<RunOutput> {\n const config = ensureConfig(options);\n const fullValues = await this._formatValues(input);\n const callbackManager_ = await CallbackManager.configure(\n config?.callbacks,\n this.callbacks,\n config?.tags,\n this.tags,\n config?.metadata,\n this.metadata,\n { verbose: this.verbose }\n );\n const runManager = await callbackManager_?.handleChainStart(\n this.toJSON(),\n fullValues,\n undefined,\n undefined,\n undefined,\n undefined,\n config?.runName\n );\n let outputValues: RunOutput;\n try {\n if (fullValues.signal) {\n let listener: (() => void) | undefined;\n outputValues = (await Promise.race([\n this._call(fullValues as RunInput, runManager, config),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(new Error(\"AbortError\"));\n };\n fullValues.signal?.addEventListener(\"abort\", listener, {\n once: true,\n });\n }),\n ]).finally(() => {\n if (fullValues.signal && listener) {\n fullValues.signal.removeEventListener(\"abort\", listener);\n }\n })) as RunOutput;\n } else {\n outputValues = await this._call(\n fullValues as RunInput,\n runManager,\n config\n );\n }\n } catch (e) {\n await runManager?.handleChainError(e);\n throw e;\n }\n if (!(this.memory == null)) {\n await this.memory.saveContext(\n this._selectMemoryInputs(input),\n outputValues\n );\n }\n await runManager?.handleChainEnd(outputValues);\n // add the runManager's currentRunId to the outputValues\n Object.defineProperty(outputValues, RUN_KEY, {\n value: runManager ? { runId: runManager?.runId } : undefined,\n configurable: true,\n });\n return outputValues;\n }\n\n private _validateOutputs(outputs: Record<string, unknown>): void {\n const missingKeys = this.outputKeys.filter((k) => !(k in outputs));\n if (missingKeys.length) {\n throw new Error(\n `Missing output keys: ${missingKeys.join(\n \", \"\n )} from chain ${this._chainType()}`\n );\n }\n }\n\n async prepOutputs(\n inputs: Record<string, unknown>,\n outputs: Record<string, unknown>,\n returnOnlyOutputs = false\n ) {\n this._validateOutputs(outputs);\n if (this.memory) {\n await this.memory.saveContext(inputs, outputs);\n }\n if (returnOnlyOutputs) {\n return outputs;\n }\n return { ...inputs, ...outputs };\n }\n\n /**\n * Run the core logic of this chain and return the output\n */\n abstract _call(\n values: RunInput,\n runManager?: CallbackManagerForChainRun,\n config?: RunnableConfig\n ): Promise<RunOutput>;\n\n /**\n * Return the string type key uniquely identifying this class of chain.\n */\n abstract _chainType(): string;\n\n /**\n * Return a json-like object representing this chain.\n */\n serialize(): SerializedBaseChain {\n throw new Error(\"Method not implemented.\");\n }\n\n abstract get inputKeys(): string[];\n\n abstract get outputKeys(): string[];\n\n /** @deprecated Use .invoke() instead. Will be removed in 0.2.0. */\n async run(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n input: any,\n config?: Callbacks | RunnableConfig\n ): Promise<string> {\n const inputKeys = this.inputKeys.filter(\n (k) => !this.memory?.memoryKeys.includes(k)\n );\n const isKeylessInput = inputKeys.length <= 1;\n if (!isKeylessInput) {\n throw new Error(\n `Chain ${this._chainType()} expects multiple inputs, cannot use 'run' `\n );\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const values = inputKeys.length ? { [inputKeys[0]]: input } : ({} as any);\n const returnValues = await this.call(values, config);\n const keys = Object.keys(returnValues);\n\n if (keys.length === 1) {\n return returnValues[keys[0]];\n }\n throw new Error(\n \"return values have multiple keys, `run` only supported when one key currently\"\n );\n }\n\n protected async _formatValues(\n values: ChainValues & { signal?: AbortSignal; timeout?: number }\n ) {\n const fullValues = { ...values } as typeof values;\n if (fullValues.timeout && !fullValues.signal) {\n fullValues.signal = AbortSignal.timeout(fullValues.timeout);\n delete fullValues.timeout;\n }\n if (!(this.memory == null)) {\n const newValues = await this.memory.loadMemoryVariables(\n this._selectMemoryInputs(values)\n );\n for (const [key, value] of Object.entries(newValues)) {\n fullValues[key] = value;\n }\n }\n return fullValues;\n }\n\n /**\n * @deprecated Use .invoke() instead. Will be removed in 0.2.0.\n *\n * Run the core logic of this chain and add to output if desired.\n *\n * Wraps _call and handles memory.\n */\n async call(\n values: ChainValues & { signal?: AbortSignal; timeout?: number },\n config?: Callbacks | RunnableConfig,\n /** @deprecated */\n tags?: string[]\n ): Promise<RunOutput> {\n const parsedConfig = { tags, ...parseCallbackConfigArg(config) };\n return this.invoke(values as RunInput, parsedConfig);\n }\n\n /**\n * @deprecated Use .batch() instead. Will be removed in 0.2.0.\n *\n * Call the chain on all inputs in the list\n */\n async apply(\n inputs: RunInput[],\n config?: (Callbacks | RunnableConfig)[]\n ): Promise<RunOutput[]> {\n return Promise.all(\n inputs.map(async (i, idx) => this.call(i, config?.[idx]))\n );\n }\n\n /**\n * Load a chain from a json-like object describing it.\n */\n static async deserialize(\n data: SerializedBaseChain,\n values: LoadValues = {}\n ): Promise<BaseChain> {\n switch (data._type) {\n case \"llm_chain\": {\n const { LLMChain } = await import(\"./llm_chain.js\");\n return LLMChain.deserialize(data);\n }\n case \"sequential_chain\": {\n const { SequentialChain } = await import(\"./sequential_chain.js\");\n return SequentialChain.deserialize(data);\n }\n case \"simple_sequential_chain\": {\n const { SimpleSequentialChain } = await import(\"./sequential_chain.js\");\n return SimpleSequentialChain.deserialize(data);\n }\n case \"stuff_documents_chain\": {\n const { StuffDocumentsChain } = await import(\"./combine_docs_chain.js\");\n return StuffDocumentsChain.deserialize(data);\n }\n case \"map_reduce_documents_chain\": {\n const { MapReduceDocumentsChain } =\n await import(\"./combine_docs_chain.js\");\n return MapReduceDocumentsChain.deserialize(data);\n }\n case \"refine_documents_chain\": {\n const { RefineDocumentsChain } =\n await import(\"./combine_docs_chain.js\");\n return RefineDocumentsChain.deserialize(data);\n }\n case \"vector_db_qa\": {\n const { VectorDBQAChain } = await import(\"./vector_db_qa.js\");\n return VectorDBQAChain.deserialize(data, values);\n }\n case \"api_chain\": {\n const { APIChain } = await import(\"./api/api_chain.js\");\n return APIChain.deserialize(data);\n }\n default:\n throw new Error(\n `Invalid prompt type in config: ${\n (data as SerializedBaseChain)._type\n }`\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -103,8 +103,9 @@ var ChatVectorDBQAChain = class ChatVectorDBQAChain extends require_base.BaseCha
|
|
|
103
103
|
static fromLLM(llm, vectorstore, options = {}) {
|
|
104
104
|
const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;
|
|
105
105
|
const question_generator_prompt = _langchain_core_prompts.PromptTemplate.fromTemplate(questionGeneratorTemplate || question_generator_template);
|
|
106
|
+
const qa_prompt = _langchain_core_prompts.PromptTemplate.fromTemplate(qaTemplate || qa_template);
|
|
106
107
|
const qaChain = require_load.loadQAStuffChain(llm, {
|
|
107
|
-
prompt:
|
|
108
|
+
prompt: qa_prompt,
|
|
108
109
|
verbose
|
|
109
110
|
});
|
|
110
111
|
const questionGeneratorChain = new require_llm_chain.LLMChain({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat_vector_db_chain.cjs","names":["BaseChain","LLMChain","PromptTemplate","loadQAStuffChain"],"sources":["../../src/chains/chat_vector_db_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { VectorStoreInterface } from \"@langchain/core/vectorstores\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { loadQAStuffChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\nconst qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.\n\n{context}\n\nQuestion: {question}\nHelpful Answer:`;\n\n/**\n * Interface for the input parameters of the ChatVectorDBQAChain class.\n */\nexport interface ChatVectorDBQAChainInput extends ChainInputs {\n vectorstore: VectorStoreInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n outputKey?: string;\n inputKey?: string;\n k?: number;\n}\n\n/** @deprecated use `ConversationalRetrievalQAChain` instead. */\nexport class ChatVectorDBQAChain\n extends BaseChain\n implements ChatVectorDBQAChainInput\n{\n k = 4;\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n outputKey = \"result\";\n\n get outputKeys() {\n return [this.outputKey];\n }\n\n vectorstore: VectorStoreInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n constructor(fields: ChatVectorDBQAChainInput) {\n super(fields);\n this.vectorstore = fields.vectorstore;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.outputKey = fields.outputKey ?? this.outputKey;\n this.k = fields.k ?? this.k;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`chat history key ${this.inputKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string = values[this.chatHistoryKey];\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n console.log(\"_call\", values, keys);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.vectorstore.similaritySearch(\n newQuestion,\n this.k,\n undefined,\n runManager?.getChild(\"vectorstore\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n const result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n return {\n ...result,\n sourceDocuments: docs,\n };\n }\n return result;\n }\n\n _chainType() {\n return \"chat-vector-db\" as const;\n }\n\n static async deserialize(\n data: SerializedChatVectorDBQAChain,\n values: LoadValues\n ) {\n if (!(\"vectorstore\" in values)) {\n throw new Error(\n `Need to pass in a vectorstore to deserialize VectorDBQAChain`\n );\n }\n const { vectorstore } = values;\n\n return new ChatVectorDBQAChain({\n combineDocumentsChain: await BaseChain.deserialize(\n data.combine_documents_chain\n ),\n questionGeneratorChain: await LLMChain.deserialize(\n data.question_generator\n ),\n k: data.k,\n vectorstore,\n });\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n return {\n _type: this._chainType(),\n combine_documents_chain: this.combineDocumentsChain.serialize(),\n question_generator: this.questionGeneratorChain.serialize(),\n k: this.k,\n };\n }\n\n /**\n * Creates an instance of ChatVectorDBQAChain using a BaseLanguageModel\n * and other options.\n * @param llm Instance of BaseLanguageModel used to generate a new question.\n * @param vectorstore Instance of VectorStore used for vector operations.\n * @param options (Optional) Additional options for creating the ChatVectorDBQAChain instance.\n * @returns New instance of ChatVectorDBQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n vectorstore: VectorStoreInterface,\n options: {\n inputKey?: string;\n outputKey?: string;\n k?: number;\n returnSourceDocuments?: boolean;\n questionGeneratorTemplate?: string;\n qaTemplate?: string;\n verbose?: boolean;\n } = {}\n ): ChatVectorDBQAChain {\n const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;\n const question_generator_prompt = PromptTemplate.fromTemplate(\n questionGeneratorTemplate || question_generator_template\n );\n const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);\n\n const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt, verbose });\n const questionGeneratorChain = new LLMChain({\n prompt: question_generator_prompt,\n llm,\n verbose,\n });\n const instance = new this({\n vectorstore,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":";;;;;AAaA,MAAM,8BAA8B;;;;;;AAOpC,MAAM,cAAc;;;;;;;AAqBpB,IAAa,sBAAb,MAAa,4BACHA,aAAAA,UAEV;CACE,IAAI;CAEJ,WAAW;CAEX,iBAAiB;CAEjB,IAAI,YAAY;EACd,OAAO,CAAC,KAAK,UAAU,KAAK,cAAc;CAC5C;CAEA,YAAY;CAEZ,IAAI,aAAa;EACf,OAAO,CAAC,KAAK,SAAS;CACxB;CAEA;CAEA;CAEA;CAEA,wBAAwB;CAExB,YAAY,QAAkC;EAC5C,MAAM,MAAM;EACZ,KAAK,cAAc,OAAO;EAC1B,KAAK,wBAAwB,OAAO;EACpC,KAAK,yBAAyB,OAAO;EACrC,KAAK,WAAW,OAAO,YAAY,KAAK;EACxC,KAAK,YAAY,OAAO,aAAa,KAAK;EAC1C,KAAK,IAAI,OAAO,KAAK,KAAK;EAC1B,KAAK,wBACH,OAAO,yBAAyB,KAAK;CACzC;;CAGA,MAAM,MACJ,QACA,YACsB;EACtB,IAAI,EAAE,KAAK,YAAY,SACrB,MAAM,IAAI,MAAM,gBAAgB,KAAK,SAAS,YAAY;EAE5D,IAAI,EAAE,KAAK,kBAAkB,SAC3B,MAAM,IAAI,MAAM,oBAAoB,KAAK,SAAS,YAAY;EAEhE,MAAM,WAAmB,OAAO,KAAK;EACrC,MAAM,cAAsB,OAAO,KAAK;EACxC,IAAI,cAAc;EAClB,IAAI,YAAY,SAAS,GAAG;GAC1B,MAAM,SAAS,MAAM,KAAK,uBAAuB,KAC/C;IACE;IACA,cAAc;GAChB,GACA,YAAY,SAAS,oBAAoB,CAC3C;GACA,MAAM,OAAO,OAAO,KAAK,MAAM;GAC/B,QAAQ,IAAI,SAAS,QAAQ,IAAI;GACjC,IAAI,KAAK,WAAW,GAClB,cAAc,OAAO,KAAK;QAE1B,MAAM,IAAI,MACR,0EACF;EAEJ;EACA,MAAM,OAAO,MAAM,KAAK,YAAY,iBAClC,aACA,KAAK,GACL,KAAA,GACA,YAAY,SAAS,aAAa,CACpC;EACA,MAAM,SAAS;GACb,UAAU;GACV,iBAAiB;GACjB,cAAc;EAChB;EACA,MAAM,SAAS,MAAM,KAAK,sBAAsB,KAC9C,QACA,YAAY,SAAS,mBAAmB,CAC1C;EACA,IAAI,KAAK,uBACP,OAAO;GACL,GAAG;GACH,iBAAiB;EACnB;EAEF,OAAO;CACT;CAEA,aAAa;EACX,OAAO;CACT;CAEA,aAAa,YACX,MACA,QACA;EACA,IAAI,EAAE,iBAAiB,SACrB,MAAM,IAAI,MACR,8DACF;EAEF,MAAM,EAAE,gBAAgB;EAExB,OAAO,IAAI,oBAAoB;GAC7B,uBAAuB,MAAMA,aAAAA,UAAU,YACrC,KAAK,uBACP;GACA,wBAAwB,MAAMC,kBAAAA,SAAS,YACrC,KAAK,kBACP;GACA,GAAG,KAAK;GACR;EACF,CAAC;CACH;CAEA,YAA2C;EACzC,OAAO;GACL,OAAO,KAAK,WAAW;GACvB,yBAAyB,KAAK,sBAAsB,UAAU;GAC9D,oBAAoB,KAAK,uBAAuB,UAAU;GAC1D,GAAG,KAAK;EACV;CACF;;;;;;;;;CAUA,OAAO,QACL,KACA,aACA,UAQI,CAAC,GACgB;EACrB,MAAM,EAAE,2BAA2B,YAAY,SAAS,GAAG,SAAS;EACpE,MAAM,4BAA4BC,wBAAAA,eAAe,aAC/C,6BAA6B,2BAC/B;
|
|
1
|
+
{"version":3,"file":"chat_vector_db_chain.cjs","names":["BaseChain","LLMChain","PromptTemplate","loadQAStuffChain"],"sources":["../../src/chains/chat_vector_db_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { VectorStoreInterface } from \"@langchain/core/vectorstores\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { loadQAStuffChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\nconst qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.\n\n{context}\n\nQuestion: {question}\nHelpful Answer:`;\n\n/**\n * Interface for the input parameters of the ChatVectorDBQAChain class.\n */\nexport interface ChatVectorDBQAChainInput extends ChainInputs {\n vectorstore: VectorStoreInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n outputKey?: string;\n inputKey?: string;\n k?: number;\n}\n\n/** @deprecated use `ConversationalRetrievalQAChain` instead. */\nexport class ChatVectorDBQAChain\n extends BaseChain\n implements ChatVectorDBQAChainInput\n{\n k = 4;\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n outputKey = \"result\";\n\n get outputKeys() {\n return [this.outputKey];\n }\n\n vectorstore: VectorStoreInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n constructor(fields: ChatVectorDBQAChainInput) {\n super(fields);\n this.vectorstore = fields.vectorstore;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.outputKey = fields.outputKey ?? this.outputKey;\n this.k = fields.k ?? this.k;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`chat history key ${this.inputKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string = values[this.chatHistoryKey];\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n console.log(\"_call\", values, keys);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.vectorstore.similaritySearch(\n newQuestion,\n this.k,\n undefined,\n runManager?.getChild(\"vectorstore\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n const result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n return {\n ...result,\n sourceDocuments: docs,\n };\n }\n return result;\n }\n\n _chainType() {\n return \"chat-vector-db\" as const;\n }\n\n static async deserialize(\n data: SerializedChatVectorDBQAChain,\n values: LoadValues\n ) {\n if (!(\"vectorstore\" in values)) {\n throw new Error(\n `Need to pass in a vectorstore to deserialize VectorDBQAChain`\n );\n }\n const { vectorstore } = values;\n\n return new ChatVectorDBQAChain({\n combineDocumentsChain: await BaseChain.deserialize(\n data.combine_documents_chain\n ),\n questionGeneratorChain: await LLMChain.deserialize(\n data.question_generator\n ),\n k: data.k,\n vectorstore,\n });\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n return {\n _type: this._chainType(),\n combine_documents_chain: this.combineDocumentsChain.serialize(),\n question_generator: this.questionGeneratorChain.serialize(),\n k: this.k,\n };\n }\n\n /**\n * Creates an instance of ChatVectorDBQAChain using a BaseLanguageModel\n * and other options.\n * @param llm Instance of BaseLanguageModel used to generate a new question.\n * @param vectorstore Instance of VectorStore used for vector operations.\n * @param options (Optional) Additional options for creating the ChatVectorDBQAChain instance.\n * @returns New instance of ChatVectorDBQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n vectorstore: VectorStoreInterface,\n options: {\n inputKey?: string;\n outputKey?: string;\n k?: number;\n returnSourceDocuments?: boolean;\n questionGeneratorTemplate?: string;\n qaTemplate?: string;\n verbose?: boolean;\n } = {}\n ): ChatVectorDBQAChain {\n const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;\n const question_generator_prompt = PromptTemplate.fromTemplate(\n questionGeneratorTemplate || question_generator_template\n );\n const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);\n\n const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt, verbose });\n const questionGeneratorChain = new LLMChain({\n prompt: question_generator_prompt,\n llm,\n verbose,\n });\n const instance = new this({\n vectorstore,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
@@ -103,8 +103,9 @@ var ChatVectorDBQAChain = class ChatVectorDBQAChain extends BaseChain {
|
|
|
103
103
|
static fromLLM(llm, vectorstore, options = {}) {
|
|
104
104
|
const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;
|
|
105
105
|
const question_generator_prompt = PromptTemplate.fromTemplate(questionGeneratorTemplate || question_generator_template);
|
|
106
|
+
const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);
|
|
106
107
|
const qaChain = loadQAStuffChain(llm, {
|
|
107
|
-
prompt:
|
|
108
|
+
prompt: qa_prompt,
|
|
108
109
|
verbose
|
|
109
110
|
});
|
|
110
111
|
const questionGeneratorChain = new LLMChain({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat_vector_db_chain.js","names":[],"sources":["../../src/chains/chat_vector_db_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { VectorStoreInterface } from \"@langchain/core/vectorstores\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { loadQAStuffChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\nconst qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.\n\n{context}\n\nQuestion: {question}\nHelpful Answer:`;\n\n/**\n * Interface for the input parameters of the ChatVectorDBQAChain class.\n */\nexport interface ChatVectorDBQAChainInput extends ChainInputs {\n vectorstore: VectorStoreInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n outputKey?: string;\n inputKey?: string;\n k?: number;\n}\n\n/** @deprecated use `ConversationalRetrievalQAChain` instead. */\nexport class ChatVectorDBQAChain\n extends BaseChain\n implements ChatVectorDBQAChainInput\n{\n k = 4;\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n outputKey = \"result\";\n\n get outputKeys() {\n return [this.outputKey];\n }\n\n vectorstore: VectorStoreInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n constructor(fields: ChatVectorDBQAChainInput) {\n super(fields);\n this.vectorstore = fields.vectorstore;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.outputKey = fields.outputKey ?? this.outputKey;\n this.k = fields.k ?? this.k;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`chat history key ${this.inputKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string = values[this.chatHistoryKey];\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n console.log(\"_call\", values, keys);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.vectorstore.similaritySearch(\n newQuestion,\n this.k,\n undefined,\n runManager?.getChild(\"vectorstore\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n const result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n return {\n ...result,\n sourceDocuments: docs,\n };\n }\n return result;\n }\n\n _chainType() {\n return \"chat-vector-db\" as const;\n }\n\n static async deserialize(\n data: SerializedChatVectorDBQAChain,\n values: LoadValues\n ) {\n if (!(\"vectorstore\" in values)) {\n throw new Error(\n `Need to pass in a vectorstore to deserialize VectorDBQAChain`\n );\n }\n const { vectorstore } = values;\n\n return new ChatVectorDBQAChain({\n combineDocumentsChain: await BaseChain.deserialize(\n data.combine_documents_chain\n ),\n questionGeneratorChain: await LLMChain.deserialize(\n data.question_generator\n ),\n k: data.k,\n vectorstore,\n });\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n return {\n _type: this._chainType(),\n combine_documents_chain: this.combineDocumentsChain.serialize(),\n question_generator: this.questionGeneratorChain.serialize(),\n k: this.k,\n };\n }\n\n /**\n * Creates an instance of ChatVectorDBQAChain using a BaseLanguageModel\n * and other options.\n * @param llm Instance of BaseLanguageModel used to generate a new question.\n * @param vectorstore Instance of VectorStore used for vector operations.\n * @param options (Optional) Additional options for creating the ChatVectorDBQAChain instance.\n * @returns New instance of ChatVectorDBQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n vectorstore: VectorStoreInterface,\n options: {\n inputKey?: string;\n outputKey?: string;\n k?: number;\n returnSourceDocuments?: boolean;\n questionGeneratorTemplate?: string;\n qaTemplate?: string;\n verbose?: boolean;\n } = {}\n ): ChatVectorDBQAChain {\n const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;\n const question_generator_prompt = PromptTemplate.fromTemplate(\n questionGeneratorTemplate || question_generator_template\n );\n const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);\n\n const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt, verbose });\n const questionGeneratorChain = new LLMChain({\n prompt: question_generator_prompt,\n llm,\n verbose,\n });\n const instance = new this({\n vectorstore,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":";;;;;AAaA,MAAM,8BAA8B;;;;;;AAOpC,MAAM,cAAc;;;;;;;AAqBpB,IAAa,sBAAb,MAAa,4BACH,UAEV;CACE,IAAI;CAEJ,WAAW;CAEX,iBAAiB;CAEjB,IAAI,YAAY;EACd,OAAO,CAAC,KAAK,UAAU,KAAK,cAAc;CAC5C;CAEA,YAAY;CAEZ,IAAI,aAAa;EACf,OAAO,CAAC,KAAK,SAAS;CACxB;CAEA;CAEA;CAEA;CAEA,wBAAwB;CAExB,YAAY,QAAkC;EAC5C,MAAM,MAAM;EACZ,KAAK,cAAc,OAAO;EAC1B,KAAK,wBAAwB,OAAO;EACpC,KAAK,yBAAyB,OAAO;EACrC,KAAK,WAAW,OAAO,YAAY,KAAK;EACxC,KAAK,YAAY,OAAO,aAAa,KAAK;EAC1C,KAAK,IAAI,OAAO,KAAK,KAAK;EAC1B,KAAK,wBACH,OAAO,yBAAyB,KAAK;CACzC;;CAGA,MAAM,MACJ,QACA,YACsB;EACtB,IAAI,EAAE,KAAK,YAAY,SACrB,MAAM,IAAI,MAAM,gBAAgB,KAAK,SAAS,YAAY;EAE5D,IAAI,EAAE,KAAK,kBAAkB,SAC3B,MAAM,IAAI,MAAM,oBAAoB,KAAK,SAAS,YAAY;EAEhE,MAAM,WAAmB,OAAO,KAAK;EACrC,MAAM,cAAsB,OAAO,KAAK;EACxC,IAAI,cAAc;EAClB,IAAI,YAAY,SAAS,GAAG;GAC1B,MAAM,SAAS,MAAM,KAAK,uBAAuB,KAC/C;IACE;IACA,cAAc;GAChB,GACA,YAAY,SAAS,oBAAoB,CAC3C;GACA,MAAM,OAAO,OAAO,KAAK,MAAM;GAC/B,QAAQ,IAAI,SAAS,QAAQ,IAAI;GACjC,IAAI,KAAK,WAAW,GAClB,cAAc,OAAO,KAAK;QAE1B,MAAM,IAAI,MACR,0EACF;EAEJ;EACA,MAAM,OAAO,MAAM,KAAK,YAAY,iBAClC,aACA,KAAK,GACL,KAAA,GACA,YAAY,SAAS,aAAa,CACpC;EACA,MAAM,SAAS;GACb,UAAU;GACV,iBAAiB;GACjB,cAAc;EAChB;EACA,MAAM,SAAS,MAAM,KAAK,sBAAsB,KAC9C,QACA,YAAY,SAAS,mBAAmB,CAC1C;EACA,IAAI,KAAK,uBACP,OAAO;GACL,GAAG;GACH,iBAAiB;EACnB;EAEF,OAAO;CACT;CAEA,aAAa;EACX,OAAO;CACT;CAEA,aAAa,YACX,MACA,QACA;EACA,IAAI,EAAE,iBAAiB,SACrB,MAAM,IAAI,MACR,8DACF;EAEF,MAAM,EAAE,gBAAgB;EAExB,OAAO,IAAI,oBAAoB;GAC7B,uBAAuB,MAAM,UAAU,YACrC,KAAK,uBACP;GACA,wBAAwB,MAAM,SAAS,YACrC,KAAK,kBACP;GACA,GAAG,KAAK;GACR;EACF,CAAC;CACH;CAEA,YAA2C;EACzC,OAAO;GACL,OAAO,KAAK,WAAW;GACvB,yBAAyB,KAAK,sBAAsB,UAAU;GAC9D,oBAAoB,KAAK,uBAAuB,UAAU;GAC1D,GAAG,KAAK;EACV;CACF;;;;;;;;;CAUA,OAAO,QACL,KACA,aACA,UAQI,CAAC,GACgB;EACrB,MAAM,EAAE,2BAA2B,YAAY,SAAS,GAAG,SAAS;EACpE,MAAM,4BAA4B,eAAe,aAC/C,6BAA6B,2BAC/B;
|
|
1
|
+
{"version":3,"file":"chat_vector_db_chain.js","names":[],"sources":["../../src/chains/chat_vector_db_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { VectorStoreInterface } from \"@langchain/core/vectorstores\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { loadQAStuffChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\nconst qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.\n\n{context}\n\nQuestion: {question}\nHelpful Answer:`;\n\n/**\n * Interface for the input parameters of the ChatVectorDBQAChain class.\n */\nexport interface ChatVectorDBQAChainInput extends ChainInputs {\n vectorstore: VectorStoreInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n outputKey?: string;\n inputKey?: string;\n k?: number;\n}\n\n/** @deprecated use `ConversationalRetrievalQAChain` instead. */\nexport class ChatVectorDBQAChain\n extends BaseChain\n implements ChatVectorDBQAChainInput\n{\n k = 4;\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n outputKey = \"result\";\n\n get outputKeys() {\n return [this.outputKey];\n }\n\n vectorstore: VectorStoreInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n constructor(fields: ChatVectorDBQAChainInput) {\n super(fields);\n this.vectorstore = fields.vectorstore;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.outputKey = fields.outputKey ?? this.outputKey;\n this.k = fields.k ?? this.k;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`chat history key ${this.inputKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string = values[this.chatHistoryKey];\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n console.log(\"_call\", values, keys);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.vectorstore.similaritySearch(\n newQuestion,\n this.k,\n undefined,\n runManager?.getChild(\"vectorstore\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n const result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n return {\n ...result,\n sourceDocuments: docs,\n };\n }\n return result;\n }\n\n _chainType() {\n return \"chat-vector-db\" as const;\n }\n\n static async deserialize(\n data: SerializedChatVectorDBQAChain,\n values: LoadValues\n ) {\n if (!(\"vectorstore\" in values)) {\n throw new Error(\n `Need to pass in a vectorstore to deserialize VectorDBQAChain`\n );\n }\n const { vectorstore } = values;\n\n return new ChatVectorDBQAChain({\n combineDocumentsChain: await BaseChain.deserialize(\n data.combine_documents_chain\n ),\n questionGeneratorChain: await LLMChain.deserialize(\n data.question_generator\n ),\n k: data.k,\n vectorstore,\n });\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n return {\n _type: this._chainType(),\n combine_documents_chain: this.combineDocumentsChain.serialize(),\n question_generator: this.questionGeneratorChain.serialize(),\n k: this.k,\n };\n }\n\n /**\n * Creates an instance of ChatVectorDBQAChain using a BaseLanguageModel\n * and other options.\n * @param llm Instance of BaseLanguageModel used to generate a new question.\n * @param vectorstore Instance of VectorStore used for vector operations.\n * @param options (Optional) Additional options for creating the ChatVectorDBQAChain instance.\n * @returns New instance of ChatVectorDBQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n vectorstore: VectorStoreInterface,\n options: {\n inputKey?: string;\n outputKey?: string;\n k?: number;\n returnSourceDocuments?: boolean;\n questionGeneratorTemplate?: string;\n qaTemplate?: string;\n verbose?: boolean;\n } = {}\n ): ChatVectorDBQAChain {\n const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;\n const question_generator_prompt = PromptTemplate.fromTemplate(\n questionGeneratorTemplate || question_generator_template\n );\n const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);\n\n const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt, verbose });\n const questionGeneratorChain = new LLMChain({\n prompt: question_generator_prompt,\n llm,\n verbose,\n });\n const instance = new this({\n vectorstore,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":";;;;;AAaA,MAAM,8BAA8B;;;;;;AAOpC,MAAM,cAAc;;;;;;;AAqBpB,IAAa,sBAAb,MAAa,4BACH,UAEV;CACE,IAAI;CAEJ,WAAW;CAEX,iBAAiB;CAEjB,IAAI,YAAY;EACd,OAAO,CAAC,KAAK,UAAU,KAAK,cAAc;CAC5C;CAEA,YAAY;CAEZ,IAAI,aAAa;EACf,OAAO,CAAC,KAAK,SAAS;CACxB;CAEA;CAEA;CAEA;CAEA,wBAAwB;CAExB,YAAY,QAAkC;EAC5C,MAAM,MAAM;EACZ,KAAK,cAAc,OAAO;EAC1B,KAAK,wBAAwB,OAAO;EACpC,KAAK,yBAAyB,OAAO;EACrC,KAAK,WAAW,OAAO,YAAY,KAAK;EACxC,KAAK,YAAY,OAAO,aAAa,KAAK;EAC1C,KAAK,IAAI,OAAO,KAAK,KAAK;EAC1B,KAAK,wBACH,OAAO,yBAAyB,KAAK;CACzC;;CAGA,MAAM,MACJ,QACA,YACsB;EACtB,IAAI,EAAE,KAAK,YAAY,SACrB,MAAM,IAAI,MAAM,gBAAgB,KAAK,SAAS,YAAY;EAE5D,IAAI,EAAE,KAAK,kBAAkB,SAC3B,MAAM,IAAI,MAAM,oBAAoB,KAAK,SAAS,YAAY;EAEhE,MAAM,WAAmB,OAAO,KAAK;EACrC,MAAM,cAAsB,OAAO,KAAK;EACxC,IAAI,cAAc;EAClB,IAAI,YAAY,SAAS,GAAG;GAC1B,MAAM,SAAS,MAAM,KAAK,uBAAuB,KAC/C;IACE;IACA,cAAc;GAChB,GACA,YAAY,SAAS,oBAAoB,CAC3C;GACA,MAAM,OAAO,OAAO,KAAK,MAAM;GAC/B,QAAQ,IAAI,SAAS,QAAQ,IAAI;GACjC,IAAI,KAAK,WAAW,GAClB,cAAc,OAAO,KAAK;QAE1B,MAAM,IAAI,MACR,0EACF;EAEJ;EACA,MAAM,OAAO,MAAM,KAAK,YAAY,iBAClC,aACA,KAAK,GACL,KAAA,GACA,YAAY,SAAS,aAAa,CACpC;EACA,MAAM,SAAS;GACb,UAAU;GACV,iBAAiB;GACjB,cAAc;EAChB;EACA,MAAM,SAAS,MAAM,KAAK,sBAAsB,KAC9C,QACA,YAAY,SAAS,mBAAmB,CAC1C;EACA,IAAI,KAAK,uBACP,OAAO;GACL,GAAG;GACH,iBAAiB;EACnB;EAEF,OAAO;CACT;CAEA,aAAa;EACX,OAAO;CACT;CAEA,aAAa,YACX,MACA,QACA;EACA,IAAI,EAAE,iBAAiB,SACrB,MAAM,IAAI,MACR,8DACF;EAEF,MAAM,EAAE,gBAAgB;EAExB,OAAO,IAAI,oBAAoB;GAC7B,uBAAuB,MAAM,UAAU,YACrC,KAAK,uBACP;GACA,wBAAwB,MAAM,SAAS,YACrC,KAAK,kBACP;GACA,GAAG,KAAK;GACR;EACF,CAAC;CACH;CAEA,YAA2C;EACzC,OAAO;GACL,OAAO,KAAK,WAAW;GACvB,yBAAyB,KAAK,sBAAsB,UAAU;GAC9D,oBAAoB,KAAK,uBAAuB,UAAU;GAC1D,GAAG,KAAK;EACV;CACF;;;;;;;;;CAUA,OAAO,QACL,KACA,aACA,UAQI,CAAC,GACgB;EACrB,MAAM,EAAE,2BAA2B,YAAY,SAAS,GAAG,SAAS;EACpE,MAAM,4BAA4B,eAAe,aAC/C,6BAA6B,2BAC/B;EACA,MAAM,YAAY,eAAe,aAAa,cAAc,WAAW;EAEvE,MAAM,UAAU,iBAAiB,KAAK;GAAE,QAAQ;GAAW;EAAQ,CAAC;EACpE,MAAM,yBAAyB,IAAI,SAAS;GAC1C,QAAQ;GACR;GACA;EACF,CAAC;EAOD,OAAO,IANc,KAAK;GACxB;GACA,uBAAuB;GACvB;GACA,GAAG;EACL,CACc;CAChB;AACF"}
|
|
@@ -191,8 +191,9 @@ var ConversationalRetrievalQAChain = class ConversationalRetrievalQAChain extend
|
|
|
191
191
|
prompt: qaTemplate ? _langchain_core_prompts.PromptTemplate.fromTemplate(qaTemplate) : void 0
|
|
192
192
|
}, questionGeneratorChainOptions, verbose, ...rest } = options;
|
|
193
193
|
const qaChain = require_load.loadQAChain(llm, qaChainOptions);
|
|
194
|
+
const questionGeneratorChainPrompt = _langchain_core_prompts.PromptTemplate.fromTemplate(questionGeneratorChainOptions?.template ?? questionGeneratorTemplate ?? question_generator_template);
|
|
194
195
|
const questionGeneratorChain = new require_llm_chain.LLMChain({
|
|
195
|
-
prompt:
|
|
196
|
+
prompt: questionGeneratorChainPrompt,
|
|
196
197
|
llm: questionGeneratorChainOptions?.llm ?? llm,
|
|
197
198
|
verbose
|
|
198
199
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversational_retrieval_chain.cjs","names":["BaseChain","HumanMessage","AIMessage","PromptTemplate","loadQAChain","LLMChain"],"sources":["../../src/chains/conversational_retrieval_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { BaseMessage, HumanMessage, AIMessage } from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { QAChainParams, loadQAChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\n/**\n * Interface for the input parameters of the\n * ConversationalRetrievalQAChain class.\n */\nexport interface ConversationalRetrievalQAChainInput extends ChainInputs {\n retriever: BaseRetrieverInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n returnGeneratedQuestion?: boolean;\n inputKey?: string;\n}\n\n/**\n * Class for conducting conversational question-answering tasks with a\n * retrieval component. Extends the BaseChain class and implements the\n * ConversationalRetrievalQAChainInput interface.\n * @example\n * ```typescript\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n * import {\n * ChatPromptTemplate,\n * MessagesPlaceholder,\n * } from \"@langchain/core/prompts\";\n * import { BaseMessage } from \"@langchain/core/messages\";\n * import { createStuffDocumentsChain } from \"@langchain/classic/chains/combine_documents\";\n * import { createHistoryAwareRetriever } from \"@langchain/classic/chains/history_aware_retriever\";\n * import { createRetrievalChain } from \"@langchain/classic/chains/retrieval\";\n *\n * const retriever = ...your retriever;\n * const llm = new ChatAnthropic();\n *\n * // Contextualize question\n * const contextualizeQSystemPrompt = `\n * Given a chat history and the latest user question\n * which might reference context in the chat history,\n * formulate a standalone question which can be understood\n * without the chat history. Do NOT answer the question, just\n * reformulate it if needed and otherwise return it as is.`;\n * const contextualizeQPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", contextualizeQSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n * const historyAwareRetriever = await createHistoryAwareRetriever({\n * llm,\n * retriever,\n * rephrasePrompt: contextualizeQPrompt,\n * });\n *\n * // Answer question\n * const qaSystemPrompt = `\n * You are an assistant for question-answering tasks. Use\n * the following pieces of retrieved context to answer the\n * question. If you don't know the answer, just say that you\n * don't know. Use three sentences maximum and keep the answer\n * concise.\n * \\n\\n\n * {context}`;\n * const qaPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", qaSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n *\n * // Below we use createStuffDocuments_chain to feed all retrieved context\n * // into the LLM. Note that we can also use StuffDocumentsChain and other\n * // instances of BaseCombineDocumentsChain.\n * const questionAnswerChain = await createStuffDocumentsChain({\n * llm,\n * prompt: qaPrompt,\n * });\n *\n * const ragChain = await createRetrievalChain({\n * retriever: historyAwareRetriever,\n * combineDocsChain: questionAnswerChain,\n * });\n *\n * // Usage:\n * const chat_history: BaseMessage[] = [];\n * const response = await ragChain.invoke({\n * chat_history,\n * input: \"...\",\n * });\n * ```\n */\nexport class ConversationalRetrievalQAChain\n extends BaseChain\n implements ConversationalRetrievalQAChainInput\n{\n static lc_name() {\n return \"ConversationalRetrievalQAChain\";\n }\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n get outputKeys() {\n return this.combineDocumentsChain.outputKeys.concat(\n this.returnSourceDocuments ? [\"sourceDocuments\"] : []\n );\n }\n\n retriever: BaseRetrieverInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n returnGeneratedQuestion = false;\n\n constructor(fields: ConversationalRetrievalQAChainInput) {\n super(fields);\n this.retriever = fields.retriever;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n this.returnGeneratedQuestion =\n fields.returnGeneratedQuestion ?? this.returnGeneratedQuestion;\n }\n\n /**\n * Static method to convert the chat history input into a formatted\n * string.\n * @param chatHistory Chat history input which can be a string, an array of BaseMessage instances, or an array of string arrays.\n * @returns A formatted string representing the chat history.\n */\n static getChatHistoryString(\n chatHistory: string | BaseMessage[] | string[][]\n ) {\n let historyMessages: BaseMessage[];\n if (Array.isArray(chatHistory)) {\n // TODO: Deprecate on a breaking release\n if (\n Array.isArray(chatHistory[0]) &&\n typeof chatHistory[0][0] === \"string\"\n ) {\n console.warn(\n \"Passing chat history as an array of strings is deprecated.\\nPlease see https://js.langchain.com/docs/modules/chains/popular/chat_vector_db#externally-managed-memory for more information.\"\n );\n historyMessages = chatHistory.flat().map((stringMessage, i) => {\n if (i % 2 === 0) {\n return new HumanMessage(stringMessage);\n } else {\n return new AIMessage(stringMessage);\n }\n });\n } else {\n historyMessages = chatHistory as BaseMessage[];\n }\n return historyMessages\n .map((chatMessage) => {\n if (chatMessage._getType() === \"human\") {\n return `Human: ${chatMessage.content}`;\n } else if (chatMessage._getType() === \"ai\") {\n return `Assistant: ${chatMessage.content}`;\n } else {\n return `${chatMessage.content}`;\n }\n })\n .join(\"\\n\");\n }\n return chatHistory;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`Chat history key ${this.chatHistoryKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string =\n ConversationalRetrievalQAChain.getChatHistoryString(\n values[this.chatHistoryKey]\n );\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.retriever.invoke(\n newQuestion,\n runManager?.getChild(\"retriever\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n let result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n result = {\n ...result,\n sourceDocuments: docs,\n };\n }\n if (this.returnGeneratedQuestion) {\n result = {\n ...result,\n generatedQuestion: newQuestion,\n };\n }\n return result;\n }\n\n _chainType(): string {\n return \"conversational_retrieval_chain\";\n }\n\n static async deserialize(\n _data: SerializedChatVectorDBQAChain,\n _values: LoadValues\n ): Promise<ConversationalRetrievalQAChain> {\n throw new Error(\"Not implemented.\");\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Static method to create a new ConversationalRetrievalQAChain from a\n * BaseLanguageModel and a BaseRetriever.\n * @param llm {@link BaseLanguageModelInterface} instance used to generate a new question.\n * @param retriever {@link BaseRetrieverInterface} instance used to retrieve relevant documents.\n * @param options.returnSourceDocuments Whether to return source documents in the final output\n * @param options.questionGeneratorChainOptions Options to initialize the standalone question generation chain used as the first internal step\n * @param options.qaChainOptions {@link QAChainParams} used to initialize the QA chain used as the second internal step\n * @returns A new instance of ConversationalRetrievalQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n retriever: BaseRetrieverInterface,\n options: {\n outputKey?: string; // not used\n returnSourceDocuments?: boolean;\n /** @deprecated Pass in questionGeneratorChainOptions.template instead */\n questionGeneratorTemplate?: string;\n /** @deprecated Pass in qaChainOptions.prompt instead */\n qaTemplate?: string;\n questionGeneratorChainOptions?: {\n llm?: BaseLanguageModelInterface;\n template?: string;\n };\n qaChainOptions?: QAChainParams;\n } & Omit<\n ConversationalRetrievalQAChainInput,\n \"retriever\" | \"combineDocumentsChain\" | \"questionGeneratorChain\"\n > = {}\n ): ConversationalRetrievalQAChain {\n const {\n questionGeneratorTemplate,\n qaTemplate,\n qaChainOptions = {\n type: \"stuff\",\n prompt: qaTemplate\n ? PromptTemplate.fromTemplate(qaTemplate)\n : undefined,\n },\n questionGeneratorChainOptions,\n verbose,\n ...rest\n } = options;\n\n const qaChain = loadQAChain(llm, qaChainOptions);\n\n const questionGeneratorChainPrompt = PromptTemplate.fromTemplate(\n questionGeneratorChainOptions?.template ??\n questionGeneratorTemplate ??\n question_generator_template\n );\n const questionGeneratorChain = new LLMChain({\n prompt: questionGeneratorChainPrompt,\n llm: questionGeneratorChainOptions?.llm ?? llm,\n verbose,\n });\n const instance = new this({\n retriever,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n verbose,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversational_retrieval_chain.cjs","names":["BaseChain","HumanMessage","AIMessage","PromptTemplate","loadQAChain","LLMChain"],"sources":["../../src/chains/conversational_retrieval_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { BaseMessage, HumanMessage, AIMessage } from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { QAChainParams, loadQAChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\n/**\n * Interface for the input parameters of the\n * ConversationalRetrievalQAChain class.\n */\nexport interface ConversationalRetrievalQAChainInput extends ChainInputs {\n retriever: BaseRetrieverInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n returnGeneratedQuestion?: boolean;\n inputKey?: string;\n}\n\n/**\n * Class for conducting conversational question-answering tasks with a\n * retrieval component. Extends the BaseChain class and implements the\n * ConversationalRetrievalQAChainInput interface.\n * @example\n * ```typescript\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n * import {\n * ChatPromptTemplate,\n * MessagesPlaceholder,\n * } from \"@langchain/core/prompts\";\n * import { BaseMessage } from \"@langchain/core/messages\";\n * import { createStuffDocumentsChain } from \"@langchain/classic/chains/combine_documents\";\n * import { createHistoryAwareRetriever } from \"@langchain/classic/chains/history_aware_retriever\";\n * import { createRetrievalChain } from \"@langchain/classic/chains/retrieval\";\n *\n * const retriever = ...your retriever;\n * const llm = new ChatAnthropic();\n *\n * // Contextualize question\n * const contextualizeQSystemPrompt = `\n * Given a chat history and the latest user question\n * which might reference context in the chat history,\n * formulate a standalone question which can be understood\n * without the chat history. Do NOT answer the question, just\n * reformulate it if needed and otherwise return it as is.`;\n * const contextualizeQPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", contextualizeQSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n * const historyAwareRetriever = await createHistoryAwareRetriever({\n * llm,\n * retriever,\n * rephrasePrompt: contextualizeQPrompt,\n * });\n *\n * // Answer question\n * const qaSystemPrompt = `\n * You are an assistant for question-answering tasks. Use\n * the following pieces of retrieved context to answer the\n * question. If you don't know the answer, just say that you\n * don't know. Use three sentences maximum and keep the answer\n * concise.\n * \\n\\n\n * {context}`;\n * const qaPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", qaSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n *\n * // Below we use createStuffDocuments_chain to feed all retrieved context\n * // into the LLM. Note that we can also use StuffDocumentsChain and other\n * // instances of BaseCombineDocumentsChain.\n * const questionAnswerChain = await createStuffDocumentsChain({\n * llm,\n * prompt: qaPrompt,\n * });\n *\n * const ragChain = await createRetrievalChain({\n * retriever: historyAwareRetriever,\n * combineDocsChain: questionAnswerChain,\n * });\n *\n * // Usage:\n * const chat_history: BaseMessage[] = [];\n * const response = await ragChain.invoke({\n * chat_history,\n * input: \"...\",\n * });\n * ```\n */\nexport class ConversationalRetrievalQAChain\n extends BaseChain\n implements ConversationalRetrievalQAChainInput\n{\n static lc_name() {\n return \"ConversationalRetrievalQAChain\";\n }\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n get outputKeys() {\n return this.combineDocumentsChain.outputKeys.concat(\n this.returnSourceDocuments ? [\"sourceDocuments\"] : []\n );\n }\n\n retriever: BaseRetrieverInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n returnGeneratedQuestion = false;\n\n constructor(fields: ConversationalRetrievalQAChainInput) {\n super(fields);\n this.retriever = fields.retriever;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n this.returnGeneratedQuestion =\n fields.returnGeneratedQuestion ?? this.returnGeneratedQuestion;\n }\n\n /**\n * Static method to convert the chat history input into a formatted\n * string.\n * @param chatHistory Chat history input which can be a string, an array of BaseMessage instances, or an array of string arrays.\n * @returns A formatted string representing the chat history.\n */\n static getChatHistoryString(\n chatHistory: string | BaseMessage[] | string[][]\n ) {\n let historyMessages: BaseMessage[];\n if (Array.isArray(chatHistory)) {\n // TODO: Deprecate on a breaking release\n if (\n Array.isArray(chatHistory[0]) &&\n typeof chatHistory[0][0] === \"string\"\n ) {\n console.warn(\n \"Passing chat history as an array of strings is deprecated.\\nPlease see https://js.langchain.com/docs/modules/chains/popular/chat_vector_db#externally-managed-memory for more information.\"\n );\n historyMessages = chatHistory.flat().map((stringMessage, i) => {\n if (i % 2 === 0) {\n return new HumanMessage(stringMessage);\n } else {\n return new AIMessage(stringMessage);\n }\n });\n } else {\n historyMessages = chatHistory as BaseMessage[];\n }\n return historyMessages\n .map((chatMessage) => {\n if (chatMessage._getType() === \"human\") {\n return `Human: ${chatMessage.content}`;\n } else if (chatMessage._getType() === \"ai\") {\n return `Assistant: ${chatMessage.content}`;\n } else {\n return `${chatMessage.content}`;\n }\n })\n .join(\"\\n\");\n }\n return chatHistory;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`Chat history key ${this.chatHistoryKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string =\n ConversationalRetrievalQAChain.getChatHistoryString(\n values[this.chatHistoryKey]\n );\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.retriever.invoke(\n newQuestion,\n runManager?.getChild(\"retriever\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n let result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n result = {\n ...result,\n sourceDocuments: docs,\n };\n }\n if (this.returnGeneratedQuestion) {\n result = {\n ...result,\n generatedQuestion: newQuestion,\n };\n }\n return result;\n }\n\n _chainType(): string {\n return \"conversational_retrieval_chain\";\n }\n\n static async deserialize(\n _data: SerializedChatVectorDBQAChain,\n _values: LoadValues\n ): Promise<ConversationalRetrievalQAChain> {\n throw new Error(\"Not implemented.\");\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Static method to create a new ConversationalRetrievalQAChain from a\n * BaseLanguageModel and a BaseRetriever.\n * @param llm {@link BaseLanguageModelInterface} instance used to generate a new question.\n * @param retriever {@link BaseRetrieverInterface} instance used to retrieve relevant documents.\n * @param options.returnSourceDocuments Whether to return source documents in the final output\n * @param options.questionGeneratorChainOptions Options to initialize the standalone question generation chain used as the first internal step\n * @param options.qaChainOptions {@link QAChainParams} used to initialize the QA chain used as the second internal step\n * @returns A new instance of ConversationalRetrievalQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n retriever: BaseRetrieverInterface,\n options: {\n outputKey?: string; // not used\n returnSourceDocuments?: boolean;\n /** @deprecated Pass in questionGeneratorChainOptions.template instead */\n questionGeneratorTemplate?: string;\n /** @deprecated Pass in qaChainOptions.prompt instead */\n qaTemplate?: string;\n questionGeneratorChainOptions?: {\n llm?: BaseLanguageModelInterface;\n template?: string;\n };\n qaChainOptions?: QAChainParams;\n } & Omit<\n ConversationalRetrievalQAChainInput,\n \"retriever\" | \"combineDocumentsChain\" | \"questionGeneratorChain\"\n > = {}\n ): ConversationalRetrievalQAChain {\n const {\n questionGeneratorTemplate,\n qaTemplate,\n qaChainOptions = {\n type: \"stuff\",\n prompt: qaTemplate\n ? PromptTemplate.fromTemplate(qaTemplate)\n : undefined,\n },\n questionGeneratorChainOptions,\n verbose,\n ...rest\n } = options;\n\n const qaChain = loadQAChain(llm, qaChainOptions);\n\n const questionGeneratorChainPrompt = PromptTemplate.fromTemplate(\n questionGeneratorChainOptions?.template ??\n questionGeneratorTemplate ??\n question_generator_template\n );\n const questionGeneratorChain = new LLMChain({\n prompt: questionGeneratorChainPrompt,\n llm: questionGeneratorChainOptions?.llm ?? llm,\n verbose,\n });\n const instance = new this({\n retriever,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n verbose,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
@@ -191,8 +191,9 @@ var ConversationalRetrievalQAChain = class ConversationalRetrievalQAChain extend
|
|
|
191
191
|
prompt: qaTemplate ? PromptTemplate.fromTemplate(qaTemplate) : void 0
|
|
192
192
|
}, questionGeneratorChainOptions, verbose, ...rest } = options;
|
|
193
193
|
const qaChain = loadQAChain(llm, qaChainOptions);
|
|
194
|
+
const questionGeneratorChainPrompt = PromptTemplate.fromTemplate(questionGeneratorChainOptions?.template ?? questionGeneratorTemplate ?? question_generator_template);
|
|
194
195
|
const questionGeneratorChain = new LLMChain({
|
|
195
|
-
prompt:
|
|
196
|
+
prompt: questionGeneratorChainPrompt,
|
|
196
197
|
llm: questionGeneratorChainOptions?.llm ?? llm,
|
|
197
198
|
verbose
|
|
198
199
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversational_retrieval_chain.js","names":[],"sources":["../../src/chains/conversational_retrieval_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { BaseMessage, HumanMessage, AIMessage } from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { QAChainParams, loadQAChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\n/**\n * Interface for the input parameters of the\n * ConversationalRetrievalQAChain class.\n */\nexport interface ConversationalRetrievalQAChainInput extends ChainInputs {\n retriever: BaseRetrieverInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n returnGeneratedQuestion?: boolean;\n inputKey?: string;\n}\n\n/**\n * Class for conducting conversational question-answering tasks with a\n * retrieval component. Extends the BaseChain class and implements the\n * ConversationalRetrievalQAChainInput interface.\n * @example\n * ```typescript\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n * import {\n * ChatPromptTemplate,\n * MessagesPlaceholder,\n * } from \"@langchain/core/prompts\";\n * import { BaseMessage } from \"@langchain/core/messages\";\n * import { createStuffDocumentsChain } from \"@langchain/classic/chains/combine_documents\";\n * import { createHistoryAwareRetriever } from \"@langchain/classic/chains/history_aware_retriever\";\n * import { createRetrievalChain } from \"@langchain/classic/chains/retrieval\";\n *\n * const retriever = ...your retriever;\n * const llm = new ChatAnthropic();\n *\n * // Contextualize question\n * const contextualizeQSystemPrompt = `\n * Given a chat history and the latest user question\n * which might reference context in the chat history,\n * formulate a standalone question which can be understood\n * without the chat history. Do NOT answer the question, just\n * reformulate it if needed and otherwise return it as is.`;\n * const contextualizeQPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", contextualizeQSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n * const historyAwareRetriever = await createHistoryAwareRetriever({\n * llm,\n * retriever,\n * rephrasePrompt: contextualizeQPrompt,\n * });\n *\n * // Answer question\n * const qaSystemPrompt = `\n * You are an assistant for question-answering tasks. Use\n * the following pieces of retrieved context to answer the\n * question. If you don't know the answer, just say that you\n * don't know. Use three sentences maximum and keep the answer\n * concise.\n * \\n\\n\n * {context}`;\n * const qaPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", qaSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n *\n * // Below we use createStuffDocuments_chain to feed all retrieved context\n * // into the LLM. Note that we can also use StuffDocumentsChain and other\n * // instances of BaseCombineDocumentsChain.\n * const questionAnswerChain = await createStuffDocumentsChain({\n * llm,\n * prompt: qaPrompt,\n * });\n *\n * const ragChain = await createRetrievalChain({\n * retriever: historyAwareRetriever,\n * combineDocsChain: questionAnswerChain,\n * });\n *\n * // Usage:\n * const chat_history: BaseMessage[] = [];\n * const response = await ragChain.invoke({\n * chat_history,\n * input: \"...\",\n * });\n * ```\n */\nexport class ConversationalRetrievalQAChain\n extends BaseChain\n implements ConversationalRetrievalQAChainInput\n{\n static lc_name() {\n return \"ConversationalRetrievalQAChain\";\n }\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n get outputKeys() {\n return this.combineDocumentsChain.outputKeys.concat(\n this.returnSourceDocuments ? [\"sourceDocuments\"] : []\n );\n }\n\n retriever: BaseRetrieverInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n returnGeneratedQuestion = false;\n\n constructor(fields: ConversationalRetrievalQAChainInput) {\n super(fields);\n this.retriever = fields.retriever;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n this.returnGeneratedQuestion =\n fields.returnGeneratedQuestion ?? this.returnGeneratedQuestion;\n }\n\n /**\n * Static method to convert the chat history input into a formatted\n * string.\n * @param chatHistory Chat history input which can be a string, an array of BaseMessage instances, or an array of string arrays.\n * @returns A formatted string representing the chat history.\n */\n static getChatHistoryString(\n chatHistory: string | BaseMessage[] | string[][]\n ) {\n let historyMessages: BaseMessage[];\n if (Array.isArray(chatHistory)) {\n // TODO: Deprecate on a breaking release\n if (\n Array.isArray(chatHistory[0]) &&\n typeof chatHistory[0][0] === \"string\"\n ) {\n console.warn(\n \"Passing chat history as an array of strings is deprecated.\\nPlease see https://js.langchain.com/docs/modules/chains/popular/chat_vector_db#externally-managed-memory for more information.\"\n );\n historyMessages = chatHistory.flat().map((stringMessage, i) => {\n if (i % 2 === 0) {\n return new HumanMessage(stringMessage);\n } else {\n return new AIMessage(stringMessage);\n }\n });\n } else {\n historyMessages = chatHistory as BaseMessage[];\n }\n return historyMessages\n .map((chatMessage) => {\n if (chatMessage._getType() === \"human\") {\n return `Human: ${chatMessage.content}`;\n } else if (chatMessage._getType() === \"ai\") {\n return `Assistant: ${chatMessage.content}`;\n } else {\n return `${chatMessage.content}`;\n }\n })\n .join(\"\\n\");\n }\n return chatHistory;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`Chat history key ${this.chatHistoryKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string =\n ConversationalRetrievalQAChain.getChatHistoryString(\n values[this.chatHistoryKey]\n );\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.retriever.invoke(\n newQuestion,\n runManager?.getChild(\"retriever\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n let result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n result = {\n ...result,\n sourceDocuments: docs,\n };\n }\n if (this.returnGeneratedQuestion) {\n result = {\n ...result,\n generatedQuestion: newQuestion,\n };\n }\n return result;\n }\n\n _chainType(): string {\n return \"conversational_retrieval_chain\";\n }\n\n static async deserialize(\n _data: SerializedChatVectorDBQAChain,\n _values: LoadValues\n ): Promise<ConversationalRetrievalQAChain> {\n throw new Error(\"Not implemented.\");\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Static method to create a new ConversationalRetrievalQAChain from a\n * BaseLanguageModel and a BaseRetriever.\n * @param llm {@link BaseLanguageModelInterface} instance used to generate a new question.\n * @param retriever {@link BaseRetrieverInterface} instance used to retrieve relevant documents.\n * @param options.returnSourceDocuments Whether to return source documents in the final output\n * @param options.questionGeneratorChainOptions Options to initialize the standalone question generation chain used as the first internal step\n * @param options.qaChainOptions {@link QAChainParams} used to initialize the QA chain used as the second internal step\n * @returns A new instance of ConversationalRetrievalQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n retriever: BaseRetrieverInterface,\n options: {\n outputKey?: string; // not used\n returnSourceDocuments?: boolean;\n /** @deprecated Pass in questionGeneratorChainOptions.template instead */\n questionGeneratorTemplate?: string;\n /** @deprecated Pass in qaChainOptions.prompt instead */\n qaTemplate?: string;\n questionGeneratorChainOptions?: {\n llm?: BaseLanguageModelInterface;\n template?: string;\n };\n qaChainOptions?: QAChainParams;\n } & Omit<\n ConversationalRetrievalQAChainInput,\n \"retriever\" | \"combineDocumentsChain\" | \"questionGeneratorChain\"\n > = {}\n ): ConversationalRetrievalQAChain {\n const {\n questionGeneratorTemplate,\n qaTemplate,\n qaChainOptions = {\n type: \"stuff\",\n prompt: qaTemplate\n ? PromptTemplate.fromTemplate(qaTemplate)\n : undefined,\n },\n questionGeneratorChainOptions,\n verbose,\n ...rest\n } = options;\n\n const qaChain = loadQAChain(llm, qaChainOptions);\n\n const questionGeneratorChainPrompt = PromptTemplate.fromTemplate(\n questionGeneratorChainOptions?.template ??\n questionGeneratorTemplate ??\n question_generator_template\n );\n const questionGeneratorChain = new LLMChain({\n prompt: questionGeneratorChainPrompt,\n llm: questionGeneratorChainOptions?.llm ?? llm,\n verbose,\n });\n const instance = new this({\n retriever,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n verbose,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversational_retrieval_chain.js","names":[],"sources":["../../src/chains/conversational_retrieval_chain.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { BaseMessage, HumanMessage, AIMessage } from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { SerializedChatVectorDBQAChain } from \"./serde.js\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\nimport { LLMChain } from \"./llm_chain.js\";\nimport { QAChainParams, loadQAChain } from \"./question_answering/load.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport type LoadValues = Record<string, any>;\n\nconst question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.\n\nChat History:\n{chat_history}\nFollow Up Input: {question}\nStandalone question:`;\n\n/**\n * Interface for the input parameters of the\n * ConversationalRetrievalQAChain class.\n */\nexport interface ConversationalRetrievalQAChainInput extends ChainInputs {\n retriever: BaseRetrieverInterface;\n combineDocumentsChain: BaseChain;\n questionGeneratorChain: LLMChain;\n returnSourceDocuments?: boolean;\n returnGeneratedQuestion?: boolean;\n inputKey?: string;\n}\n\n/**\n * Class for conducting conversational question-answering tasks with a\n * retrieval component. Extends the BaseChain class and implements the\n * ConversationalRetrievalQAChainInput interface.\n * @example\n * ```typescript\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n * import {\n * ChatPromptTemplate,\n * MessagesPlaceholder,\n * } from \"@langchain/core/prompts\";\n * import { BaseMessage } from \"@langchain/core/messages\";\n * import { createStuffDocumentsChain } from \"@langchain/classic/chains/combine_documents\";\n * import { createHistoryAwareRetriever } from \"@langchain/classic/chains/history_aware_retriever\";\n * import { createRetrievalChain } from \"@langchain/classic/chains/retrieval\";\n *\n * const retriever = ...your retriever;\n * const llm = new ChatAnthropic();\n *\n * // Contextualize question\n * const contextualizeQSystemPrompt = `\n * Given a chat history and the latest user question\n * which might reference context in the chat history,\n * formulate a standalone question which can be understood\n * without the chat history. Do NOT answer the question, just\n * reformulate it if needed and otherwise return it as is.`;\n * const contextualizeQPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", contextualizeQSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n * const historyAwareRetriever = await createHistoryAwareRetriever({\n * llm,\n * retriever,\n * rephrasePrompt: contextualizeQPrompt,\n * });\n *\n * // Answer question\n * const qaSystemPrompt = `\n * You are an assistant for question-answering tasks. Use\n * the following pieces of retrieved context to answer the\n * question. If you don't know the answer, just say that you\n * don't know. Use three sentences maximum and keep the answer\n * concise.\n * \\n\\n\n * {context}`;\n * const qaPrompt = ChatPromptTemplate.fromMessages([\n * [\"system\", qaSystemPrompt],\n * new MessagesPlaceholder(\"chat_history\"),\n * [\"human\", \"{input}\"],\n * ]);\n *\n * // Below we use createStuffDocuments_chain to feed all retrieved context\n * // into the LLM. Note that we can also use StuffDocumentsChain and other\n * // instances of BaseCombineDocumentsChain.\n * const questionAnswerChain = await createStuffDocumentsChain({\n * llm,\n * prompt: qaPrompt,\n * });\n *\n * const ragChain = await createRetrievalChain({\n * retriever: historyAwareRetriever,\n * combineDocsChain: questionAnswerChain,\n * });\n *\n * // Usage:\n * const chat_history: BaseMessage[] = [];\n * const response = await ragChain.invoke({\n * chat_history,\n * input: \"...\",\n * });\n * ```\n */\nexport class ConversationalRetrievalQAChain\n extends BaseChain\n implements ConversationalRetrievalQAChainInput\n{\n static lc_name() {\n return \"ConversationalRetrievalQAChain\";\n }\n\n inputKey = \"question\";\n\n chatHistoryKey = \"chat_history\";\n\n get inputKeys() {\n return [this.inputKey, this.chatHistoryKey];\n }\n\n get outputKeys() {\n return this.combineDocumentsChain.outputKeys.concat(\n this.returnSourceDocuments ? [\"sourceDocuments\"] : []\n );\n }\n\n retriever: BaseRetrieverInterface;\n\n combineDocumentsChain: BaseChain;\n\n questionGeneratorChain: LLMChain;\n\n returnSourceDocuments = false;\n\n returnGeneratedQuestion = false;\n\n constructor(fields: ConversationalRetrievalQAChainInput) {\n super(fields);\n this.retriever = fields.retriever;\n this.combineDocumentsChain = fields.combineDocumentsChain;\n this.questionGeneratorChain = fields.questionGeneratorChain;\n this.inputKey = fields.inputKey ?? this.inputKey;\n this.returnSourceDocuments =\n fields.returnSourceDocuments ?? this.returnSourceDocuments;\n this.returnGeneratedQuestion =\n fields.returnGeneratedQuestion ?? this.returnGeneratedQuestion;\n }\n\n /**\n * Static method to convert the chat history input into a formatted\n * string.\n * @param chatHistory Chat history input which can be a string, an array of BaseMessage instances, or an array of string arrays.\n * @returns A formatted string representing the chat history.\n */\n static getChatHistoryString(\n chatHistory: string | BaseMessage[] | string[][]\n ) {\n let historyMessages: BaseMessage[];\n if (Array.isArray(chatHistory)) {\n // TODO: Deprecate on a breaking release\n if (\n Array.isArray(chatHistory[0]) &&\n typeof chatHistory[0][0] === \"string\"\n ) {\n console.warn(\n \"Passing chat history as an array of strings is deprecated.\\nPlease see https://js.langchain.com/docs/modules/chains/popular/chat_vector_db#externally-managed-memory for more information.\"\n );\n historyMessages = chatHistory.flat().map((stringMessage, i) => {\n if (i % 2 === 0) {\n return new HumanMessage(stringMessage);\n } else {\n return new AIMessage(stringMessage);\n }\n });\n } else {\n historyMessages = chatHistory as BaseMessage[];\n }\n return historyMessages\n .map((chatMessage) => {\n if (chatMessage._getType() === \"human\") {\n return `Human: ${chatMessage.content}`;\n } else if (chatMessage._getType() === \"ai\") {\n return `Assistant: ${chatMessage.content}`;\n } else {\n return `${chatMessage.content}`;\n }\n })\n .join(\"\\n\");\n }\n return chatHistory;\n }\n\n /** @ignore */\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n if (!(this.inputKey in values)) {\n throw new Error(`Question key ${this.inputKey} not found.`);\n }\n if (!(this.chatHistoryKey in values)) {\n throw new Error(`Chat history key ${this.chatHistoryKey} not found.`);\n }\n const question: string = values[this.inputKey];\n const chatHistory: string =\n ConversationalRetrievalQAChain.getChatHistoryString(\n values[this.chatHistoryKey]\n );\n let newQuestion = question;\n if (chatHistory.length > 0) {\n const result = await this.questionGeneratorChain.call(\n {\n question,\n chat_history: chatHistory,\n },\n runManager?.getChild(\"question_generator\")\n );\n const keys = Object.keys(result);\n if (keys.length === 1) {\n newQuestion = result[keys[0]];\n } else {\n throw new Error(\n \"Return from llm chain has multiple values, only single values supported.\"\n );\n }\n }\n const docs = await this.retriever.invoke(\n newQuestion,\n runManager?.getChild(\"retriever\")\n );\n const inputs = {\n question: newQuestion,\n input_documents: docs,\n chat_history: chatHistory,\n };\n let result = await this.combineDocumentsChain.call(\n inputs,\n runManager?.getChild(\"combine_documents\")\n );\n if (this.returnSourceDocuments) {\n result = {\n ...result,\n sourceDocuments: docs,\n };\n }\n if (this.returnGeneratedQuestion) {\n result = {\n ...result,\n generatedQuestion: newQuestion,\n };\n }\n return result;\n }\n\n _chainType(): string {\n return \"conversational_retrieval_chain\";\n }\n\n static async deserialize(\n _data: SerializedChatVectorDBQAChain,\n _values: LoadValues\n ): Promise<ConversationalRetrievalQAChain> {\n throw new Error(\"Not implemented.\");\n }\n\n serialize(): SerializedChatVectorDBQAChain {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Static method to create a new ConversationalRetrievalQAChain from a\n * BaseLanguageModel and a BaseRetriever.\n * @param llm {@link BaseLanguageModelInterface} instance used to generate a new question.\n * @param retriever {@link BaseRetrieverInterface} instance used to retrieve relevant documents.\n * @param options.returnSourceDocuments Whether to return source documents in the final output\n * @param options.questionGeneratorChainOptions Options to initialize the standalone question generation chain used as the first internal step\n * @param options.qaChainOptions {@link QAChainParams} used to initialize the QA chain used as the second internal step\n * @returns A new instance of ConversationalRetrievalQAChain.\n */\n static fromLLM(\n llm: BaseLanguageModelInterface,\n retriever: BaseRetrieverInterface,\n options: {\n outputKey?: string; // not used\n returnSourceDocuments?: boolean;\n /** @deprecated Pass in questionGeneratorChainOptions.template instead */\n questionGeneratorTemplate?: string;\n /** @deprecated Pass in qaChainOptions.prompt instead */\n qaTemplate?: string;\n questionGeneratorChainOptions?: {\n llm?: BaseLanguageModelInterface;\n template?: string;\n };\n qaChainOptions?: QAChainParams;\n } & Omit<\n ConversationalRetrievalQAChainInput,\n \"retriever\" | \"combineDocumentsChain\" | \"questionGeneratorChain\"\n > = {}\n ): ConversationalRetrievalQAChain {\n const {\n questionGeneratorTemplate,\n qaTemplate,\n qaChainOptions = {\n type: \"stuff\",\n prompt: qaTemplate\n ? PromptTemplate.fromTemplate(qaTemplate)\n : undefined,\n },\n questionGeneratorChainOptions,\n verbose,\n ...rest\n } = options;\n\n const qaChain = loadQAChain(llm, qaChainOptions);\n\n const questionGeneratorChainPrompt = PromptTemplate.fromTemplate(\n questionGeneratorChainOptions?.template ??\n questionGeneratorTemplate ??\n question_generator_template\n );\n const questionGeneratorChain = new LLMChain({\n prompt: questionGeneratorChainPrompt,\n llm: questionGeneratorChainOptions?.llm ?? llm,\n verbose,\n });\n const instance = new this({\n retriever,\n combineDocumentsChain: qaChain,\n questionGeneratorChain,\n verbose,\n ...rest,\n });\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.cjs","names":["JsonOutputFunctionsParser"],"sources":["../../../src/chains/openai_functions/base.ts"],"sourcesContent":["import type { BaseOutputParser } from \"@langchain/core/output_parsers\";\nimport type { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport type { Runnable, RunnableInterface } from \"@langchain/core/runnables\";\nimport type {\n BaseFunctionCallOptions,\n BaseLanguageModelInput,\n FunctionDefinition,\n} from \"@langchain/core/language_models/base\";\nimport {\n isInteropZodSchema,\n type InputValues,\n InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { JsonOutputFunctionsParser } from \"../../output_parsers/openai_functions.js\";\n\n/**\n * Configuration params for the createOpenAIFnRunnable method.\n */\nexport type CreateOpenAIFnRunnableConfig<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any>,\n RunOutput,\n> = {\n functions: FunctionDefinition[];\n /** Language model to use, assumed to support the OpenAI function-calling API. */\n llm: RunnableInterface<\n BaseLanguageModelInput,\n BaseMessage,\n BaseFunctionCallOptions\n >;\n /** BasePromptTemplate to pass to the model. */\n prompt: BasePromptTemplate<InputValues<Extract<keyof RunInput, string>>>;\n /**\n * Only used if a single function is passed in. If `true`, then the model will be\n * forced to use the given function. If `false`, then the model will be given the\n * option to use the given function or not.\n */\n enforceSingleFunctionUsage?: boolean;\n /**\n * BaseLLMOutputParser to use for parsing model outputs.\n * By default will be inferred from the function types.\n */\n outputParser?: BaseOutputParser<RunOutput>;\n};\n\n/**\n * Creates a runnable sequence that calls OpenAI functions.\n * @param config - The parameters required to create the runnable.\n * @returns A runnable sequence that will pass the given functions to the model when run.\n *\n * @example\n * ```typescript\n * const openAIFunction = {\n * name: \"get_person_details\",\n * description: \"Get details about a person\",\n * parameters: {\n * title: \"Person\",\n * description: \"Identifying information about a person.\",\n * type: \"object\",\n * properties: {\n * name: { title: \"Name\", description: \"The person's name\", type: \"string\" },\n * age: { title: \"Age\", description: \"The person's age\", type: \"integer\" },\n * fav_food: {\n * title: \"Fav Food\",\n * description: \"The person's favorite food\",\n * type: \"string\",\n * },\n * },\n * required: [\"name\", \"age\"],\n * },\n * };\n *\n * const model = new ChatOpenAI();\n * const prompt = ChatPromptTemplate.fromMessages([\n * [\"human\", \"Human description: {description}\"],\n * ]);\n * const outputParser = new JsonOutputFunctionsParser();\n *\n * const runnable = createOpenAIFnRunnable({\n * functions: [openAIFunction],\n * llm: model,\n * prompt,\n * enforceSingleFunctionUsage: true, // Default is true\n * outputParser\n * });\n * const response = await runnable.invoke({\n * description:\n * \"My name's John Doe and I'm 30 years old. My favorite kind of food are chocolate chip cookies.\",\n * });\n *\n * console.log(response);\n *\n * // { name: 'John Doe', age: 30, fav_food: 'chocolate chip cookies' }\n * ```\n */\nexport function createOpenAIFnRunnable<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any> = Record<string, any>,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n config: CreateOpenAIFnRunnableConfig<RunInput, RunOutput>\n): Runnable<RunInput, RunOutput> {\n const {\n functions,\n llm,\n prompt,\n enforceSingleFunctionUsage = true,\n outputParser = new JsonOutputFunctionsParser<RunOutput>(),\n } = config;\n const llmKwargs: BaseFunctionCallOptions = {\n functions,\n };\n\n if (functions.length === 1 && enforceSingleFunctionUsage) {\n llmKwargs.function_call = {\n name: functions[0].name,\n };\n }\n\n const llmWithKwargs = (llm as Runnable).withConfig(llmKwargs);\n return prompt.pipe(llmWithKwargs).pipe(outputParser);\n}\n\n/**\n * Configuration params for the createStructuredOutputRunnable method.\n */\nexport type CreateStructuredOutputRunnableConfig<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any>,\n RunOutput,\n> = {\n /**\n * Schema to output. Must be either valid JSONSchema or a Zod schema.\n */\n outputSchema: InteropZodObject | JsonSchema7Type;\n /**\n * Language model to use, assumed to support the OpenAI function-calling API.\n */\n llm: RunnableInterface<\n BaseLanguageModelInput,\n BaseMessage,\n BaseFunctionCallOptions\n >;\n /** BasePromptTemplate to pass to the model. */\n prompt: BasePromptTemplate<InputValues<Extract<keyof RunInput, string>>>;\n /**\n * BaseLLMOutputParser to use for parsing model outputs.\n */\n outputParser?: BaseOutputParser<RunOutput>;\n};\n\n/**\n * @deprecated Prefer the `.withStructuredOutput` method on chat model classes.\n *\n * Create a runnable that uses an OpenAI function to get a structured output.\n * @param config Params required to create the runnable.\n * @returns A runnable sequence that will pass the given function to the model when run.\n *\n * @example\n * ```typescript\n * import { createStructuredOutputRunnable } from \"@langchain/classic/chains/openai_functions\";\n * import { ChatOpenAI } from \"@langchain/openai\";\n * import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n * import { JsonOutputFunctionsParser } from \"@langchain/classic/output_parsers\";\n *\n * const jsonSchema = {\n * title: \"Person\",\n * description: \"Identifying information about a person.\",\n * type: \"object\",\n * properties: {\n * name: { title: \"Name\", description: \"The person's name\", type: \"string\" },\n * age: { title: \"Age\", description: \"The person's age\", type: \"integer\" },\n * fav_food: {\n * title: \"Fav Food\",\n * description: \"The person's favorite food\",\n * type: \"string\",\n * },\n * },\n * required: [\"name\", \"age\"],\n * };\n *\n * const model = new ChatOpenAI({ model: \"gpt-4o-mini\" });\n * const prompt = ChatPromptTemplate.fromMessages([\n * [\"human\", \"Human description: {description}\"],\n * ]);\n *\n * const outputParser = new JsonOutputFunctionsParser();\n *\n * // Also works with Zod schema\n * const runnable = createStructuredOutputRunnable({\n * outputSchema: jsonSchema,\n * llm: model,\n * prompt,\n * outputParser\n * });\n *\n * const response = await runnable.invoke({\n * description:\n * \"My name's John Doe and I'm 30 years old. My favorite kind of food are chocolate chip cookies.\",\n * });\n *\n * console.log(response);\n *\n * // { name: 'John Doe', age: 30, fav_food: 'chocolate chip cookies' }\n * ```\n */\nexport function createStructuredOutputRunnable<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any> = Record<string, any>,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n config: CreateStructuredOutputRunnableConfig<RunInput, RunOutput>\n): Runnable<RunInput, RunOutput> {\n const { outputSchema, llm, prompt, outputParser } = config;\n const jsonSchema = isInteropZodSchema(outputSchema)\n ? toJsonSchema(outputSchema)\n : outputSchema;\n const oaiFunction: FunctionDefinition = {\n name: \"outputFormatter\",\n description:\n \"Output formatter. Should always be used to format your response to the user\",\n parameters: jsonSchema,\n };\n\n return createOpenAIFnRunnable({\n functions: [oaiFunction],\n llm,\n prompt,\n enforceSingleFunctionUsage: true,\n outputParser,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoGA,SAAgB,uBAMd,QAC+B;CAC/B,MAAM,EACJ,WACA,KACA,QACA,6BAA6B,MAC7B,eAAe,IAAIA,yBAAAA,0BAAqC,MACtD;CACJ,MAAM,YAAqC,EACzC,UACF;CAEA,IAAI,UAAU,WAAW,KAAK,4BAC5B,UAAU,gBAAgB,EACxB,MAAM,UAAU,EAAE,CAAC,KACrB;CAGF,MAAM,gBAAiB,IAAiB,WAAW,SAAS;CAC5D,OAAO,OAAO,KAAK,aAAa,CAAC,CAAC,KAAK,YAAY;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,+BAMd,QAC+B;CAC/B,MAAM,EAAE,cAAc,KAAK,QAAQ,iBAAiB;CAWpD,OAAO,uBAAuB;EAC5B,WAAW,CAAC;GAPZ,MAAM;GACN,aACE;GACF,aAAA,
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["JsonOutputFunctionsParser","isInteropZodSchema","toJsonSchema"],"sources":["../../../src/chains/openai_functions/base.ts"],"sourcesContent":["import type { BaseOutputParser } from \"@langchain/core/output_parsers\";\nimport type { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport type { Runnable, RunnableInterface } from \"@langchain/core/runnables\";\nimport type {\n BaseFunctionCallOptions,\n BaseLanguageModelInput,\n FunctionDefinition,\n} from \"@langchain/core/language_models/base\";\nimport {\n isInteropZodSchema,\n type InputValues,\n InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { JsonOutputFunctionsParser } from \"../../output_parsers/openai_functions.js\";\n\n/**\n * Configuration params for the createOpenAIFnRunnable method.\n */\nexport type CreateOpenAIFnRunnableConfig<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any>,\n RunOutput,\n> = {\n functions: FunctionDefinition[];\n /** Language model to use, assumed to support the OpenAI function-calling API. */\n llm: RunnableInterface<\n BaseLanguageModelInput,\n BaseMessage,\n BaseFunctionCallOptions\n >;\n /** BasePromptTemplate to pass to the model. */\n prompt: BasePromptTemplate<InputValues<Extract<keyof RunInput, string>>>;\n /**\n * Only used if a single function is passed in. If `true`, then the model will be\n * forced to use the given function. If `false`, then the model will be given the\n * option to use the given function or not.\n */\n enforceSingleFunctionUsage?: boolean;\n /**\n * BaseLLMOutputParser to use for parsing model outputs.\n * By default will be inferred from the function types.\n */\n outputParser?: BaseOutputParser<RunOutput>;\n};\n\n/**\n * Creates a runnable sequence that calls OpenAI functions.\n * @param config - The parameters required to create the runnable.\n * @returns A runnable sequence that will pass the given functions to the model when run.\n *\n * @example\n * ```typescript\n * const openAIFunction = {\n * name: \"get_person_details\",\n * description: \"Get details about a person\",\n * parameters: {\n * title: \"Person\",\n * description: \"Identifying information about a person.\",\n * type: \"object\",\n * properties: {\n * name: { title: \"Name\", description: \"The person's name\", type: \"string\" },\n * age: { title: \"Age\", description: \"The person's age\", type: \"integer\" },\n * fav_food: {\n * title: \"Fav Food\",\n * description: \"The person's favorite food\",\n * type: \"string\",\n * },\n * },\n * required: [\"name\", \"age\"],\n * },\n * };\n *\n * const model = new ChatOpenAI();\n * const prompt = ChatPromptTemplate.fromMessages([\n * [\"human\", \"Human description: {description}\"],\n * ]);\n * const outputParser = new JsonOutputFunctionsParser();\n *\n * const runnable = createOpenAIFnRunnable({\n * functions: [openAIFunction],\n * llm: model,\n * prompt,\n * enforceSingleFunctionUsage: true, // Default is true\n * outputParser\n * });\n * const response = await runnable.invoke({\n * description:\n * \"My name's John Doe and I'm 30 years old. My favorite kind of food are chocolate chip cookies.\",\n * });\n *\n * console.log(response);\n *\n * // { name: 'John Doe', age: 30, fav_food: 'chocolate chip cookies' }\n * ```\n */\nexport function createOpenAIFnRunnable<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any> = Record<string, any>,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n config: CreateOpenAIFnRunnableConfig<RunInput, RunOutput>\n): Runnable<RunInput, RunOutput> {\n const {\n functions,\n llm,\n prompt,\n enforceSingleFunctionUsage = true,\n outputParser = new JsonOutputFunctionsParser<RunOutput>(),\n } = config;\n const llmKwargs: BaseFunctionCallOptions = {\n functions,\n };\n\n if (functions.length === 1 && enforceSingleFunctionUsage) {\n llmKwargs.function_call = {\n name: functions[0].name,\n };\n }\n\n const llmWithKwargs = (llm as Runnable).withConfig(llmKwargs);\n return prompt.pipe(llmWithKwargs).pipe(outputParser);\n}\n\n/**\n * Configuration params for the createStructuredOutputRunnable method.\n */\nexport type CreateStructuredOutputRunnableConfig<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any>,\n RunOutput,\n> = {\n /**\n * Schema to output. Must be either valid JSONSchema or a Zod schema.\n */\n outputSchema: InteropZodObject | JsonSchema7Type;\n /**\n * Language model to use, assumed to support the OpenAI function-calling API.\n */\n llm: RunnableInterface<\n BaseLanguageModelInput,\n BaseMessage,\n BaseFunctionCallOptions\n >;\n /** BasePromptTemplate to pass to the model. */\n prompt: BasePromptTemplate<InputValues<Extract<keyof RunInput, string>>>;\n /**\n * BaseLLMOutputParser to use for parsing model outputs.\n */\n outputParser?: BaseOutputParser<RunOutput>;\n};\n\n/**\n * @deprecated Prefer the `.withStructuredOutput` method on chat model classes.\n *\n * Create a runnable that uses an OpenAI function to get a structured output.\n * @param config Params required to create the runnable.\n * @returns A runnable sequence that will pass the given function to the model when run.\n *\n * @example\n * ```typescript\n * import { createStructuredOutputRunnable } from \"@langchain/classic/chains/openai_functions\";\n * import { ChatOpenAI } from \"@langchain/openai\";\n * import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n * import { JsonOutputFunctionsParser } from \"@langchain/classic/output_parsers\";\n *\n * const jsonSchema = {\n * title: \"Person\",\n * description: \"Identifying information about a person.\",\n * type: \"object\",\n * properties: {\n * name: { title: \"Name\", description: \"The person's name\", type: \"string\" },\n * age: { title: \"Age\", description: \"The person's age\", type: \"integer\" },\n * fav_food: {\n * title: \"Fav Food\",\n * description: \"The person's favorite food\",\n * type: \"string\",\n * },\n * },\n * required: [\"name\", \"age\"],\n * };\n *\n * const model = new ChatOpenAI({ model: \"gpt-4o-mini\" });\n * const prompt = ChatPromptTemplate.fromMessages([\n * [\"human\", \"Human description: {description}\"],\n * ]);\n *\n * const outputParser = new JsonOutputFunctionsParser();\n *\n * // Also works with Zod schema\n * const runnable = createStructuredOutputRunnable({\n * outputSchema: jsonSchema,\n * llm: model,\n * prompt,\n * outputParser\n * });\n *\n * const response = await runnable.invoke({\n * description:\n * \"My name's John Doe and I'm 30 years old. My favorite kind of food are chocolate chip cookies.\",\n * });\n *\n * console.log(response);\n *\n * // { name: 'John Doe', age: 30, fav_food: 'chocolate chip cookies' }\n * ```\n */\nexport function createStructuredOutputRunnable<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput extends Record<string, any> = Record<string, any>,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n config: CreateStructuredOutputRunnableConfig<RunInput, RunOutput>\n): Runnable<RunInput, RunOutput> {\n const { outputSchema, llm, prompt, outputParser } = config;\n const jsonSchema = isInteropZodSchema(outputSchema)\n ? toJsonSchema(outputSchema)\n : outputSchema;\n const oaiFunction: FunctionDefinition = {\n name: \"outputFormatter\",\n description:\n \"Output formatter. Should always be used to format your response to the user\",\n parameters: jsonSchema,\n };\n\n return createOpenAIFnRunnable({\n functions: [oaiFunction],\n llm,\n prompt,\n enforceSingleFunctionUsage: true,\n outputParser,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoGA,SAAgB,uBAMd,QAC+B;CAC/B,MAAM,EACJ,WACA,KACA,QACA,6BAA6B,MAC7B,eAAe,IAAIA,yBAAAA,0BAAqC,MACtD;CACJ,MAAM,YAAqC,EACzC,UACF;CAEA,IAAI,UAAU,WAAW,KAAK,4BAC5B,UAAU,gBAAgB,EACxB,MAAM,UAAU,EAAE,CAAC,KACrB;CAGF,MAAM,gBAAiB,IAAiB,WAAW,SAAS;CAC5D,OAAO,OAAO,KAAK,aAAa,CAAC,CAAC,KAAK,YAAY;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,+BAMd,QAC+B;CAC/B,MAAM,EAAE,cAAc,KAAK,QAAQ,iBAAiB;CAWpD,OAAO,uBAAuB;EAC5B,WAAW,CAAC;GAPZ,MAAM;GACN,aACE;GACF,aAAA,GAPiBC,4BAAAA,mBAAAA,CAAmB,YAAY,KAAA,GAC9CC,kCAAAA,aAAAA,CAAa,YAAY,IACzB;EASoB,CAAC;EACvB;EACA;EACA,4BAA4B;EAC5B;CACF,CAAC;AACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.cjs","names":["PromptTemplate","JsonKeyOutputFunctionsParser","LLMChain"],"sources":["../../../src/chains/openai_functions/extraction.ts"],"sourcesContent":["import { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { BaseFunctionCallOptions } from \"@langchain/core/language_models/base\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\nimport type { AIMessageChunk } from \"@langchain/core/messages\";\nimport {\n type JsonSchema7ObjectType,\n toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n FunctionParameters,\n JsonKeyOutputFunctionsParser,\n} from \"../../output_parsers/openai_functions.js\";\nimport { LLMChain } from \"../llm_chain.js\";\n\n/**\n * Function that returns an array of extraction functions. These functions\n * are used to extract relevant information from a passage.\n * @param schema The schema of the function parameters.\n * @returns An array of extraction functions.\n */\nfunction getExtractionFunctions(schema: FunctionParameters) {\n return [\n {\n name: \"information_extraction\",\n description: \"Extracts the relevant information from the passage.\",\n parameters: {\n type: \"object\",\n properties: {\n info: {\n type: \"array\",\n items: {\n type: schema.type,\n properties: schema.properties,\n required: schema.required,\n },\n },\n },\n required: [\"info\"],\n },\n },\n ];\n}\n\nconst _EXTRACTION_TEMPLATE = `Extract and save the relevant entities mentioned in the following passage together with their properties.\n\nPassage:\n{input}\n`;\n\n/**\n * Function that creates an extraction chain using the provided JSON schema.\n * It sets up the necessary components, such as the prompt, output parser, and tags.\n * @param schema JSON schema of the function parameters.\n * @param llm Must be a ChatOpenAI or AnthropicFunctions model that supports function calling.\n * @returns A LLMChain instance configured to return data matching the schema.\n */\nexport function createExtractionChain(\n schema: FunctionParameters,\n llm: BaseChatModel<BaseFunctionCallOptions>\n): LLMChain<object, BaseChatModel<BaseFunctionCallOptions, AIMessageChunk>> {\n const functions = getExtractionFunctions(schema);\n const prompt = PromptTemplate.fromTemplate(_EXTRACTION_TEMPLATE);\n const outputParser = new JsonKeyOutputFunctionsParser({ attrName: \"info\" });\n return new LLMChain({\n llm,\n prompt,\n llmKwargs: { functions },\n outputParser,\n tags: [\"openai_functions\", \"extraction\"],\n });\n}\n\n/**\n * Function that creates an extraction chain from a Zod schema. It\n * converts the Zod schema to a JSON schema using before creating\n * the extraction chain.\n * @param schema The Zod schema which extracted data should match\n * @param llm Must be a ChatOpenAI or AnthropicFunctions model that supports function calling.\n * @returns A LLMChain instance configured to return data matching the schema.\n */\nexport function createExtractionChainFromZod(\n schema: InteropZodObject,\n llm: BaseChatModel<BaseFunctionCallOptions>\n): LLMChain<object, BaseChatModel<BaseFunctionCallOptions, AIMessageChunk>> {\n return createExtractionChain(\n toJsonSchema(schema) as JsonSchema7ObjectType,\n llm\n );\n}\n"],"mappings":";;;;;;;;;;;AAqBA,SAAS,uBAAuB,QAA4B;CAC1D,OAAO,CACL;EACE,MAAM;EACN,aAAa;EACb,YAAY;GACV,MAAM;GACN,YAAY,EACV,MAAM;IACJ,MAAM;IACN,OAAO;KACL,MAAM,OAAO;KACb,YAAY,OAAO;KACnB,UAAU,OAAO;IACnB;GACF,EACF;GACA,UAAU,CAAC,MAAM;EACnB;CACF,CACF;AACF;AAEA,MAAM,uBAAuB;;;;;;;;;;;;AAa7B,SAAgB,sBACd,QACA,KAC0E;CAC1E,MAAM,YAAY,uBAAuB,MAAM;CAC/C,MAAM,SAASA,wBAAAA,eAAe,aAAa,oBAAoB;CAC/D,MAAM,eAAe,IAAIC,yBAAAA,6BAA6B,EAAE,UAAU,OAAO,CAAC;CAC1E,OAAO,IAAIC,kBAAAA,SAAS;EAClB;EACA;EACA,WAAW,EAAE,UAAU;EACvB;EACA,MAAM,CAAC,oBAAoB,YAAY;CACzC,CAAC;AACH;;;;;;;;;AAUA,SAAgB,6BACd,QACA,KAC0E;CAC1E,OAAO,uBAAA,
|
|
1
|
+
{"version":3,"file":"extraction.cjs","names":["PromptTemplate","JsonKeyOutputFunctionsParser","LLMChain","toJsonSchema"],"sources":["../../../src/chains/openai_functions/extraction.ts"],"sourcesContent":["import { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { BaseFunctionCallOptions } from \"@langchain/core/language_models/base\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\nimport type { AIMessageChunk } from \"@langchain/core/messages\";\nimport {\n type JsonSchema7ObjectType,\n toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n FunctionParameters,\n JsonKeyOutputFunctionsParser,\n} from \"../../output_parsers/openai_functions.js\";\nimport { LLMChain } from \"../llm_chain.js\";\n\n/**\n * Function that returns an array of extraction functions. These functions\n * are used to extract relevant information from a passage.\n * @param schema The schema of the function parameters.\n * @returns An array of extraction functions.\n */\nfunction getExtractionFunctions(schema: FunctionParameters) {\n return [\n {\n name: \"information_extraction\",\n description: \"Extracts the relevant information from the passage.\",\n parameters: {\n type: \"object\",\n properties: {\n info: {\n type: \"array\",\n items: {\n type: schema.type,\n properties: schema.properties,\n required: schema.required,\n },\n },\n },\n required: [\"info\"],\n },\n },\n ];\n}\n\nconst _EXTRACTION_TEMPLATE = `Extract and save the relevant entities mentioned in the following passage together with their properties.\n\nPassage:\n{input}\n`;\n\n/**\n * Function that creates an extraction chain using the provided JSON schema.\n * It sets up the necessary components, such as the prompt, output parser, and tags.\n * @param schema JSON schema of the function parameters.\n * @param llm Must be a ChatOpenAI or AnthropicFunctions model that supports function calling.\n * @returns A LLMChain instance configured to return data matching the schema.\n */\nexport function createExtractionChain(\n schema: FunctionParameters,\n llm: BaseChatModel<BaseFunctionCallOptions>\n): LLMChain<object, BaseChatModel<BaseFunctionCallOptions, AIMessageChunk>> {\n const functions = getExtractionFunctions(schema);\n const prompt = PromptTemplate.fromTemplate(_EXTRACTION_TEMPLATE);\n const outputParser = new JsonKeyOutputFunctionsParser({ attrName: \"info\" });\n return new LLMChain({\n llm,\n prompt,\n llmKwargs: { functions },\n outputParser,\n tags: [\"openai_functions\", \"extraction\"],\n });\n}\n\n/**\n * Function that creates an extraction chain from a Zod schema. It\n * converts the Zod schema to a JSON schema using before creating\n * the extraction chain.\n * @param schema The Zod schema which extracted data should match\n * @param llm Must be a ChatOpenAI or AnthropicFunctions model that supports function calling.\n * @returns A LLMChain instance configured to return data matching the schema.\n */\nexport function createExtractionChainFromZod(\n schema: InteropZodObject,\n llm: BaseChatModel<BaseFunctionCallOptions>\n): LLMChain<object, BaseChatModel<BaseFunctionCallOptions, AIMessageChunk>> {\n return createExtractionChain(\n toJsonSchema(schema) as JsonSchema7ObjectType,\n llm\n );\n}\n"],"mappings":";;;;;;;;;;;AAqBA,SAAS,uBAAuB,QAA4B;CAC1D,OAAO,CACL;EACE,MAAM;EACN,aAAa;EACb,YAAY;GACV,MAAM;GACN,YAAY,EACV,MAAM;IACJ,MAAM;IACN,OAAO;KACL,MAAM,OAAO;KACb,YAAY,OAAO;KACnB,UAAU,OAAO;IACnB;GACF,EACF;GACA,UAAU,CAAC,MAAM;EACnB;CACF,CACF;AACF;AAEA,MAAM,uBAAuB;;;;;;;;;;;;AAa7B,SAAgB,sBACd,QACA,KAC0E;CAC1E,MAAM,YAAY,uBAAuB,MAAM;CAC/C,MAAM,SAASA,wBAAAA,eAAe,aAAa,oBAAoB;CAC/D,MAAM,eAAe,IAAIC,yBAAAA,6BAA6B,EAAE,UAAU,OAAO,CAAC;CAC1E,OAAO,IAAIC,kBAAAA,SAAS;EAClB;EACA;EACA,WAAW,EAAE,UAAU;EACvB;EACA,MAAM,CAAC,oBAAoB,YAAY;CACzC,CAAC;AACH;;;;;;;;;AAUA,SAAgB,6BACd,QACA,KAC0E;CAC1E,OAAO,uBAAA,GACLC,kCAAAA,aAAAA,CAAa,MAAM,GACnB,GACF;AACF"}
|
|
@@ -29,14 +29,15 @@ function formatURL(url, pathParams) {
|
|
|
29
29
|
const cleanParamName = paramName.replace(/^\.;/, "").replace(/\*$/, "");
|
|
30
30
|
const value = pathParams[cleanParamName];
|
|
31
31
|
let formattedValue;
|
|
32
|
-
if (Array.isArray(value))
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
if (paramName.startsWith(".")) {
|
|
34
|
+
const separator = paramName.endsWith("*") ? "." : ",";
|
|
35
|
+
formattedValue = `.${value.join(separator)}`;
|
|
36
|
+
} else if (paramName.startsWith(",")) {
|
|
37
|
+
const separator = paramName.endsWith("*") ? `${cleanParamName}=` : ",";
|
|
38
|
+
formattedValue = `${cleanParamName}=${value.join(separator)}`;
|
|
39
|
+
} else formattedValue = value.join(",");
|
|
40
|
+
} else if (typeof value === "object") {
|
|
40
41
|
const kvSeparator = paramName.endsWith("*") ? "=" : ",";
|
|
41
42
|
const kvStrings = Object.entries(value).map(([k, v]) => k + kvSeparator + v);
|
|
42
43
|
let entrySeparator;
|