ai-parrot 0.8.3__cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ai-parrot might be problematic. Click here for more details.

Files changed (128) hide show
  1. ai_parrot-0.8.3.dist-info/LICENSE +21 -0
  2. ai_parrot-0.8.3.dist-info/METADATA +306 -0
  3. ai_parrot-0.8.3.dist-info/RECORD +128 -0
  4. ai_parrot-0.8.3.dist-info/WHEEL +6 -0
  5. ai_parrot-0.8.3.dist-info/top_level.txt +2 -0
  6. parrot/__init__.py +30 -0
  7. parrot/bots/__init__.py +5 -0
  8. parrot/bots/abstract.py +1115 -0
  9. parrot/bots/agent.py +492 -0
  10. parrot/bots/basic.py +9 -0
  11. parrot/bots/bose.py +17 -0
  12. parrot/bots/chatbot.py +271 -0
  13. parrot/bots/cody.py +17 -0
  14. parrot/bots/copilot.py +117 -0
  15. parrot/bots/data.py +730 -0
  16. parrot/bots/dataframe.py +103 -0
  17. parrot/bots/hrbot.py +15 -0
  18. parrot/bots/interfaces/__init__.py +1 -0
  19. parrot/bots/interfaces/retrievers.py +12 -0
  20. parrot/bots/notebook.py +619 -0
  21. parrot/bots/odoo.py +17 -0
  22. parrot/bots/prompts/__init__.py +41 -0
  23. parrot/bots/prompts/agents.py +91 -0
  24. parrot/bots/prompts/data.py +214 -0
  25. parrot/bots/retrievals/__init__.py +1 -0
  26. parrot/bots/retrievals/constitutional.py +19 -0
  27. parrot/bots/retrievals/multi.py +122 -0
  28. parrot/bots/retrievals/retrieval.py +610 -0
  29. parrot/bots/tools/__init__.py +7 -0
  30. parrot/bots/tools/eda.py +325 -0
  31. parrot/bots/tools/pdf.py +50 -0
  32. parrot/bots/tools/plot.py +48 -0
  33. parrot/bots/troc.py +16 -0
  34. parrot/conf.py +170 -0
  35. parrot/crew/__init__.py +3 -0
  36. parrot/crew/tools/__init__.py +22 -0
  37. parrot/crew/tools/bing.py +13 -0
  38. parrot/crew/tools/config.py +43 -0
  39. parrot/crew/tools/duckgo.py +62 -0
  40. parrot/crew/tools/file.py +24 -0
  41. parrot/crew/tools/google.py +168 -0
  42. parrot/crew/tools/gtrends.py +16 -0
  43. parrot/crew/tools/md2pdf.py +25 -0
  44. parrot/crew/tools/rag.py +42 -0
  45. parrot/crew/tools/search.py +32 -0
  46. parrot/crew/tools/url.py +21 -0
  47. parrot/exceptions.cpython-311-x86_64-linux-gnu.so +0 -0
  48. parrot/handlers/__init__.py +4 -0
  49. parrot/handlers/agents.py +292 -0
  50. parrot/handlers/bots.py +196 -0
  51. parrot/handlers/chat.py +192 -0
  52. parrot/interfaces/__init__.py +6 -0
  53. parrot/interfaces/database.py +27 -0
  54. parrot/interfaces/http.py +805 -0
  55. parrot/interfaces/images/__init__.py +0 -0
  56. parrot/interfaces/images/plugins/__init__.py +18 -0
  57. parrot/interfaces/images/plugins/abstract.py +58 -0
  58. parrot/interfaces/images/plugins/exif.py +709 -0
  59. parrot/interfaces/images/plugins/hash.py +52 -0
  60. parrot/interfaces/images/plugins/vision.py +104 -0
  61. parrot/interfaces/images/plugins/yolo.py +66 -0
  62. parrot/interfaces/images/plugins/zerodetect.py +197 -0
  63. parrot/llms/__init__.py +1 -0
  64. parrot/llms/abstract.py +69 -0
  65. parrot/llms/anthropic.py +58 -0
  66. parrot/llms/gemma.py +15 -0
  67. parrot/llms/google.py +44 -0
  68. parrot/llms/groq.py +67 -0
  69. parrot/llms/hf.py +45 -0
  70. parrot/llms/openai.py +61 -0
  71. parrot/llms/pipes.py +114 -0
  72. parrot/llms/vertex.py +89 -0
  73. parrot/loaders/__init__.py +9 -0
  74. parrot/loaders/abstract.py +628 -0
  75. parrot/loaders/files/__init__.py +0 -0
  76. parrot/loaders/files/abstract.py +39 -0
  77. parrot/loaders/files/text.py +63 -0
  78. parrot/loaders/txt.py +26 -0
  79. parrot/manager.py +333 -0
  80. parrot/models.py +504 -0
  81. parrot/py.typed +0 -0
  82. parrot/stores/__init__.py +11 -0
  83. parrot/stores/abstract.py +248 -0
  84. parrot/stores/chroma.py +188 -0
  85. parrot/stores/duck.py +162 -0
  86. parrot/stores/embeddings/__init__.py +10 -0
  87. parrot/stores/embeddings/abstract.py +46 -0
  88. parrot/stores/embeddings/base.py +52 -0
  89. parrot/stores/embeddings/bge.py +20 -0
  90. parrot/stores/embeddings/fastembed.py +17 -0
  91. parrot/stores/embeddings/google.py +18 -0
  92. parrot/stores/embeddings/huggingface.py +20 -0
  93. parrot/stores/embeddings/ollama.py +14 -0
  94. parrot/stores/embeddings/openai.py +26 -0
  95. parrot/stores/embeddings/transformers.py +21 -0
  96. parrot/stores/embeddings/vertexai.py +17 -0
  97. parrot/stores/empty.py +10 -0
  98. parrot/stores/faiss.py +160 -0
  99. parrot/stores/milvus.py +397 -0
  100. parrot/stores/postgres.py +653 -0
  101. parrot/stores/qdrant.py +170 -0
  102. parrot/tools/__init__.py +23 -0
  103. parrot/tools/abstract.py +68 -0
  104. parrot/tools/asknews.py +33 -0
  105. parrot/tools/basic.py +51 -0
  106. parrot/tools/bby.py +359 -0
  107. parrot/tools/bing.py +13 -0
  108. parrot/tools/docx.py +343 -0
  109. parrot/tools/duck.py +62 -0
  110. parrot/tools/execute.py +56 -0
  111. parrot/tools/gamma.py +28 -0
  112. parrot/tools/google.py +170 -0
  113. parrot/tools/gvoice.py +301 -0
  114. parrot/tools/results.py +278 -0
  115. parrot/tools/stack.py +27 -0
  116. parrot/tools/weather.py +70 -0
  117. parrot/tools/wikipedia.py +58 -0
  118. parrot/tools/zipcode.py +198 -0
  119. parrot/utils/__init__.py +2 -0
  120. parrot/utils/parsers/__init__.py +5 -0
  121. parrot/utils/parsers/toml.cpython-311-x86_64-linux-gnu.so +0 -0
  122. parrot/utils/toml.py +11 -0
  123. parrot/utils/types.cpython-311-x86_64-linux-gnu.so +0 -0
  124. parrot/utils/uv.py +11 -0
  125. parrot/version.py +10 -0
  126. resources/users/__init__.py +5 -0
  127. resources/users/handlers.py +13 -0
  128. resources/users/models.py +205 -0
@@ -0,0 +1,170 @@
1
+ from collections.abc import Callable
2
+ from typing import Union, Optional
3
+ from qdrant_client import QdrantClient, models
4
+ from langchain.docstore.document import Document
5
+ from langchain.memory import VectorStoreRetrieverMemory
6
+ from langchain_qdrant import Qdrant
7
+ from .abstract import AbstractStore
8
+ from ..conf import (
9
+ QDRANT_PROTOCOL,
10
+ QDRANT_HOST,
11
+ QDRANT_PORT,
12
+ QDRANT_USE_HTTPS,
13
+ QDRANT_CONN_TYPE,
14
+ QDRANT_URL
15
+ )
16
+
17
+
18
+ class QdrantStore(AbstractStore):
19
+ """Qdrant DB Store Class.
20
+
21
+ Using Qdrant as a Document Vector Store.
22
+
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ embedding_model: Union[dict, str] = None,
28
+ embedding: Union[dict, Callable] = None,
29
+ **kwargs
30
+ ):
31
+ super().__init__(
32
+ embedding_model=embedding_model,
33
+ embedding=embedding,
34
+ **kwargs
35
+ )
36
+ self.client: Optional[QdrantClient] = None
37
+ self.host: str = kwargs.pop('host', QDRANT_HOST)
38
+ self.port: int = kwargs.pop('port', QDRANT_PORT)
39
+ self.use_https: bool = kwargs.pop('use_https', QDRANT_USE_HTTPS)
40
+ self.protocol: str = kwargs.pop('protocol', QDRANT_PROTOCOL)
41
+ self.conn_type: str = kwargs.pop('conn_type', QDRANT_CONN_TYPE)
42
+ self.url: str = kwargs.pop('url', QDRANT_URL)
43
+ self._host: str = f"{self.protocol}://{self.host}:{self.port}"
44
+
45
+ async def connection(self):
46
+ """Initialize Qdrant vector store.
47
+
48
+ Connects to a Qdrant instance, if connection fails, raise error.
49
+ """
50
+ try:
51
+ self._connection = QdrantClient(
52
+ host=self.host,
53
+ port=self.port,
54
+ )
55
+ collections = self._connection.get_collections().collections
56
+ collection_names = [collection.name for collection in collections]
57
+ if self.collection_name not in collection_names:
58
+ print(
59
+ f"Collection '{self.collection_name}' not found, creating new one."
60
+ )
61
+ self._connection.create_collection(
62
+ collection_name=self.collection_name,
63
+ vectors_config=models.VectorParams(
64
+ size=len(self._embed_.embedding.embed_query("test")), distance=models.Distance.EUCLID
65
+ )
66
+ )
67
+ self.client = Qdrant(
68
+ client=self._connection,
69
+ collection_name=self.collection_name,
70
+ embedding_function=self._embed_.embedding
71
+ )
72
+ except Exception as e:
73
+ print(f"Error connecting to Qdrant: {e}")
74
+ raise
75
+ self._connected = True
76
+ return self._connection
77
+
78
+ async def disconnect(self) -> None:
79
+ """Disconnects from Qdrant instance."""
80
+ self.client = None # No explicit disconnect needed for QdrantClient in this context.
81
+ self._connection = None
82
+ self._connected = False
83
+
84
+ def get_vector(
85
+ self,
86
+ embedding: Optional[Callable] = None,
87
+ ) -> Qdrant:
88
+ """Returns Qdrant VectorStore instance."""
89
+ if embedding is not None:
90
+ _embed_ = embedding
91
+ else:
92
+ _embed_ = self.create_embedding(
93
+ embedding_model=self.embedding_model
94
+ )
95
+ if not self._connection:
96
+ # Re-establish client if lost, but should not happen frequently in well-managed context.
97
+ self._connection = QdrantClient(host=self.host, port=self.port)
98
+ return Qdrant(
99
+ client=self._connection,
100
+ collection_name=self.collection_name,
101
+ embedding_function=_embed_
102
+ )
103
+
104
+ async def from_documents(self, documents: list[Document], **kwargs):
105
+ """Save Documents as Vectors in Qdrant."""
106
+ vectordb = await Qdrant.afrom_documents(
107
+ documents=documents,
108
+ embedding=self._embed_.embedding,
109
+ client=self.client,
110
+ collection_name=self.collection_name,
111
+ **kwargs
112
+ )
113
+ return vectordb
114
+
115
+ async def add_documents(
116
+ self,
117
+ documents: list[Document],
118
+ embedding: Optional[Callable] = None,
119
+ ) -> bool:
120
+ """Add Documents to Qdrant."""
121
+ async with self:
122
+ vector_db = self.get_vector(embedding=embedding)
123
+ await vector_db.aadd_documents(documents=documents)
124
+ return True
125
+
126
+ async def update_documents(
127
+ self,
128
+ documents: list[Document],
129
+ embedding: Optional[Callable] = None,
130
+ ) -> bool:
131
+ """Update Documents in Qdrant."""
132
+ async with self:
133
+ vector_db = self.get_vector(embedding=embedding)
134
+ if all('id' in doc for doc in documents):
135
+ ids = [doc.pop('id') for doc in documents]
136
+ vector_db.delete(ids=ids) # Remove old entries
137
+ await vector_db.aadd_documents(documents=documents) # Add new versions
138
+ return True
139
+ return False
140
+
141
+ async def similarity_search(
142
+ self,
143
+ query: str,
144
+ embedding: Optional[Callable] = None,
145
+ limit: int = 2,
146
+ ) -> list:
147
+ """Performs similarity search in Qdrant."""
148
+ async with self:
149
+ vector_db = self.get_vector(embedding=embedding)
150
+ return await vector_db.asimilarity_search(query, k=limit) # Use asimilarity_search for async
151
+
152
+ def memory_retriever(
153
+ self,
154
+ documents: Optional[list] = None,
155
+ num_results: int = 5
156
+ ) -> VectorStoreRetrieverMemory:
157
+ """Retrieves stored memory-based documents."""
158
+ if not documents:
159
+ documents = []
160
+ vectordb = Qdrant.from_documents(
161
+ documents=documents,
162
+ embedding=self._embed_.embedding,
163
+ client=self.client,
164
+ collection_name=self.collection_name
165
+ )
166
+ retriever = Qdrant.as_retriever(
167
+ vectordb,
168
+ search_kwargs=dict(k=num_results)
169
+ )
170
+ return VectorStoreRetrieverMemory(retriever=retriever)
@@ -0,0 +1,23 @@
1
+ """
2
+ Tools infrastructure for building Agents.
3
+ """
4
+ # Abstract Agent interface
5
+ from .abstract import AbstractTool
6
+ from .basic import SearchTool, MathTool
7
+ from .duck import DuckDuckGoSearchTool, DuckDuckGoRelevantSearch
8
+ from .gamma import GammaLink
9
+ from .gvoice import GoogleVoiceTool
10
+ from .docx import WordToMarkdownTool
11
+
12
+ # from langchain_community.tools.yahoo_finance_news import YahooFinanceNewsTool
13
+ # from langchain_community.tools import YouTubeSearchTool
14
+ # from langchain_community.agent_toolkits import O365Toolkit
15
+ # from navconfig import config
16
+ # # from .wikipedia import WikipediaTool, WikidataTool
17
+ # from .asknews import AskNewsTool
18
+
19
+ # from .weather import OpenWeather, OpenWeatherMapTool
20
+ # from .google import GoogleLocationFinder, GoogleSiteSearchTool, GoogleSearchTool
21
+ # from .zipcode import ZipcodeAPIToolkit
22
+ # from .bing import BingSearchTool
23
+ # from .stack import StackExchangeTool
@@ -0,0 +1,68 @@
1
+ from typing import Optional, Dict, Any, Type
2
+ from abc import abstractmethod
3
+ # from langchain_core.pydantic_v1 import BaseModel
4
+ from pydantic import BaseModel, Field
5
+ from langchain_core.callbacks import CallbackManagerForToolRun
6
+ from langchain_core.tools import BaseTool
7
+ from navconfig.logging import logging
8
+
9
+
10
+ logging.getLogger(name='cookie_store').setLevel(logging.INFO)
11
+ logging.getLogger(name='httpx').setLevel(logging.INFO)
12
+ logging.getLogger(name='httpcore').setLevel(logging.WARNING)
13
+ logging.getLogger(name='primp').setLevel(logging.WARNING)
14
+
15
+ class AbstractToolArgsSchema(BaseModel):
16
+ """Schema for the arguments to the AbstractTool."""
17
+
18
+ # This Field allows any number of arguments to be passed in.
19
+ args: list = Field(description="A list of arguments to the tool")
20
+
21
+
22
+ class AbstractTool(BaseTool):
23
+ """Abstract class for tools."""
24
+
25
+ args_schema: Type[BaseModel] = AbstractToolArgsSchema
26
+
27
+ class Config:
28
+ """Configuration for this pydantic object."""
29
+ arbitrary_types_allowed = True
30
+
31
+ def __init__(self, *args, **kwargs):
32
+ super().__init__(*args, **kwargs)
33
+ self.name = kwargs.pop('name', self.__class__.__name__)
34
+ self.logger = logging.getLogger(
35
+ f'{self.name}.Tool'
36
+ )
37
+
38
+
39
+ @abstractmethod
40
+ def _search(self, query: str) -> str:
41
+ """Run the tool."""
42
+
43
+ async def _asearch(self, *args, **kwargs):
44
+ """Run the tool asynchronously."""
45
+ return self._search(*args, **kwargs)
46
+
47
+ def _run(
48
+ self,
49
+ query: str,
50
+ run_manager: Optional[CallbackManagerForToolRun] = None
51
+ ) -> Dict[str, Any]:
52
+ args = [a.strip() for a in query.split(',')]
53
+ try:
54
+ return self._search(*args)
55
+ except Exception as e:
56
+ raise ValueError(f"Error running tool: {e}") from e
57
+
58
+ async def _arun(
59
+ self,
60
+ query: str,
61
+ run_manager: Optional[CallbackManagerForToolRun] = None
62
+ ) -> Dict[str, Any]:
63
+ """Use the tool asynchronously."""
64
+ args = [a.strip() for a in query.split(',')]
65
+ try:
66
+ return await self._asearch(*args)
67
+ except Exception as e:
68
+ raise ValueError(f"Error running tool: {e}") from e
@@ -0,0 +1,33 @@
1
+ from typing import Any
2
+ import os
3
+ from navconfig import config
4
+ from langchain_community.tools.asknews import AskNewsSearch
5
+ from langchain.tools import BaseTool
6
+
7
+ class AskNewsTool(BaseTool):
8
+ """Tool that searches the AskNews API."""
9
+ name: str = "asknews_search"
10
+ description: str = (
11
+ "Search for up-to-date news and historical news on AskNews site. "
12
+ "This tool allows you to perform a search on up-to-date news and historical news. "
13
+ "If you needs news from more than 48 hours ago, you can estimate the "
14
+ "number of hours back to search."
15
+ )
16
+ search: Any = None
17
+
18
+ def __init__(self, max_results: int = 5, **kwargs):
19
+ super().__init__(**kwargs)
20
+ os.environ["ASKNEWS_CLIENT_ID"] = config.get('ASKNEWS_CLIENT_ID')
21
+ os.environ["ASKNEWS_CLIENT_SECRET"] = config.get('ASKNEWS_CLIENT_SECRET')
22
+ self.search = AskNewsSearch(max_results=5)
23
+
24
+ def _run(
25
+ self,
26
+ query: str
27
+ ) -> str:
28
+ """Use the Wikipedia tool."""
29
+ return self.search.invoke(
30
+ {
31
+ "query": query,
32
+ }
33
+ )
parrot/tools/basic.py ADDED
@@ -0,0 +1,51 @@
1
+ from langchain.tools import Tool
2
+ # Tools:
3
+ from langchain.chains.llm_math.base import LLMMathChain
4
+ from langchain_community.utilities import SerpAPIWrapper
5
+ from langchain_groq import ChatGroq
6
+ from ..conf import (
7
+ SERPAPI_API_KEY,
8
+ GROQ_API_KEY
9
+ )
10
+
11
+ class SearchTool:
12
+ """Search Tool."""
13
+ name: str = "web_search"
14
+ def __new__(cls, *args, **kwargs):
15
+ search = SerpAPIWrapper(
16
+ serpapi_api_key=kwargs.get('serpapi_api_key', SERPAPI_API_KEY)
17
+ )
18
+ tool = Tool(
19
+ name="Web Search",
20
+ func=search.run,
21
+ description="""
22
+ useful for when you need to answer questions about current events or general knowledge. Input should be a search query.
23
+ """,
24
+ coroutine=search.arun
25
+ )
26
+ tool.name = "Web Search"
27
+ return tool
28
+
29
+
30
+ class MathTool:
31
+ """Math Tool."""
32
+ def __new__(cls, *args, **kwargs):
33
+ groq = ChatGroq(
34
+ model="llama-3.1-8b-instant",
35
+ temperature=0.1,
36
+ api_key=kwargs.get('GROQ_API_KEY', GROQ_API_KEY)
37
+ )
38
+ llm = kwargs.get('llm', groq)
39
+ math_chain = LLMMathChain.from_llm(
40
+ llm=llm,
41
+ verbose=True
42
+ )
43
+ tool = Tool(
44
+ name="math_calculator",
45
+ func=math_chain.run,
46
+ description="""
47
+ useful for when you need to solve math problems or perform mathematical calculations. Input should be a math equation or a mathematical expression.
48
+ """,
49
+ coroutine=math_chain.arun
50
+ )
51
+ return tool