diff --git a/llama-index-packs/llama-index-packs-finchat/.gitignore b/llama-index-packs/llama-index-packs-finchat/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..990c18de229088f55c6c514fd0f2d49981d1b0e7
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/.gitignore
@@ -0,0 +1,153 @@
+llama_index/_static
+.DS_Store
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+bin/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+etc/
+include/
+lib/
+lib64/
+parts/
+sdist/
+share/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+.ruff_cache
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+notebooks/
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+pyvenv.cfg
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# Jetbrains
+.idea
+modules/
+*.swp
+
+# VsCode
+.vscode
+
+# pipenv
+Pipfile
+Pipfile.lock
+
+# pyright
+pyrightconfig.json
diff --git a/llama-index-packs/llama-index-packs-finchat/BUILD b/llama-index-packs/llama-index-packs-finchat/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..0896ca890d8bffd60a44fa824f8d57fecd73ee53
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/BUILD
@@ -0,0 +1,3 @@
+poetry_requirements(
+    name="poetry",
+)
diff --git a/llama-index-packs/llama-index-packs-finchat/Makefile b/llama-index-packs/llama-index-packs-finchat/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b9eab05aa370629a4a3de75df3ff64cd53887b68
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/Makefile
@@ -0,0 +1,17 @@
+GIT_ROOT ?= $(shell git rev-parse --show-toplevel)
+
+help:	## Show all Makefile targets.
+	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[33m%-30s\033[0m %s\n", $$1, $$2}'
+
+format:	## Run code autoformatters (black).
+	pre-commit install
+	git ls-files | xargs pre-commit run black --files
+
+lint:	## Run linters: pre-commit (black, ruff, codespell) and mypy
+	pre-commit install && git ls-files | xargs pre-commit run --show-diff-on-failure --files
+
+test:	## Run tests via pytest.
+	pytest tests
+
+watch-docs:	## Build and watch documentation.
+	sphinx-autobuild docs/ docs/_build/html --open-browser --watch $(GIT_ROOT)/llama_index/
diff --git a/llama-index-packs/llama-index-packs-finchat/README.md b/llama-index-packs/llama-index-packs-finchat/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..fda963f89b8d8518c29f0c177124ffcb72b60c21
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/README.md
@@ -0,0 +1,61 @@
+# Finance Chat Llama Pack based on OpenAIAgent
+
+This LlamaPack implements a hierarchical agent based on LLM for financial chat and information extraction purposed.
+
+LLM agent is connected to various open financial apis as well as daily updated SP500 postgres SQL database storing
+opening & closing price, volume as well as past earnings.
+
+Based on the query, the agent reasons and routes to available tools or runs SQL query to retrieve information and
+combine information to answer.
+
+### Installation
+
+```bash
+pip install llama-index llama-index-tools-finchat
+```
+
+## CLI Usage
+
+You can download llamapacks directly using `llamaindex-cli`, which comes installed with the `llama-index` python package:
+
+```bash
+llamaindex-cli download-llamapack FinanceChatPack --download-dir ./finchat_pack
+```
+
+You can then inspect the files at `./finchat_pack` and use them as a template for your own project.
+
+## Code Usage
+
+You can download the pack to a the `./finchat_pack` directory:
+
+```python
+from llama_index.core.llama_pack import download_llama_pack
+
+FinanceChatPack = download_llama_pack("FinanceChatPack", "./finchat_pack")
+```
+
+To use this tool, you'll need a few API keys:
+
+- POLYGON_API_KEY -- <https://polygon.io/>
+- FINNHUB_API_KEY -- <https://finnhub.io/>
+- ALPHA_VANTAGE_API_KEY -- <https://www.alphavantage.co/>
+- NEWSAPI_API_KEY -- <https://newsapi.org/>
+- POSTGRES_DB_URI -- 'postgresql://postgres.xhlcobfkbhtwmckmszqp:fingptpassword#123@aws-0-us-east-1.pooler.supabase.com:5432/postgres' (You can also host your own postgres SQL DB with the same table signatures. To use different signatures, modification is required in giving query examples for SQL code generation.)
+
+```python
+fin_agent = FinanceChatPack(
+    POLYGON_API_KEY,
+    FINNHUB_API_KEY,
+    ALPHA_VANTAGE_API_KEY,
+    NEWSAPI_API_KEY,
+    OPENAI_API_KEY,
+)
+```
+
+From here, you can use the pack, or inspect and modify the pack in `./finchat_pack`.
+
+The `run()` function chats with the agent and sends the response of the input query.
+
+```python
+response = fin_agent.run("<query>")
+```
diff --git a/llama-index-packs/llama-index-packs-finchat/examples/BUILD b/llama-index-packs/llama-index-packs-finchat/examples/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..db46e8d6c978c67e301dd6c47bee08c1b3fd141c
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/examples/BUILD
@@ -0,0 +1 @@
+python_sources()
diff --git a/llama-index-packs/llama-index-packs-finchat/examples/example.py b/llama-index-packs/llama-index-packs-finchat/examples/example.py
new file mode 100644
index 0000000000000000000000000000000000000000..b414f15ebc821a71eaf6941d3ccc716eaae2176d
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/examples/example.py
@@ -0,0 +1,37 @@
+"""
+This example demonstrates how to set up and test chatting with a finance agent using the FinanceChatPack.
+It involves collecting necessary API keys and initializing the FinanceChatPack with these keys and a PostgreSQL database URI.
+"""
+
+import getpass
+from llama_index.packs.finchat import FinanceChatPack
+
+# Prompting the user to enter all necessary API keys for finance data access and OpenAI
+openai_api_key = getpass.getpass("Enter your OpenAI API key: ")
+polygon_api_key = getpass.getpass("Enter your Polygon API key: ")
+finnhub_api_key = getpass.getpass("Enter your Finnhub API key: ")
+alpha_vantage_api_key = getpass.getpass("Enter your Alpha Vantage API key: ")
+newsapi_api_key = getpass.getpass("Enter your NewsAPI API key: ")
+
+# PostgreSQL database URI for storing and accessing financial data
+postgres_db_uri = "postgresql://postgres.xhlcobfkbhtwmckmszqp:fingptpassword#123@aws-0-us-east-1.pooler.supabase.com:5432/postgres"
+
+# Initializing the FinanceChatPack with the collected API keys and database URI
+finance_chat_pack = FinanceChatPack(
+    polygon_api_key=polygon_api_key,
+    finnhub_api_key=finnhub_api_key,
+    alpha_vantage_api_key=alpha_vantage_api_key,
+    newsapi_api_key=newsapi_api_key,
+    openai_api_key=openai_api_key,
+    postgres_db_uri=postgres_db_uri,
+)
+
+# Notifying the user that the FinanceChatPack has been initialized and is ready for testing
+print(
+    "FinanceChatPack initialized successfully. Ready for testing chat interactions with the finance agent."
+)
+
+
+user_query = "Find similar companies to Rivian?"
+response = finance_chat_pack.run(user_query)
+print("Finance agent response:", response)
diff --git a/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/BUILD b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..db46e8d6c978c67e301dd6c47bee08c1b3fd141c
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/BUILD
@@ -0,0 +1 @@
+python_sources()
diff --git a/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/__init__.py b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e85603546160de936731808f4b5af04c42acac38
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/__init__.py
@@ -0,0 +1,3 @@
+from llama_index.packs.finchat.base import FinanceChatPack
+
+__all__ = ["FinanceChatPack"]
diff --git a/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/base.py b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a7082d7fe64714fbc8b9b22770e2c72193c2b3d
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/llama_index/packs/finchat/base.py
@@ -0,0 +1,375 @@
+"""Finance Chat LlamaPack class."""
+
+from typing import Optional, List, Any
+
+# The following imports have been adjusted to fix the ModuleNotFoundError
+from llama_index.core.llama_pack.base import BaseLlamaPack
+from llama_index.llms.openai import OpenAI
+from llama_index.tools.finance import FinanceAgentToolSpec
+from llama_index.core.tools.tool_spec.base import BaseToolSpec
+from llama_index.core.readers.base import BaseReader
+from llama_index.core.utilities.sql_wrapper import SQLDatabase
+from llama_index.core.tools.query_engine import QueryEngineTool
+from llama_index.agent.openai import OpenAIAgent
+from llama_index.core.schema import Document
+from llama_index.core.base.llms.types import ChatMessage
+from sqlalchemy import MetaData, text
+from sqlalchemy.engine import Engine
+from sqlalchemy.exc import NoSuchTableError
+from sqlalchemy.schema import CreateTable
+
+
+class SQLDatabaseToolSpec(BaseToolSpec, BaseReader):
+    """
+    A tool to query and retrieve results from a SQL Database.
+
+    Args:
+        sql_database (Optional[SQLDatabase]): SQL database to use,
+            including table names to specify.
+            See :ref:`Ref-Struct-Store` for more details.
+
+        OR
+
+        engine (Optional[Engine]): SQLAlchemy Engine object of the database connection.
+
+        OR
+
+        uri (Optional[str]): uri of the database connection.
+
+        OR
+
+        scheme (Optional[str]): scheme of the database connection.
+        host (Optional[str]): host of the database connection.
+        port (Optional[int]): port of the database connection.
+        user (Optional[str]): user of the database connection.
+        password (Optional[str]): password of the database connection.
+        dbname (Optional[str]): dbname of the database connection.
+
+    """
+
+    spec_functions = ["run_sql_query", "describe_tables", "list_tables"]
+
+    def __init__(
+        self,
+        sql_database: Optional[SQLDatabase] = None,
+        engine: Optional[Engine] = None,
+        uri: Optional[str] = None,
+        scheme: Optional[str] = None,
+        host: Optional[str] = None,
+        port: Optional[str] = None,
+        user: Optional[str] = None,
+        password: Optional[str] = None,
+        dbname: Optional[str] = None,
+        *args: Optional[Any],
+        **kwargs: Optional[Any],
+    ) -> None:
+        """Initialize with parameters."""
+        if sql_database:
+            self.sql_database = sql_database
+        elif engine:
+            self.sql_database = SQLDatabase(engine, *args, **kwargs)
+        elif uri:
+            self.uri = uri
+            self.sql_database = SQLDatabase.from_uri(uri, *args, **kwargs)
+        elif scheme and host and port and user and password and dbname:
+            uri = f"{scheme}://{user}:{password}@{host}:{port}/{dbname}"
+            self.uri = uri
+            self.sql_database = SQLDatabase.from_uri(uri, *args, **kwargs)
+        else:
+            raise ValueError(
+                "You must provide either a SQLDatabase, "
+                "a SQL Alchemy Engine, a valid connection URI, or a valid "
+                "set of credentials."
+            )
+        self._metadata = MetaData()
+        self._metadata.reflect(bind=self.sql_database.engine)
+
+    def run_sql_query(self, query: str) -> Document:
+        r"""Runs SQL query on the provided SQL database, returning a Document storing all the rows separated by \n.
+
+        Args:
+            query (str): SQL query in text format which can directly be executed using SQLAlchemy engine.
+
+        Returns:
+            Document: Document storing all the output result of the sql-query generated.
+        """
+        with self.sql_database.engine.connect() as connection:
+            if query is None:
+                raise ValueError("A query parameter is necessary to filter the data")
+            else:
+                result = connection.execute(text(query))
+            all_doc_str = ""
+            for item in result.fetchall():
+                if all_doc_str:
+                    all_doc_str += "\n"
+                # fetch each item
+                doc_str = ", ".join([str(entry) for entry in item])
+                all_doc_str += doc_str
+            return Document(text=all_doc_str)
+
+    def list_tables(self) -> List[str]:
+        """
+        Returns a list of available tables in the database.
+        """
+        return [x.name for x in self._metadata.sorted_tables]
+
+    def describe_tables(self, tables: Optional[List[str]] = None) -> str:
+        """
+        Describes the specified tables in the database.
+
+        Args:
+            tables (List[str]): A list of table names to retrieve details about
+        """
+        table_names = tables or [table.name for table in self._metadata.sorted_tables]
+        table_schemas = []
+
+        for table_name in table_names:
+            table = next(
+                (
+                    table
+                    for table in self._metadata.sorted_tables
+                    if table.name == table_name
+                ),
+                None,
+            )
+            if table is None:
+                raise NoSuchTableError(f"Table '{table_name}' does not exist.")
+            schema = str(CreateTable(table).compile(self.sql_database._engine))
+            table_schemas.append(f"{schema}\n")
+
+        return "\n".join(table_schemas)
+
+    def get_table_info(self) -> str:
+        """Construct table info for the all tables in DB which includes information about the columns of the table and also shows top row of the table."""
+        all_table_info = ""
+        for table_name in self.list_tables():
+            table_info = self.sql_database.get_single_table_info(table_name)
+            table_info += f"\n\nHere is the DDL statement for this table:\n"
+            table_info += self.describe_tables([table_name])
+            _, output = self.sql_database.run_sql(f"SELECT * FROM {table_name} LIMIT 1")
+            table_info += f"\nTop row of {table_name}:\n\n"
+            for colname in output["col_keys"]:
+                table_info += colname + "\t"
+            table_info += "\n"
+            for data in output["result"]:
+                for val in data:
+                    table_info += str(val) + "\t"
+                table_info += "\n"
+            all_table_info += f"\n{table_info}\n"
+        return all_table_info
+
+
+class FinanceChatPack(BaseLlamaPack):
+    def __init__(
+        self,
+        polygon_api_key: str,
+        finnhub_api_key: str,
+        alpha_vantage_api_key: str,
+        newsapi_api_key: str,
+        openai_api_key: str,
+        postgres_db_uri: str,
+        gpt_model_name: str = "gpt-4-0613",
+    ):
+        llm = OpenAI(temperature=0, model=gpt_model_name, api_key=openai_api_key)
+        self.db_tool_spec = SQLDatabaseToolSpec(uri=postgres_db_uri)
+        self.fin_tool_spec = FinanceAgentToolSpec(
+            polygon_api_key, finnhub_api_key, alpha_vantage_api_key, newsapi_api_key
+        )
+
+        self.db_table_info = self.db_tool_spec.get_table_info()
+        prefix_messages = self.construct_prefix_db_message(self.db_table_info)
+        # add some role play in the system .
+        database_agent = OpenAIAgent.from_tools(
+            [
+                tool
+                for tool in self.db_tool_spec.to_tool_list()
+                if tool.metadata.name == "run_sql_query"
+            ],
+            prefix_messages=prefix_messages,
+            llm=llm,
+            verbose=True,
+        )
+        database_agent_tool = QueryEngineTool.from_defaults(
+            database_agent,
+            name="database_agent",
+            description=""""
+                This agent analyzes a text query and add further explanations and thoughts to help a data scientist who has access to following tables:
+
+                {table_info}
+
+                Be concise and do not lose any information about original query while passing to the data scientist.
+                """,
+        )
+
+        fin_api_agent = OpenAIAgent.from_tools(
+            self.fin_tool_spec.to_tool_list(),
+            system_prompt=f"""
+                You are a helpful AI financial assistant designed to understand the intent of the user query and then use relevant tools/apis to help answer it.
+                You can use more than one tool/api only if needed, but final response should be concise and relevant. If you are not able to find
+                relevant tool/api, respond respectfully suggesting that you don't know. Think step by step""",
+            llm=llm,
+            verbose=True,
+        )
+
+        fin_api_agent_tool = QueryEngineTool.from_defaults(
+            fin_api_agent,
+            name="fin_api_agent",
+            description=f"""
+                This agent has access to another agent which can access certain open APIs to provide information based on user query.
+                Analyze the query and add any information if needed which can help to decide which API to call.
+                Be concise and do not lose any information about original query.
+                """,
+        )
+
+        self.fin_hierarchical_agent = OpenAIAgent.from_tools(
+            [database_agent_tool, fin_api_agent_tool],
+            system_prompt="""
+                You are a specialized financial assistant with access to certain tools which can access open APIs and SP500 companies database containing information on
+                daily opening price, closing price, high, low, volume, reported earnings, estimated earnings since 2010 to 2023. Before answering query you should check
+                if the question can be answered via querying the database or using specific open APIs. If you try to find answer via querying database first and it did
+                not work out, think if you can use other tool APIs available before replying gracefully.
+                """,
+            llm=llm,
+            verbose=True,
+        )
+
+    def construct_prefix_db_message(self, table_info: str) -> str:
+        system_prompt = f"""
+        You are a smart data scientist working in a reputed trading firm like Jump Trading developing automated trading algorithms. Take a deep breathe and think
+        step by step to design queries over a SQL database.
+
+        Here is a complete description of tables in SQL database you have access to:
+
+        {table_info}
+
+        Use responses to past questions also to guide you.
+
+
+        """
+
+        prefix_messages = []
+        prefix_messages.append(ChatMessage(role="system", content=system_prompt))
+
+        prefix_messages.append(
+            ChatMessage(
+                role="user",
+                content="What is the average price of Google in the month of July in 2023",
+            )
+        )
+        prefix_messages.append(
+            ChatMessage(
+                role="assistant",
+                content="""
+        SELECT AVG(close) AS AvgPrice
+        FROM stock_data
+        WHERE stock = 'GOOG'
+            AND date >= '2023-07-01'
+            AND date <= '2023-07-31';
+        """,
+            )
+        )
+
+        prefix_messages.append(
+            ChatMessage(
+                role="user",
+                content="Which stock has the maximum % change in any month in 2023",
+            )
+        )
+        # prefix_messages.append(ChatMessage(role="user", content="Which stocks gave more than 2% return constantly in month of July from past 5 years"))
+        prefix_messages.append(
+            ChatMessage(
+                role="assistant",
+                content="""
+        WITH MonthlyPrices AS (
+            SELECT
+                stock,
+                EXTRACT(YEAR FROM date) AS year,
+                EXTRACT(MONTH FROM date) AS month,
+                FIRST_VALUE(close) OVER (PARTITION BY stock, EXTRACT(YEAR FROM date), EXTRACT(MONTH FROM date) ORDER BY date ASC) AS opening_price,
+                LAST_VALUE(close) OVER (PARTITION BY stock, EXTRACT(YEAR FROM date), EXTRACT(MONTH FROM date) ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS closing_price
+            FROM
+                stock_data
+            WHERE
+                EXTRACT(YEAR FROM date) = 2023
+        ),
+        PercentageChanges AS (
+            SELECT
+                stock,
+                year,
+                month,
+                CASE
+                    WHEN opening_rice IS NULL OR closing_price IS NULL THEN NULL
+                    WHEN opening_price = 0 THEN NULL
+                    ELSE ((closing_price - opening_price) / opening_price) * 100
+                END AS pct
+            FROM
+                MonthlyPrices
+        )
+        SELECT *
+        FROM
+            PercentageChanges
+        WHERE pct IS NOT NULL
+        ORDER BY
+            pct DESC
+        LIMIT 1;
+        """,
+            )
+        )
+
+        prefix_messages.append(
+            ChatMessage(
+                role="user",
+                content="How many times Microsoft beat earnings estimates in 2022",
+            )
+        )
+        prefix_messages.append(
+            ChatMessage(
+                role="assistant",
+                content="""
+        SELECT
+            COUNT(*)
+        FROM
+            earnings
+        WHERE
+            stock = 'MSFT' AND reported > estimated and EXTRACT(YEAR FROM date) = 2022
+        """,
+            )
+        )
+
+        prefix_messages.append(
+            ChatMessage(
+                role="user",
+                content="Which stocks have beaten earnings estimate by more than 1$ consecutively from last 4 reportings?",
+            )
+        )
+        prefix_messages.append(
+            ChatMessage(
+                role="assistant",
+                content="""
+        WITH RankedEarnings AS(
+            SELECT
+                stock,
+                date,
+                reported,
+                estimated,
+                RANK() OVER (PARTITION BY stock ORDER BY date DESC) as ranking
+            FROM
+                earnings
+        )
+        SELECT
+            stock
+        FROM
+            RankedEarnings
+        WHERE
+            ranking <= 4 AND reported - estimated > 1
+        GROUP BY
+            stock
+        HAVING COUNT(*) = 4
+        """,
+            )
+        )
+
+        return prefix_messages
+
+    def run(self, query: str):
+        return self.fin_hierarchical_agent.chat(query)
diff --git a/llama-index-packs/llama-index-packs-finchat/pyproject.toml b/llama-index-packs/llama-index-packs-finchat/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..b5e23a3bb299f38f895604f55f9fc20cd00eebe0
--- /dev/null
+++ b/llama-index-packs/llama-index-packs-finchat/pyproject.toml
@@ -0,0 +1,61 @@
+[build-system]
+build-backend = "poetry.core.masonry.api"
+requires = ["poetry-core"]
+
+[tool.codespell]
+check-filenames = true
+check-hidden = true
+# Feel free to un-skip examples, and experimental, you will just need to
+# work through many typos (--write-changes and --interactive will help)
+skip = "*.csv,*.html,*.json,*.jsonl,*.pdf,*.txt,*.ipynb"
+
+[tool.llamahub]
+contains_example = true
+import_path = "llama_index.packs.finchat"
+
+[tool.llamahub.class_authors]
+FinanceChatPack = "345ishaan"
+
+[tool.mypy]
+disallow_untyped_defs = true
+# Remove venv skip when integrated with pre-commit
+exclude = ["_static", "build", "examples", "notebooks", "venv"]
+ignore_missing_imports = true
+python_version = "3.8"
+
+[tool.poetry]
+authors = ["Ishan Gupta <345ishaan@gmail.com>"]
+description = "llama-index packs implementation of a hierarchical agent for finance chat."
+keywords = ["agent", "finance", "finchat"]
+license = "MIT"
+maintainers = ["345ishaan"]
+name = "llama-index-packs-finchat"
+packages = [{include = "llama_index/"}]
+readme = "README.md"
+version = "0.1.0"
+
+[tool.poetry.dependencies]
+python = ">=3.8.1,<3.12"
+llama-index-core = "^0.10.0"
+tavily-python = "^0.3.1"
+llama-index-agent-openai = "^0.1.5"
+llama-index-tools-finance = "^0.1.0"
+
+[tool.poetry.group.dev.dependencies]
+black = {extras = ["jupyter"], version = "<=23.9.1,>=23.7.0"}
+codespell = {extras = ["toml"], version = ">=v2.2.6"}
+ipython = "8.10.0"
+jupyter = "^1.0.0"
+mypy = "0.991"
+pre-commit = "3.2.0"
+pylint = "2.15.10"
+pytest = "7.2.1"
+pytest-mock = "3.11.1"
+ruff = "0.0.292"
+tree-sitter-languages = "^1.8.0"
+types-Deprecated = ">=0.1.0"
+types-PyYAML = "^6.0.12.12"
+types-protobuf = "^4.24.0.4"
+types-redis = "4.5.5.0"
+types-requests = "2.28.11.8"  # TODO: unpin when mypy>0.991
+types-setuptools = "67.1.0.0"