From cb40fbd3be3c114215871ce976f8a5fdcd2056c2 Mon Sep 17 00:00:00 2001 From: Bagatur Date: Wed, 30 Oct 2024 13:25:39 -0700 Subject: [PATCH] core[patch]: make Tool.description optional --- libs/core/langchain_core/tools/base.py | 2 +- libs/core/langchain_core/tools/structured.py | 10 ++++------ .../langchain_core/utils/function_calling.py | 18 ++++++++++++----- .../__snapshots__/test_runnable.ambr | 4 ++-- .../unit_tests/runnables/test_runnable.py | 1 + libs/core/tests/unit_tests/test_tools.py | 20 +++++++++++++------ 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index 4de0452020f..4b60727f260 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -348,7 +348,7 @@ class ChildTool(BaseTool): name: str """The unique name of the tool that clearly communicates its purpose.""" - description: str + description: Optional[str] = None """Used to tell the model how/when/why to use the tool. You can provide few-shot examples as a part of the description. diff --git a/libs/core/langchain_core/tools/structured.py b/libs/core/langchain_core/tools/structured.py index 174e7b2f537..35388d327f4 100644 --- a/libs/core/langchain_core/tools/structured.py +++ b/libs/core/langchain_core/tools/structured.py @@ -32,7 +32,7 @@ from langchain_core.utils.pydantic import TypeBaseModel class StructuredTool(BaseTool): """Tool that can operate on any number of inputs.""" - description: str = "" + description: Optional[str] = "" args_schema: Annotated[TypeBaseModel, SkipValidation()] = Field( ..., description="The tool schema." ) @@ -185,16 +185,14 @@ class StructuredTool(BaseTool): description_ = source_function.__doc__ or None if description_ is None and args_schema: description_ = args_schema.__doc__ or None - if description_ is None: - msg = "Function must have a docstring if description not provided." - raise ValueError(msg) - if description is None: + if description is None and description_ is not None: # Only apply if using the function's docstring description_ = textwrap.dedent(description_).strip() # Description example: # search_api(query: str) - Searches the API for the query. - description_ = f"{description_.strip()}" + if description_: + description_ = f"{description_.strip()}" return cls( name=name, func=func, diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 1a1c26443c7..e0e5a424831 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -20,7 +20,7 @@ from typing import ( ) from pydantic import BaseModel -from typing_extensions import TypedDict, get_args, get_origin, is_typeddict +from typing_extensions import NotRequired, TypedDict, get_args, get_origin, is_typeddict from langchain_core._api import deprecated from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, ToolMessage @@ -45,10 +45,16 @@ class FunctionDescription(TypedDict): name: str """The name of the function.""" - description: str + description: NotRequired[str] """A description of the function.""" - parameters: dict + parameters: NotRequired[dict] """The parameters of the function.""" + strict: NotRequired[Optional[bool]] + """Whether to enable strict schema adherence when generating the function call. + + If set to True, the model will follow the exact schema defined in the parameters + field. Only a subset of JSON Schema is supported when strict is True. + """ class ToolDescription(TypedDict): @@ -294,9 +300,8 @@ def format_tool_to_openai_function(tool: BaseTool) -> FunctionDescription: tool.tool_call_schema, name=tool.name, description=tool.description ) else: - return { + oai_function = { "name": tool.name, - "description": tool.description, "parameters": { # This is a hack to get around the fact that some tools # do not expose an args_schema, and expect an argument @@ -310,6 +315,9 @@ def format_tool_to_openai_function(tool: BaseTool) -> FunctionDescription: "type": "object", }, } + if tool.description: + oai_function["description"] = tool.description + return cast(FunctionDescription, oai_function) @deprecated( diff --git a/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr b/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr index c8312104b0d..63244248da9 100644 --- a/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr +++ b/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr @@ -1474,8 +1474,8 @@ # --- # name: test_prompt_with_llm.2 list([ - RunTree(id=UUID('00000000-0000-4000-8000-000000000000'), name='RunnableSequence', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='chain', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized=None, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your name?'}, outputs={'output': 'bar'}, reference_example_id=None, parent_run_id=None, tags=[], attachments={}, child_runs=[RunTree(id=UUID('00000000-0000-4000-8000-000000000001'), name='ChatPromptTemplate', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='prompt', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized={'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptTemplate'], 'kwargs': {'input_variables': ['question'], 'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'SystemMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': [], 'template': 'You are a nice assistant.', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'HumanMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': ['question'], 'template': '{question}', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}]}, 'name': 'ChatPromptTemplate'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your name?'}, outputs={'output': ChatPromptValue(messages=[SystemMessage(content='You are a nice assistant.', additional_kwargs={}, response_metadata={}), HumanMessage(content='What is your name?', additional_kwargs={}, response_metadata={})])}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000000'), tags=['seq:step:1'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000.20230101T000000000000Z00000000-0000-4000-8000-000000000001', trace_id=UUID('00000000-0000-4000-8000-000000000000')), RunTree(id=UUID('00000000-0000-4000-8000-000000000002'), name='FakeListLLM', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='llm', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={'invocation_params': {'responses': ['foo', 'bar'], '_type': 'fake-list', 'stop': None}, 'options': {'stop': None}, 'batch_size': 2, 'metadata': {'ls_provider': 'fakelist', 'ls_model_type': 'llm'}}, error=None, serialized={'lc': 1, 'type': 'not_implemented', 'id': ['langchain_core', 'language_models', 'fake', 'FakeListLLM'], 'repr': "FakeListLLM(responses=['foo', 'bar'])", 'name': 'FakeListLLM'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'prompts': ['System: You are a nice assistant.\nHuman: What is your name?']}, outputs={'generations': [[{'text': 'bar', 'generation_info': None, 'type': 'Generation'}]], 'llm_output': None, 'run': None, 'type': 'LLMResult'}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000000'), tags=['seq:step:2'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000.20230101T000000000000Z00000000-0000-4000-8000-000000000002', trace_id=UUID('00000000-0000-4000-8000-000000000000'))], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000', trace_id=UUID('00000000-0000-4000-8000-000000000000')), - RunTree(id=UUID('00000000-0000-4000-8000-000000000003'), name='RunnableSequence', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='chain', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized=None, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your favorite color?'}, outputs={'output': 'foo'}, reference_example_id=None, parent_run_id=None, tags=[], attachments={}, child_runs=[RunTree(id=UUID('00000000-0000-4000-8000-000000000004'), name='ChatPromptTemplate', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='prompt', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized={'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptTemplate'], 'kwargs': {'input_variables': ['question'], 'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'SystemMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': [], 'template': 'You are a nice assistant.', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'HumanMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': ['question'], 'template': '{question}', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}]}, 'name': 'ChatPromptTemplate'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your favorite color?'}, outputs={'output': ChatPromptValue(messages=[SystemMessage(content='You are a nice assistant.', additional_kwargs={}, response_metadata={}), HumanMessage(content='What is your favorite color?', additional_kwargs={}, response_metadata={})])}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000003'), tags=['seq:step:1'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003.20230101T000000000000Z00000000-0000-4000-8000-000000000004', trace_id=UUID('00000000-0000-4000-8000-000000000003')), RunTree(id=UUID('00000000-0000-4000-8000-000000000005'), name='FakeListLLM', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='llm', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={'invocation_params': {'responses': ['foo', 'bar'], '_type': 'fake-list', 'stop': None}, 'options': {'stop': None}, 'batch_size': 2, 'metadata': {'ls_provider': 'fakelist', 'ls_model_type': 'llm'}}, error=None, serialized={'lc': 1, 'type': 'not_implemented', 'id': ['langchain_core', 'language_models', 'fake', 'FakeListLLM'], 'repr': "FakeListLLM(responses=['foo', 'bar'])", 'name': 'FakeListLLM'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'prompts': ['System: You are a nice assistant.\nHuman: What is your favorite color?']}, outputs={'generations': [[{'text': 'foo', 'generation_info': None, 'type': 'Generation'}]], 'llm_output': None, 'run': None, 'type': 'LLMResult'}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000003'), tags=['seq:step:2'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003.20230101T000000000000Z00000000-0000-4000-8000-000000000005', trace_id=UUID('00000000-0000-4000-8000-000000000003'))], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003', trace_id=UUID('00000000-0000-4000-8000-000000000003')), + RunTree(id=UUID('00000000-0000-4000-8000-000000000000'), name='RunnableSequence', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='chain', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized=None, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your favorite color?'}, outputs={'output': 'foo'}, reference_example_id=None, parent_run_id=None, tags=[], attachments={}, child_runs=[RunTree(id=UUID('00000000-0000-4000-8000-000000000001'), name='ChatPromptTemplate', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='prompt', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized={'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptTemplate'], 'kwargs': {'input_variables': ['question'], 'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'SystemMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': [], 'template': 'You are a nice assistant.', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'HumanMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': ['question'], 'template': '{question}', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}]}, 'name': 'ChatPromptTemplate'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your favorite color?'}, outputs={'output': ChatPromptValue(messages=[SystemMessage(content='You are a nice assistant.', additional_kwargs={}, response_metadata={}), HumanMessage(content='What is your favorite color?', additional_kwargs={}, response_metadata={})])}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000000'), tags=['seq:step:1'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000.20230101T000000000000Z00000000-0000-4000-8000-000000000001', trace_id=UUID('00000000-0000-4000-8000-000000000000')), RunTree(id=UUID('00000000-0000-4000-8000-000000000002'), name='FakeListLLM', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='llm', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={'invocation_params': {'responses': ['foo', 'bar'], '_type': 'fake-list', 'stop': None}, 'options': {'stop': None}, 'batch_size': 2, 'metadata': {'ls_provider': 'fakelist', 'ls_model_type': 'llm'}}, error=None, serialized={'lc': 1, 'type': 'not_implemented', 'id': ['langchain_core', 'language_models', 'fake', 'FakeListLLM'], 'repr': "FakeListLLM(responses=['foo', 'bar'])", 'name': 'FakeListLLM'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'prompts': ['System: You are a nice assistant.\nHuman: What is your favorite color?']}, outputs={'generations': [[{'text': 'foo', 'generation_info': None, 'type': 'Generation'}]], 'llm_output': None, 'run': None, 'type': 'LLMResult'}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000000'), tags=['seq:step:2'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000.20230101T000000000000Z00000000-0000-4000-8000-000000000002', trace_id=UUID('00000000-0000-4000-8000-000000000000'))], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000000', trace_id=UUID('00000000-0000-4000-8000-000000000000')), + RunTree(id=UUID('00000000-0000-4000-8000-000000000003'), name='RunnableSequence', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='chain', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized=None, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your name?'}, outputs={'output': 'bar'}, reference_example_id=None, parent_run_id=None, tags=[], attachments={}, child_runs=[RunTree(id=UUID('00000000-0000-4000-8000-000000000004'), name='ChatPromptTemplate', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='prompt', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={}, error=None, serialized={'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'ChatPromptTemplate'], 'kwargs': {'input_variables': ['question'], 'messages': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'SystemMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': [], 'template': 'You are a nice assistant.', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}, {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'chat', 'HumanMessagePromptTemplate'], 'kwargs': {'prompt': {'lc': 1, 'type': 'constructor', 'id': ['langchain', 'prompts', 'prompt', 'PromptTemplate'], 'kwargs': {'input_variables': ['question'], 'template': '{question}', 'template_format': 'f-string'}, 'name': 'PromptTemplate'}}}]}, 'name': 'ChatPromptTemplate'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'question': 'What is your name?'}, outputs={'output': ChatPromptValue(messages=[SystemMessage(content='You are a nice assistant.', additional_kwargs={}, response_metadata={}), HumanMessage(content='What is your name?', additional_kwargs={}, response_metadata={})])}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000003'), tags=['seq:step:1'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003.20230101T000000000000Z00000000-0000-4000-8000-000000000004', trace_id=UUID('00000000-0000-4000-8000-000000000003')), RunTree(id=UUID('00000000-0000-4000-8000-000000000005'), name='FakeListLLM', start_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), run_type='llm', end_time=FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), extra={'invocation_params': {'responses': ['foo', 'bar'], '_type': 'fake-list', 'stop': None}, 'options': {'stop': None}, 'batch_size': 2, 'metadata': {'ls_provider': 'fakelist', 'ls_model_type': 'llm'}}, error=None, serialized={'lc': 1, 'type': 'not_implemented', 'id': ['langchain_core', 'language_models', 'fake', 'FakeListLLM'], 'repr': "FakeListLLM(responses=['foo', 'bar'])", 'name': 'FakeListLLM'}, events=[{'name': 'start', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}, {'name': 'end', 'time': FakeDatetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)}], inputs={'prompts': ['System: You are a nice assistant.\nHuman: What is your name?']}, outputs={'generations': [[{'text': 'bar', 'generation_info': None, 'type': 'Generation'}]], 'llm_output': None, 'run': None, 'type': 'LLMResult'}, reference_example_id=None, parent_run_id=UUID('00000000-0000-4000-8000-000000000003'), tags=['seq:step:2'], attachments={}, child_runs=[], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003.20230101T000000000000Z00000000-0000-4000-8000-000000000005', trace_id=UUID('00000000-0000-4000-8000-000000000003'))], session_name='default', session_id=None, dotted_order='20230101T000000000000Z00000000-0000-4000-8000-000000000003', trace_id=UUID('00000000-0000-4000-8000-000000000003')), ]) # --- # name: test_prompt_with_llm_and_async_lambda diff --git a/libs/core/tests/unit_tests/runnables/test_runnable.py b/libs/core/tests/unit_tests/runnables/test_runnable.py index 7b03b53c212..d2b2083c7f5 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable.py @@ -4616,6 +4616,7 @@ async def test_tool_from_runnable() -> None: assert await chain_tool.arun({"question": "What up"}) == await chain.ainvoke( {"question": "What up"} ) + assert chain_tool.description assert chain_tool.description.endswith(repr(chain)) assert _schema(chain_tool.args_schema) == chain.get_input_jsonschema() assert _schema(chain_tool.args_schema) == { diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index 065e36c8668..785c82c5f7d 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -651,13 +651,21 @@ def test_tool_with_kwargs() -> None: def test_missing_docstring() -> None: - """Test error is raised when docstring is missing.""" - # expect to throw a value error if there's no docstring - with pytest.raises(ValueError, match="Function must have a docstring"): + """Test error is not raised when docstring is missing.""" - @tool - def search_api(query: str) -> str: - return "API result" + @tool + def search_api(query: str) -> str: + return "API result" + + assert search_api.name == "search_api" + assert search_api.description is None + assert search_api.args_schema + assert search_api.args_schema.model_json_schema() == { + "properties": {"query": {"title": "Query", "type": "string"}}, + "required": ["query"], + "title": "search_api", + "type": "object", + } def test_create_tool_positional_args() -> None: