Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added an IMDb toolkit #14105

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fe6e99f
added IMDb base tool and movie search tool
jesseyao89 Nov 17, 2023
aa0d1be
Merge pull request #1 from Pyrunix/imdb-base-tool
Pyrunix Nov 17, 2023
734b669
Implemented plot and cast of movie. Did basic manual testing.
STalukder20 Nov 21, 2023
5e8a976
add search_keyword function
ryanWang2018 Nov 26, 2023
5174be0
Linting/formatting changes
STalukder20 Nov 28, 2023
69dac12
Added more IMDb tools
jesseyao89 Nov 28, 2023
c40aae9
Merge pull request #2 from Pyrunix/STalukder-CastPlot
jesseyao89 Nov 28, 2023
ed77afe
Merge branch 'master' into more-tools
jesseyao89 Nov 28, 2023
12610aa
add search_keyword function
ryanWang2018 Nov 28, 2023
7ce38bb
Fixed formatting and linting
jesseyao89 Nov 28, 2023
748fbe0
Updated __init__.py of imdb tools and base tools module, added commen…
jesseyao89 Nov 28, 2023
4d223f7
Linting changes, and try/catch for movie name instead of ID error.
STalukder20 Nov 28, 2023
1342f71
Merge pull request #3 from Pyrunix/STalukder-CastPlot
jesseyao89 Nov 28, 2023
37f5ebd
Merge branch 'master' into more-tools
jesseyao89 Nov 28, 2023
de9dd8e
fixed formatting
jesseyao89 Nov 28, 2023
5c4fd96
Merge pull request #4 from Pyrunix/more-tools
STalukder20 Nov 28, 2023
c28ceed
add find movie by keyword
ryanWang2018 Nov 29, 2023
1b5f44c
add file for imdbtoolkit
ryanWang2018 Nov 29, 2023
9c6b45d
merge changes from master and fix conflict
ryanWang2018 Nov 29, 2023
5a5fff4
implement toolkit for imdb
ryanWang2018 Nov 29, 2023
f393b4c
Merge pull request #5 from Pyrunix/imdb_feature
ryanWang2018 Nov 29, 2023
055c39f
toolkit cleanup
jesseyao89 Nov 30, 2023
dde91e7
added imdb.ipynb
Pyrunix Nov 30, 2023
e66fa6d
Made some changes to IMDb example notebook
jesseyao89 Nov 30, 2023
0532e64
Merge pull request #6 from Pyrunix/doc-notebook
jesseyao89 Nov 30, 2023
03d365a
Made IMDb capitalization consistent
jesseyao89 Dec 1, 2023
54459fc
Added IMDb tools to unit tests
jesseyao89 Dec 1, 2023
9e6bcbc
Added cinemagoer as poetry dependency
jesseyao89 Dec 1, 2023
d61ca1a
Ran linting and formatting
jesseyao89 Dec 1, 2023
1cf708e
Merge pull request #7 from Pyrunix/cleanup
jesseyao89 Dec 1, 2023
6200775
Merge remote-tracking branch 'upstream/master'
jesseyao89 Dec 1, 2023
a81696d
Cleanup after merge
jesseyao89 Dec 1, 2023
1806d6b
Fixed linting error
jesseyao89 Dec 1, 2023
6ae55fe
Merge remote-tracking branch 'upstream/master'
jesseyao89 Dec 4, 2023
a27dc82
Merge remote-tracking branch 'upstream/master'
STalukder20 Dec 4, 2023
21e58ca
Merge remote-tracking branch 'upstream/master'
STalukder20 Dec 5, 2023
b310591
Merge remote-tracking branch 'upstream/master'
STalukder20 Dec 6, 2023
60a37aa
Poetry lock update
STalukder20 Dec 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions docs/docs/integrations/toolkits/imdb.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# IMDb\n",
"\n",
"This toolkit connects Langchain to IMDb using the Cinemagoer API.\n",
"\n",
"This tool requires the Cinemagoer package, which can be installed as follows:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"!pip install git+https://github.com/cinemagoer/cinemagoer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An agent can now be created like so:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import AgentType, initialize_agent\n",
"from langchain.agents.agent_toolkits import IMDbToolkit\n",
"from langchain.chat_models import ChatOpenAI\n",
"\n",
"toolkit = IMDbToolkit()\n",
"llm = ChatOpenAI(temperature=0, openai_api_key=\"your openai api key here\")\n",
"tools = toolkit.get_tools()\n",
"agent = initialize_agent(\n",
" tools=tools,\n",
" llm=llm,\n",
" verbose=True,\n",
" agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3mI need to find the movie ID for Oppenheimer first.\n",
"Action: imdb_search_movie\n",
"Action Input: Oppenheimer\u001b[0m\n",
"Observation: \u001b[33;1m\u001b[1;3m[{\"title\": \"Oppenheimer (2023)\", \"id\": \"15398776\"}, {\"title\": \"\\\"Oppenheimer\\\" (1980) (mini)\", \"id\": \"0078037\"}, {\"title\": \"Oppenheimer: The Real Story (2023)\", \"id\": \"27192512\"}, {\"title\": \"Oppenheimer (2023)\", \"id\": \"29466107\"}, {\"title\": \"To End All War: Oppenheimer & the Atomic Bomb (2023)\", \"id\": \"28240284\"}, {\"title\": \"Oppenheimer After Trinity (2023)\", \"id\": \"28017314\"}, {\"title\": \"The Trials of J. Robert Oppenheimer (2008)\", \"id\": \"1559008\"}, {\"title\": \"The Real Oppenheimer (2023)\", \"id\": \"28655290\"}, {\"title\": \"\\\"Oppenheimer presenta\\\" (2003)\", \"id\": \"0400005\"}, {\"title\": \"Oppenheimer Barbie (2023)\", \"id\": \"28454751\"}, {\"title\": \"Oppenheimer (2014)\", \"id\": \"3695394\"}, {\"title\": \"Inside Christopher Nolan's Oppenheimer (2023)\", \"id\": \"28522133\"}, {\"title\": \"Norman (2016)\", \"id\": \"4191702\"}, {\"title\": \"RadioActive Soldiers - The Oppenheimer Aftermath (2023)\", \"id\": \"29080313\"}, {\"title\": \"The LEGO Oppenheimer Movie (None)\", \"id\": \"28249545\"}, {\"title\": \"In der Sache J. Robert Oppenheimer (1964) (TV)\", \"id\": \"0058228\"}, {\"title\": \"The Case of Oppenheimer (1967) (TV)\", \"id\": \"0443178\"}, {\"title\": \"The Ballad of Oppenheimer Park (2016)\", \"id\": \"5136682\"}, {\"title\": \"Oppenheimer (2011)\", \"id\": \"2241393\"}, {\"title\": \"The Rags of Time: J. Robert Oppenheimer (2020)\", \"id\": \"13046592\"}]\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3mThe movie ID for Oppenheimer is 15398776.\n",
"Action: imdb_get_movie_crew\n",
"Action Input: 15398776\u001b[0m\n",
"Observation: \u001b[33;1m\u001b[1;3m{\"director\": [{\"name\": \"Christopher Nolan\", \"id\": \"0634240\"}], \"writer\": [{\"name\": \"Christopher Nolan\", \"id\": \"0634240\"}, {\"name\": \"Kai Bird\", \"id\": \"3284831\"}, {\"name\": \"Martin Sherwin\", \"id\": \"2452558\"}], \"producer\": [{\"name\": \"Thomas Hayslip\", \"id\": \"0371669\"}, {\"name\": \"Helen Medrano\", \"id\": \"0749781\"}, {\"name\": \"Christopher Nolan\", \"id\": \"0634240\"}, {\"name\": \"Charles Roven\", \"id\": \"0746273\"}, {\"name\": \"Emma Thomas\", \"id\": \"0858799\"}, {\"name\": \"Andy Thompson\", \"id\": \"3379670\"}, {\"name\": \"J. David Wargo\", \"id\": \"11356994\"}, {\"name\": \"James Woods\", \"id\": \"0000249\"}], \"cinematographer\": [{\"name\": \"Hoyte Van Hoytema\", \"id\": \"0887227\"}], \"editor\": [{\"name\": \"Jennifer Lame\", \"id\": \"2352780\"}], \"composer\": [{\"name\": \"Ludwig G\\u00f6ransson\", \"id\": \"3234869\"}]}\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3mThe movie crew for Oppenheimer includes:\n",
"- Director: Christopher Nolan\n",
"- Writers: Christopher Nolan, Kai Bird, Martin Sherwin\n",
"- Producers: Thomas Hayslip, Helen Medrano, Christopher Nolan, Charles Roven, Emma Thomas, Andy Thompson, J. David Wargo, James Woods\n",
"- Cinematographer: Hoyte Van Hoytema\n",
"- Editor: Jennifer Lame\n",
"- Composer: Ludwig Göransson\n",
"\n",
"Final Answer: The movie crew for Oppenheimer includes Christopher Nolan as the director, Christopher Nolan, Kai Bird, and Martin Sherwin as the writers, Thomas Hayslip, Helen Medrano, Christopher Nolan, Charles Roven, Emma Thomas, Andy Thompson, J. David Wargo, and James Woods as the producers, Hoyte Van Hoytema as the cinematographer, Jennifer Lame as the editor, and Ludwig Göransson as the composer.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'The movie crew for Oppenheimer includes Christopher Nolan as the director, Christopher Nolan, Kai Bird, and Martin Sherwin as the writers, Thomas Hayslip, Helen Medrano, Christopher Nolan, Charles Roven, Emma Thomas, Andy Thompson, J. David Wargo, and James Woods as the producers, Hoyte Van Hoytema as the cinematographer, Jennifer Lame as the editor, and Ludwig Göransson as the composer.'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent.run(\"Who was the movie crew for Oppenheimer?\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
2 changes: 2 additions & 0 deletions libs/langchain/langchain/agents/agent_toolkits/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
FileManagementToolkit,
)
from langchain.agents.agent_toolkits.gmail.toolkit import GmailToolkit
from langchain.agents.agent_toolkits.imdb.toolkit import IMDbToolkit
from langchain.agents.agent_toolkits.jira.toolkit import JiraToolkit
from langchain.agents.agent_toolkits.json.base import create_json_agent
from langchain.agents.agent_toolkits.json.toolkit import JsonToolkit
Expand Down Expand Up @@ -88,6 +89,7 @@ def __getattr__(name: str) -> Any:
"AzureCognitiveServicesToolkit",
"FileManagementToolkit",
"GmailToolkit",
"IMDbToolkit",
"JiraToolkit",
"JsonToolkit",
"MultionToolkit",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""IMDb toolkit."""
33 changes: 33 additions & 0 deletions libs/langchain/langchain/agents/agent_toolkits/imdb/toolkit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import List

from langchain.agents.agent_toolkits.base import BaseToolkit
from langchain.tools import BaseTool
from langchain.tools.imdb.cast_of_movie import IMDbCastOfMovie
from langchain.tools.imdb.get_movie_crew import IMDbGetMovieCrew
from langchain.tools.imdb.get_movie_info import IMDbGetMovieInfo
from langchain.tools.imdb.get_person_bio import IMDbGetPersonBio
from langchain.tools.imdb.get_person_movies import IMDbGetPersonMovies
from langchain.tools.imdb.plot_of_movie import IMDbPlotOfMovie
from langchain.tools.imdb.popular_movies import IMDbPopularMovies
from langchain.tools.imdb.search_keyword import IMDbSearchMovieKeyword
from langchain.tools.imdb.search_movie import IMDbSearchMovie
from langchain.tools.imdb.search_person import IMDbSearchPerson


class IMDbToolkit(BaseToolkit):
"""Toolkit for interacting with IMDB."""

def get_tools(self) -> List[BaseTool]:
"""Get the tools in the toolkit."""
return [
IMDbCastOfMovie(),
IMDbGetMovieCrew(),
IMDbGetMovieInfo(),
IMDbGetPersonBio(),
IMDbGetPersonMovies(),
IMDbPopularMovies(),
IMDbPlotOfMovie(),
IMDbSearchMovie(),
IMDbSearchPerson(),
IMDbSearchMovieKeyword(),
]
90 changes: 90 additions & 0 deletions libs/langchain/langchain/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,66 @@ def _import_ifttt() -> Any:
return IFTTTWebhook


def _import_imdb_CastOfMovieTool() -> Any:
from langchain.tools.imdb.cast_of_movie import IMDbCastOfMovie

return IMDbCastOfMovie


def _import_imdb_GetMovieCrewTool() -> Any:
from langchain.tools.imdb.get_movie_crew import IMDbGetMovieCrew

return IMDbGetMovieCrew


def _import_imdb_GetMovieInfoTool() -> Any:
from langchain.tools.imdb.get_movie_info import IMDbGetMovieInfo

return IMDbGetMovieInfo


def _import_imdb_GetPersonBioTool() -> Any:
from langchain.tools.imdb.get_person_bio import IMDbGetPersonBio

return IMDbGetPersonBio


def _import_imdb_GetPersonMoviesTool() -> Any:
from langchain.tools.imdb.get_person_movies import IMDbGetPersonMovies

return IMDbGetPersonMovies


def _import_imdb_PlotOfMovieTool() -> Any:
from langchain.tools.imdb.plot_of_movie import IMDbPlotOfMovie

return IMDbPlotOfMovie


def _import_imdb_PopularMoviesTool() -> Any:
from langchain.tools.imdb.popular_movies import IMDbPopularMovies

return IMDbPopularMovies


def _import_imdb_SearchMovieTool() -> Any:
from langchain.tools.imdb.search_movie import IMDbSearchMovie

return IMDbSearchMovie


def _import_imdb_SearchMovieKeywordTool() -> Any:
from langchain.tools.imdb.search_keyword import IMDbSearchMovieKeyword

return IMDbSearchMovieKeyword


def _import_imdb_SearchPersonTool() -> Any:
from langchain.tools.imdb.search_person import IMDbSearchPerson

return IMDbSearchPerson


def _import_interaction_tool() -> Any:
from langchain.tools.interaction.tool import StdInInquireTool

Expand Down Expand Up @@ -789,6 +849,26 @@ def __getattr__(name: str) -> Any:
return _import_human_tool()
elif name == "IFTTTWebhook":
return _import_ifttt()
elif name == "IMDbCastOfMovie":
return _import_imdb_CastOfMovieTool()
elif name == "IMDbGetMovieCrew":
return _import_imdb_GetMovieCrewTool()
elif name == "IMDbGetMovieInfo":
return _import_imdb_GetMovieInfoTool()
elif name == "IMDbGetPersonBio":
return _import_imdb_GetPersonBioTool()
elif name == "IMDbGetPersonMovies":
return _import_imdb_GetPersonMoviesTool()
elif name == "IMDbPopularMovies":
return _import_imdb_PopularMoviesTool()
elif name == "IMDbPlotOfMovie":
return _import_imdb_PlotOfMovieTool()
elif name == "IMDbSearchMovie":
return _import_imdb_SearchMovieTool()
elif name == "IMDbSearchMovieKeyword":
return _import_imdb_SearchMovieKeywordTool()
elif name == "IMDbSearchPerson":
return _import_imdb_SearchPersonTool()
elif name == "StdInInquireTool":
return _import_interaction_tool()
elif name == "JiraAction":
Expand Down Expand Up @@ -977,6 +1057,16 @@ def __getattr__(name: str) -> Any:
"GoogleSerperRun",
"HumanInputRun",
"IFTTTWebhook",
"IMDbCastOfMovie",
"IMDbGetMovieCrew",
"IMDbGetMovieInfo",
"IMDbGetPersonBio",
"IMDbGetPersonMovies",
"IMDbPopularMovies",
"IMDbPlotOfMovie",
"IMDbSearchMovie",
"IMDbSearchPerson",
"IMDbSearchMovieKeyword",
"InfoPowerBITool",
"InfoSQLDatabaseTool",
"InfoSparkSQLTool",
Expand Down
25 changes: 25 additions & 0 deletions libs/langchain/langchain/tools/imdb/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Tools for querying IMDb (the Internet Movie Database)."""

from langchain.tools.imdb.cast_of_movie import IMDbCastOfMovie
from langchain.tools.imdb.get_movie_crew import IMDbGetMovieCrew
from langchain.tools.imdb.get_movie_info import IMDbGetMovieInfo
from langchain.tools.imdb.get_person_bio import IMDbGetPersonBio
from langchain.tools.imdb.get_person_movies import IMDbGetPersonMovies
from langchain.tools.imdb.plot_of_movie import IMDbPlotOfMovie
from langchain.tools.imdb.popular_movies import IMDbPopularMovies
from langchain.tools.imdb.search_keyword import IMDbSearchMovieKeyword
from langchain.tools.imdb.search_movie import IMDbSearchMovie
from langchain.tools.imdb.search_person import IMDbSearchPerson

__all__ = [
"IMDbCastOfMovie",
"IMDbGetMovieCrew",
"IMDbGetMovieInfo",
"IMDbGetPersonBio",
"IMDbGetPersonMovies",
"IMDbPopularMovies",
"IMDbPlotOfMovie",
"IMDbSearchMovie",
"IMDbSearchMovieKeyword",
"IMDbSearchPerson",
]
22 changes: 22 additions & 0 deletions libs/langchain/langchain/tools/imdb/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Any, Dict

from langchain.pydantic_v1 import root_validator
from langchain.tools.base import BaseTool


class IMDbBaseTool(BaseTool):
"""Base tool for IMDb."""

client: Any = None #: :meta private:

@root_validator
def validate_environment(cls, values: Dict) -> Dict:
try:
from imdb import Cinemagoer
except ImportError:
raise ImportError(
"Could not import the cinemagoer package. "
"Please install it with `pip install git+https://github.com/cinemagoer/cinemagoer`."
)
values["client"] = Cinemagoer()
return values
31 changes: 31 additions & 0 deletions libs/langchain/langchain/tools/imdb/cast_of_movie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import json
from typing import Optional

from langchain.callbacks.manager import CallbackManagerForToolRun
from langchain.tools.imdb.base import IMDbBaseTool
from langchain.tools.imdb.utils import people_to_dicts


class IMDbCastOfMovie(IMDbBaseTool):
"""Tool to find cast of a movie given its name."""

name: str = "imdb_cast_of_movie"
description: str = (
"Use this tool to retrieve a list of cast members for a movie, given "
"its IMBD movie ID."
)

def _run(
self, id: str, run_manager: Optional[CallbackManagerForToolRun] = None
) -> str:
from imdb import IMDbError

try:
res_movie = self.client.get_movie(id)
except IMDbError:
return (
"The movie could not be found. "
"Please make sure to give a movie ID instead of a movie name."
)

return json.dumps(people_to_dicts(res_movie["cast"]))
Loading
Loading