Skip to content

Commit

Permalink
docs: Add OpenAIAssistantV2Runnable docstrings (#27402)
Browse files Browse the repository at this point in the history
- **Description:** add/improve docstrings of OpenAIAssistantV2Runnable
- **Issue:** the issue #21983

Co-authored-by: Chester Curme <[email protected]>
  • Loading branch information
hmnfalahi and ccurme authored Oct 30, 2024
1 parent 7a29ca6 commit 98bb3a0
Showing 1 changed file with 112 additions and 46 deletions.
158 changes: 112 additions & 46 deletions libs/community/langchain_community/agents/openai_assistant/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@


def _get_openai_client() -> openai.OpenAI:
"""Get the OpenAI client.
Returns:
openai.OpenAI: OpenAI client
Raises:
ImportError: If `openai` is not installed.
AttributeError: If the installed `openai` version is not compatible.
"""
try:
import openai

Expand All @@ -44,6 +53,15 @@ def _get_openai_client() -> openai.OpenAI:


def _get_openai_async_client() -> openai.AsyncOpenAI:
"""Get the async OpenAI client.
Returns:
openai.AsyncOpenAI: Async OpenAI client
Raises:
ImportError: If `openai` is not installed.
AttributeError: If the installed `openai` version is not compatible.
"""
try:
import openai

Expand All @@ -60,14 +78,14 @@ def _get_openai_async_client() -> openai.AsyncOpenAI:


def _convert_file_ids_into_attachments(file_ids: list) -> list:
"""
Convert file_ids into attachments
"""Convert file_ids into attachments
File search and Code interpreter will be turned on by default.
Args:
file_ids (list): List of file_ids that need to be converted into attachments.
Returns:
A list of attachments that are converted from file_ids.
list: List of attachments converted from file_ids.
"""
attachments = []
for id in file_ids:
Expand All @@ -83,14 +101,15 @@ def _convert_file_ids_into_attachments(file_ids: list) -> list:
def _is_assistants_builtin_tool(
tool: Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool],
) -> bool:
"""
Determine if tool corresponds to OpenAI Assistants built-in.
"""Determine if tool corresponds to OpenAI Assistants built-in.
Args:
tool : Tool that needs to be determined
tool (Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]):
Tool that needs to be determined.
Returns:
A boolean response of true or false indicating if the tool corresponds to
OpenAI Assistants built-in.
OpenAI Assistants built-in.
"""
assistants_builtin_tools = ("code_interpreter", "retrieval", "file_search")
return (
Expand All @@ -109,10 +128,11 @@ def _get_assistants_tool(
such as "code_interpreter" and "retrieval."
Args:
tool: Tools or functions that need to be converted to OpenAI tools.
Returns:
A dictionary of tools that are converted into OpenAI tools.
tool (Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]):
Tools or functions that need to be converted to OpenAI tools.
Returns:
Dict[str, Any]: A dictionary of tools that are converted into OpenAI tools.
"""
if _is_assistants_builtin_tool(tool):
return tool # type: ignore
Expand All @@ -124,18 +144,25 @@ def _get_assistants_tool(
class OpenAIAssistantV2Runnable(OpenAIAssistantRunnable):
"""Run an OpenAI Assistant.
Attributes:
client (Any): OpenAI or AzureOpenAI client.
async_client (Any): Async OpenAI or AzureOpenAI client.
assistant_id (str): OpenAI assistant ID.
check_every_ms (float): Frequency to check progress in milliseconds.
as_agent (bool): Whether to use the assistant as a LangChain agent.
Example using OpenAI tools:
.. code-block:: python
from langchain.agents.openai_assistant import OpenAIAssistantV2Runnable
interpreter_assistant = OpenAIAssistantV2Runnable.create_assistant(
name="langchain assistant",
assistant = OpenAIAssistantV2Runnable.create_assistant(
name="math assistant",
instructions="You are a personal math tutor. Write and run code to answer math questions.",
tools=[{"type": "code_interpreter"}],
model="gpt-4-1106-preview"
)
output = interpreter_assistant.invoke({"content": "What's 10 - 4 raised to the 2.7"})
output = assistant.invoke({"content": "What's 10 - 4 raised to the 2.7"})
Example using custom tools and AgentExecutor:
.. code-block:: python
Expand All @@ -155,8 +182,7 @@ class OpenAIAssistantV2Runnable(OpenAIAssistantRunnable):
)
agent_executor = AgentExecutor(agent=agent, tools=tools)
agent_executor.invoke({"content": "What's 10 - 4 raised to the 2.7"})
agent_executor.invoke({"content": "Analyze the data..."})
Example using custom tools and custom execution:
.. code-block:: python
Expand Down Expand Up @@ -206,12 +232,13 @@ def execute_agent(agent, tools, input):
assistant_id: str
"""OpenAI assistant id."""
check_every_ms: float = 1_000.0
"""Frequency with which to check run progress in ms."""
"""Frequency with which to check run progress in milliseconds."""
as_agent: bool = False
"""Use as a LangChain agent, compatible with the AgentExecutor."""

@model_validator(mode="after")
def validate_async_client(self) -> Self:
"""Validate that the async client is set, otherwise initialize it."""
if self.async_client is None:
import openai

Expand All @@ -236,21 +263,23 @@ def create_assistant(
"""Create an OpenAI Assistant and instantiate the Runnable.
Args:
name: Assistant name.
instructions: Assistant instructions.
tools: Assistant tools. Can be passed in OpenAI format or as BaseTools.
tool_resources: Assistant tool resources. Can be passed in OpenAI format
model: Assistant model to use.
client: OpenAI or AzureOpenAI client.
Will create default OpenAI client (Assistant v2) if not specified.
name (str): Assistant name.
instructions (str): Assistant instructions.
tools (Sequence[Union[BaseTool, dict]]): Assistant tools. Can be passed
in OpenAI format or as BaseTools.
tool_resources (Optional[Union[AssistantToolResources, dict, NotGiven]]):
Assistant tool resources. Can be passed in OpenAI format.
model (str): Assistant model to use.
client (Optional[Union[openai.OpenAI, openai.AzureOpenAI]]): OpenAI or
AzureOpenAI client. Will create default OpenAI client (Assistant v2)
if not specified.
model_kwargs: Additional model arguments. Only available for temperature
and top_p parameters.
and top_p parameters.
extra_body: Additional body parameters to be passed to the assistant.
Returns:
OpenAIAssistantRunnable configured to run using the created assistant.
OpenAIAssistantRunnable: The configured assistant runnable.
"""

client = client or _get_openai_client()
if tool_resources is None:
from openai._types import NOT_GIVEN
Expand All @@ -270,10 +299,10 @@ def create_assistant(
def invoke(
self, input: dict, config: Optional[RunnableConfig] = None, **kwargs: Any
) -> OutputType:
"""Invoke assistant.
"""Invoke the assistant.
Args:
input: Runnable input dict that can have:
input (dict): Runnable input dict that can have:
content: User message when starting a new run.
thread_id: Existing thread to use.
run_id: Existing run to use. Should only be supplied when providing
Expand All @@ -289,18 +318,17 @@ def invoke(
tools: Override Assistant tools for this run.
tool_resources: Override Assistant tool resources for this run (v2 API).
run_metadata: Metadata to associate with new run.
config: Runnable config:
config (Optional[RunnableConfig]): Configuration for the run.
Return:
If self.as_agent, will return
Returns:
OutputType: If self.as_agent, will return
Union[List[OpenAIAssistantAction], OpenAIAssistantFinish]. Otherwise,
will return OpenAI types
Union[List[ThreadMessage], List[RequiredActionFunctionToolCall]].
Raises:
BaseException: If an error occurs during the invocation.
"""

config = ensure_config(config)
callback_manager = CallbackManager.configure(
inheritable_callbacks=config.get("callbacks"),
Expand Down Expand Up @@ -379,16 +407,18 @@ async def acreate_assistant(
"""Create an AsyncOpenAI Assistant and instantiate the Runnable.
Args:
name: Assistant name.
instructions: Assistant instructions.
tools: Assistant tools. Can be passed in OpenAI format or as BaseTools.
tool_resources: Assistant tool resources. Can be passed in OpenAI format
model: Assistant model to use.
async_client: AsyncOpenAI client.
Will create default async_client if not specified.
name (str): Assistant name.
instructions (str): Assistant instructions.
tools (Sequence[Union[BaseTool, dict]]): Assistant tools. Can be passed
in OpenAI format or as BaseTools.
tool_resources (Optional[Union[AssistantToolResources, dict, NotGiven]]):
Assistant tool resources. Can be passed in OpenAI format.
model (str): Assistant model to use.
async_client (Optional[Union[openai.OpenAI, openai.AzureOpenAI]]): OpenAI or
AzureOpenAI async client. Will create default async_client if not specified.
Returns:
AsyncOpenAIAssistantRunnable configured to run using the created assistant.
AsyncOpenAIAssistantRunnable: The configured assistant runnable.
"""
async_client = async_client or _get_openai_async_client()
if tool_resources is None:
Expand All @@ -412,7 +442,7 @@ async def ainvoke(
"""Async invoke assistant.
Args:
input: Runnable input dict that can have:
input (dict): Runnable input dict that can have:
content: User message when starting a new run.
thread_id: Existing thread to use.
run_id: Existing run to use. Should only be supplied when providing
Expand All @@ -428,15 +458,17 @@ async def ainvoke(
tools: Override Assistant tools for this run.
tool_resources: Override Assistant tool resources for this run (v2 API).
run_metadata: Metadata to associate with new run.
config: Runnable config:
config (Optional[RunnableConfig]): Configuration for the run.
Return:
If self.as_agent, will return
Returns:
OutputType: If self.as_agent, will return
Union[List[OpenAIAssistantAction], OpenAIAssistantFinish]. Otherwise,
will return OpenAI types
Union[List[ThreadMessage], List[RequiredActionFunctionToolCall]].
"""
Raises:
BaseException: If an error occurs during the invocation.
"""
config = config or {}
callback_manager = CallbackManager.configure(
inheritable_callbacks=config.get("callbacks"),
Expand Down Expand Up @@ -503,6 +535,14 @@ async def ainvoke(
return response

def _create_run(self, input: dict) -> Any:
"""Create a new run within an existing thread.
Args:
input (dict): The input data for the new run.
Returns:
Any: The created run object.
"""
params = {
k: v
for k, v in input.items()
Expand All @@ -515,6 +555,15 @@ def _create_run(self, input: dict) -> Any:
)

def _create_thread_and_run(self, input: dict, thread: dict) -> Any:
"""Create a new thread and run.
Args:
input (dict): The input data for the run.
thread (dict): The thread data to create.
Returns:
Any: The created thread and run.
"""
params = {
k: v
for k, v in input.items()
Expand All @@ -530,10 +579,18 @@ def _create_thread_and_run(self, input: dict, thread: dict) -> Any:
return run

async def _acreate_run(self, input: dict) -> Any:
"""Asynchronously create a new run within an existing thread.
Args:
input (dict): The input data for the new run.
Returns:
Any: The created run object.
"""
params = {
k: v
for k, v in input.items()
if k in ("instructions", "model", "tools", "tool_resources" "run_metadata")
if k in ("instructions", "model", "tools", "tool_resources", "run_metadata")
}
return await self.async_client.beta.threads.runs.create(
input["thread_id"],
Expand All @@ -542,6 +599,15 @@ async def _acreate_run(self, input: dict) -> Any:
)

async def _acreate_thread_and_run(self, input: dict, thread: dict) -> Any:
"""Asynchronously create a new thread and run simultaneously.
Args:
input (dict): The input data for the run.
thread (dict): The thread data to create.
Returns:
Any: The created thread and run.
"""
params = {
k: v
for k, v in input.items()
Expand Down

0 comments on commit 98bb3a0

Please sign in to comment.