From a708561bb22a52be5886cf52a97ed968090bc89e Mon Sep 17 00:00:00 2001 From: bracesproul Date: Wed, 31 Jul 2024 15:39:03 -0700 Subject: [PATCH] :cr --- docs/core_docs/.gitignore | 4 +- .../docs/integrations/chat/mistral.ipynb | 254 ++++++------------ libs/langchain-mistralai/src/chat_models.ts | 8 +- 3 files changed, 91 insertions(+), 175 deletions(-) diff --git a/docs/core_docs/.gitignore b/docs/core_docs/.gitignore index aa23525d4033..d6d1df5db70f 100644 --- a/docs/core_docs/.gitignore +++ b/docs/core_docs/.gitignore @@ -209,4 +209,6 @@ docs/how_to/assign.mdx docs/how_to/agent_executor.md docs/how_to/agent_executor.mdx docs/integrations/llms/mistral.md -docs/integrations/llms/mistral.mdx \ No newline at end of file +docs/integrations/llms/mistral.mdx +docs/integrations/chat/mistral.md +docs/integrations/chat/mistral.mdx \ No newline at end of file diff --git a/docs/core_docs/docs/integrations/chat/mistral.ipynb b/docs/core_docs/docs/integrations/chat/mistral.ipynb index 0718227e5063..e0da1701d8f1 100644 --- a/docs/core_docs/docs/integrations/chat/mistral.ipynb +++ b/docs/core_docs/docs/integrations/chat/mistral.ipynb @@ -39,37 +39,17 @@ "\n", "Head [here](https://console.mistral.ai/) to sign up to Mistral AI and generate an API key. Once you've done this set the `MISTRAL_API_KEY` environment variable:\n", "\n", - "```{=mdx}\n", - "\n", "```bash\n", "export MISTRAL_API_KEY=\"your-api-key\"\n", "```\n", "\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "72ee0c4b-9764-423a-9dbf-95129e185210", - "metadata": {}, - "source": [ "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n", "\n", - "```{=mdx}\n", - "\n", "```bash\n", "# export LANGCHAIN_TRACING_V2=\"true\"\n", "# export LANGCHAIN_API_KEY=\"your-api-key\"\n", "```\n", "\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "0730d6a1-c893-4840-9817-5e5251676d5d", - "metadata": {}, - "source": [ "### Installation\n", "\n", "The LangChain ChatMistralAI integration lives in the `@langchain/mistralai` package:\n", @@ -98,15 +78,7 @@ "execution_count": 1, "id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "3:7 - Exported variable 'llm' has or is using name 'MistralAICallOptions' from external module \"/Users/bracesproul/code/lang-chain-ai/langchainjs/libs/langchain-mistralai/dist/chat_models\" but cannot be named.\n" - ] - } - ], + "outputs": [], "source": [ "import { ChatMistralAI } from \"@langchain/mistralai\" \n", "\n", @@ -135,40 +107,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "62e0dbc3", "metadata": { "tags": [] }, "outputs": [ { - "data": { - "text/plain": [ - "AIMessage {\n", - " lc_serializable: \u001b[33mtrue\u001b[39m,\n", - " lc_kwargs: {\n", - " content: \u001b[32m`Sure, I'd be happy to help you translate that sentence into French! The English sentence \"I love pro`\u001b[39m... 126 more characters,\n", - " tool_calls: [],\n", - " invalid_tool_calls: [],\n", - " additional_kwargs: { tool_calls: [] },\n", - " response_metadata: {}\n", - " },\n", - " lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n", - " content: \u001b[32m`Sure, I'd be happy to help you translate that sentence into French! The English sentence \"I love pro`\u001b[39m... 126 more characters,\n", - " name: \u001b[90mundefined\u001b[39m,\n", - " additional_kwargs: { tool_calls: [] },\n", - " response_metadata: {\n", - " tokenUsage: { completionTokens: \u001b[33m52\u001b[39m, promptTokens: \u001b[33m32\u001b[39m, totalTokens: \u001b[33m84\u001b[39m },\n", - " finish_reason: \u001b[32m\"stop\"\u001b[39m\n", - " },\n", - " tool_calls: [],\n", - " invalid_tool_calls: []\n", - "}" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "AIMessage {\n", + " \"content\": \"Sure, I'd be happy to help you translate that sentence into French! The English sentence \\\"I love programming\\\" translates to \\\"J'aime programmer\\\" in French. Let me know if you have any other questions or need further assistance!\",\n", + " \"additional_kwargs\": {},\n", + " \"response_metadata\": {\n", + " \"tokenUsage\": {\n", + " \"completionTokens\": 52,\n", + " \"promptTokens\": 32,\n", + " \"totalTokens\": 84\n", + " },\n", + " \"finish_reason\": \"stop\"\n", + " },\n", + " \"tool_calls\": [],\n", + " \"invalid_tool_calls\": [],\n", + " \"usage_metadata\": {\n", + " \"input_tokens\": 32,\n", + " \"output_tokens\": 52,\n", + " \"total_tokens\": 84\n", + " }\n", + "}\n" + ] } ], "source": [ @@ -184,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "d86145b3-bfef-46e8-b227-4dda5c9c2705", "metadata": {}, "outputs": [ @@ -212,44 +180,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b", "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "AIMessage {\n", - " lc_serializable: \u001b[33mtrue\u001b[39m,\n", - " lc_kwargs: {\n", - " content: \u001b[32m\"Ich liebe Programmierung. (German translation)\"\u001b[39m,\n", - " tool_calls: [],\n", - " invalid_tool_calls: [],\n", - " additional_kwargs: { tool_calls: [] },\n", - " response_metadata: {}\n", - " },\n", - " lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n", - " content: \u001b[32m\"Ich liebe Programmierung. (German translation)\"\u001b[39m,\n", - " name: \u001b[90mundefined\u001b[39m,\n", - " additional_kwargs: { tool_calls: [] },\n", - " response_metadata: {\n", - " tokenUsage: { completionTokens: \u001b[33m12\u001b[39m, promptTokens: \u001b[33m26\u001b[39m, totalTokens: \u001b[33m38\u001b[39m },\n", - " finish_reason: \u001b[32m\"stop\"\u001b[39m\n", - " },\n", - " tool_calls: [],\n", - " invalid_tool_calls: []\n", - "}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "Error in handler LangChainTracer, handleChainEnd: AbortError: The user aborted a request.\n" + "AIMessage {\n", + " \"content\": \"Ich liebe Programmierung. (German translation)\",\n", + " \"additional_kwargs\": {},\n", + " \"response_metadata\": {\n", + " \"tokenUsage\": {\n", + " \"completionTokens\": 12,\n", + " \"promptTokens\": 26,\n", + " \"totalTokens\": 38\n", + " },\n", + " \"finish_reason\": \"stop\"\n", + " },\n", + " \"tool_calls\": [],\n", + " \"invalid_tool_calls\": [],\n", + " \"usage_metadata\": {\n", + " \"input_tokens\": 26,\n", + " \"output_tokens\": 12,\n", + " \"total_tokens\": 38\n", + " }\n", + "}\n" ] } ], @@ -289,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "98d9034c", "metadata": {}, "outputs": [ @@ -299,9 +256,10 @@ "text": [ "[\n", " {\n", - " name: \"calculator\",\n", - " args: { operation: \"add\", number1: 2, number2: 2 },\n", - " id: \"Qcw6so4hJ\"\n", + " name: 'calculator',\n", + " args: { operation: 'add', number1: 2, number2: 2 },\n", + " type: 'tool_call',\n", + " id: '2HFfjvCvo'\n", " }\n", "]\n" ] @@ -375,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "a8638d82", "metadata": {}, "outputs": [ @@ -383,7 +341,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{ operation: \"add\", number1: 2, number2: 2 }\n" + "{ operation: 'add', number1: 2, number2: 2 }\n" ] } ], @@ -436,7 +394,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "9786b41a", "metadata": {}, "outputs": [ @@ -448,79 +406,65 @@ " raw: AIMessage {\n", " lc_serializable: true,\n", " lc_kwargs: {\n", - " content: \"\",\n", + " content: '',\n", " tool_calls: [\n", " {\n", - " name: \"calculator\",\n", - " args: { operation: \"add\", number1: 2, number2: 2 },\n", - " id: \"qQz1AWzNd\"\n", + " name: 'calculator',\n", + " args: { operation: 'add', number1: 2, number2: 2 },\n", + " type: 'tool_call',\n", + " id: 'qVxKofNLR'\n", " }\n", " ],\n", " invalid_tool_calls: [],\n", " additional_kwargs: {\n", " tool_calls: [\n", " {\n", - " id: \"qQz1AWzNd\",\n", + " id: 'qVxKofNLR',\n", " function: {\n", - " name: \"calculator\",\n", + " name: 'calculator',\n", " arguments: '{\"operation\": \"add\", \"number1\": 2, \"number2\": 2}'\n", - " }\n", + " },\n", + " type: 'function'\n", " }\n", " ]\n", " },\n", + " usage_metadata: { input_tokens: 205, output_tokens: 34, total_tokens: 239 },\n", " response_metadata: {}\n", " },\n", - " lc_namespace: [ \"langchain_core\", \"messages\" ],\n", - " content: \"\",\n", + " lc_namespace: [ 'langchain_core', 'messages' ],\n", + " content: '',\n", " name: undefined,\n", " additional_kwargs: {\n", " tool_calls: [\n", " {\n", - " id: \"qQz1AWzNd\",\n", + " id: 'qVxKofNLR',\n", " function: {\n", - " name: \"calculator\",\n", + " name: 'calculator',\n", " arguments: '{\"operation\": \"add\", \"number1\": 2, \"number2\": 2}'\n", - " }\n", + " },\n", + " type: 'function'\n", " }\n", " ]\n", " },\n", " response_metadata: {\n", " tokenUsage: { completionTokens: 34, promptTokens: 205, totalTokens: 239 },\n", - " finish_reason: \"tool_calls\"\n", + " finish_reason: 'tool_calls'\n", " },\n", + " id: undefined,\n", " tool_calls: [\n", " {\n", - " name: \"calculator\",\n", - " args: { operation: \"add\", number1: 2, number2: 2 },\n", - " id: \"qQz1AWzNd\"\n", + " name: 'calculator',\n", + " args: { operation: 'add', number1: 2, number2: 2 },\n", + " type: 'tool_call',\n", + " id: 'qVxKofNLR'\n", " }\n", " ],\n", - " invalid_tool_calls: []\n", + " invalid_tool_calls: [],\n", + " usage_metadata: { input_tokens: 205, output_tokens: 34, total_tokens: 239 }\n", " },\n", - " parsed: { operation: \"add\", number1: 2, number2: 2 }\n", + " parsed: { operation: 'add', number1: 2, number2: 2 }\n", "}\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "AbortError: The user aborted a request.\n", - " at abort (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/node-fetch/2.7.0/lib/index.js:1458:16)\n", - " at AbortSignal.abortAndFinalize (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/node-fetch/2.7.0/lib/index.js:1473:4)\n", - " at innerInvokeEventListeners (ext:deno_web/02_event.js:754:7)\n", - " at invokeEventListeners (ext:deno_web/02_event.js:801:5)\n", - " at dispatch (ext:deno_web/02_event.js:658:9)\n", - " at AbortSignal.dispatchEvent (ext:deno_web/02_event.js:1043:12)\n", - " at AbortSignal.[[[signalAbort]]] (ext:deno_web/03_abort_signal.js:146:11)\n", - " at ext:deno_web/03_abort_signal.js:116:28\n", - " at Object.action (ext:deno_web/02_timers.js:154:11)\n", - " at handleTimerMacrotask (ext:deno_web/02_timers.js:68:10) {\n", - " type: \"aborted\",\n", - " message: \"The user aborted a request.\"\n", - "}\n", - "Error in handler LangChainTracer, handleChainEnd: AbortError: The user aborted a request.\n" - ] } ], "source": [ @@ -546,7 +490,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "9f1dc9bd", "metadata": {}, "outputs": [ @@ -554,14 +498,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{ operation: \"add\", number1: 2, number2: 2 }\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Error in handler LangChainTracer, handleChainEnd: AbortError: The user aborted a request.\n" + "{ operation: 'add', number1: 2, number2: 2 }\n" ] } ], @@ -624,36 +561,15 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "76bd0061", "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "Request failed: HTTP error! status: 400 Response: \n", - "{\"object\":\"error\",\"message\":\"Tool call id has to be defined in serving mode.\",\"type\":\"invalid_request_error\",\"param\":null,\"code\":null}\n" - ] - }, - { - "ename": "MistralAPIError", - "evalue": "HTTP error! status: 400 Response: \n{\"object\":\"error\",\"message\":\"Tool call id has to be defined in serving mode.\",\"type\":\"invalid_request_error\",\"param\":null,\"code\":null}", - "output_type": "error", - "traceback": [ - "Stack trace:", - "MistralAPIError: HTTP error! status: 400 Response: ", - "{\"object\":\"error\",\"message\":\"Tool call id has to be defined in serving mode.\",\"type\":\"invalid_request_error\",\"param\":null,\"code\":null}", - " at MistralClient._request (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@mistralai/mistralai/0.1.3/src/client.js:132:17)", - " at Object.runMicrotasks (ext:core/01_core.js:484:26)", - " at processTicksAndRejections (ext:deno_node/_next_tick.ts:53:10)", - " at runNextTicks (ext:deno_node/_next_tick.ts:71:3)", - " at eventLoopTick (ext:core/01_core.js:70:21)", - " at async MistralClient.chatStream (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@mistralai/mistralai/0.1.3/src/client.js:306:22)", - " at async ChatMistralAI._streamResponseChunks (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@langchain/mistralai/0.0.19/dist/chat_models.js:403:26)", - " at async ChatMistralAI._streamIterator (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@langchain/core/0.1.63/dist/language_models/chat_models.js:78:34)", - " at async ChatMistralAI.transform (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@langchain/core/0.1.63/dist/runnables/base.js:377:9)", - " at async RunnableBinding.transform (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@langchain/core/0.1.63/dist/runnables/base.js:733:9)" + "The weather in Paris is 28 °C.\n" ] } ], diff --git a/libs/langchain-mistralai/src/chat_models.ts b/libs/langchain-mistralai/src/chat_models.ts index 4c14e304a9dd..fe58f740676c 100644 --- a/libs/langchain-mistralai/src/chat_models.ts +++ b/libs/langchain-mistralai/src/chat_models.ts @@ -77,8 +77,8 @@ interface TokenUsage { export type MistralAIToolChoice = "auto" | "any" | "none"; type MistralAIToolInput = { type: string; function: MistralAIFunction }; -interface MistralAICallOptions - extends Omit { + +export interface ChatMistralAICallOptions extends Omit { response_format?: { type: "text" | "json_object"; }; @@ -91,8 +91,6 @@ interface MistralAICallOptions streamUsage?: boolean; } -export interface ChatMistralAICallOptions extends MistralAICallOptions {} - /** * Input to chat model class. */ @@ -406,7 +404,7 @@ function _convertStructuredToolToMistralTool( * Integration with a chat model. */ export class ChatMistralAI< - CallOptions extends MistralAICallOptions = MistralAICallOptions + CallOptions extends ChatMistralAICallOptions = ChatMistralAICallOptions > extends BaseChatModel implements ChatMistralAIInput